<!DOCTYPE html>

<!--
  Copyright 2018 The Chromium Authors. All rights reserved.
  Use of this source code is governed by a BSD-style license that can be
  found in the LICENSE file.
-->

<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- Note: This tag is replaced when served through DDS! -->
    <base href="/">

    <title></title>
    <link href="favicon.png" rel="icon" sizes="64x64">

    <!-- Global site tag (gtag.js) - Google Analytics -->	
    <script>	
      const GA_DEVTOOLS_PROPERTY = 'UA-26406144-34'; // Dart DevTools GA Property UA.	

      function getDevToolsPropertyID() {	
          return GA_DEVTOOLS_PROPERTY;	
      }	
    </script>	
    <!-- The below URI ?id= must match the GA_DEVTOOLS_PROPERTY above. -->	
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-26406144-34"></script>	
    <script src="devtools_analytics.js"></script>	
    <!-- End of DevTools Google Analytics -->

    <!-- DO NOT REMOVE: -->
    <!-- OBSERVER SCRIPT PLACEHOLDER -->

    <script>
        function supportsES6Classes() {
            "use strict";
            try { eval("class Foo {}"); }
            catch (e) { return false; }
            return true;
        }

        if (!supportsES6Classes()) {
            window.location.href = '/unsupported-browser.html';
        }
    </script>
</head>

<body>
  <!-- This script installs service_worker.js to provide PWA functionality to
       application. For more information, see:
       https://developers.google.com/web/fundamentals/primers/service-workers -->
  <script>
    var version = '2.22.2-dev.7';
    var scriptLoaded = false;
    function loadMainDartJs() {
      if (scriptLoaded) {
        return;
      }
      scriptLoaded = true;
      var scriptTag = document.createElement('script');
      scriptTag.src = 'main.dart.js';
      scriptTag.type = 'application/javascript';
      document.body.append(scriptTag);
    }

    if ('serviceWorker' in navigator) {
      if (window.location.href.includes('index.ddc.html')) {
        // If we are running DevTools locally, immediately load `main.dart.js` and
        // unregister any service workers:
        loadMainDartJs();
        navigator.serviceWorker.getRegistrations().then(function(registrations) {
          for (let registration of registrations) {
            registration.unregister();
          }
        });
      } else {
        // Service workers are supported. Use them.
        window.addEventListener('load', function() {
          // Wait for registration to finish before dropping the <script> tag.
          // Otherwise, the browser will load the script multiple times,
          // potentially different versions.
          var serviceWorkerUrl = 'service_worker.js?v=' + version;
          navigator.serviceWorker.register(serviceWorkerUrl)
              .then((reg) => {
                function waitForActivation(serviceWorker) {
                  serviceWorker.addEventListener('statechange', () => {
                    if (serviceWorker.state == 'activated') {
                      loadMainDartJs();
                    }
                  });
                }
                if (!reg.active && (reg.installing || reg.waiting)) {
                  // No active web worker and we have installed or are installing
                  // one for the first time. Simply wait for it to activate.
                  waitForActivation(reg.installing || reg.waiting);
                } else if (!reg.active.scriptURL.endsWith(version)) {
                  // When the app updates the version changes, so we
                  // need to ask the service worker to update.
                  reg.update();
                  waitForActivation(reg.installing);
                } else {
                  // Existing service worker is still good.
                  loadMainDartJs();
                }
              })
              .catch((err) => {
                console.warn(
                    ` Falling back to plain <script> tag. Error loading service worker: ${
                        err}`);
                loadMainDartJs();
              });

          // If service worker doesn't succeed in a reasonable amount of time,
          // fallback to plain <script> tag.
          setTimeout(() => {
            if (!scriptLoaded) {
              console.warn(
                  'Failed to load app from service worker. Falling back to plain <script> tag.',
              );
              loadMainDartJs();
            }
          }, 4000);
        });
      }
    } else {
      // Service workers not supported. Just drop the <script> tag.
      loadMainDartJs();
    }
  </script>
</body>
</html>
