Version 1.16.0-dev.4.0

Merge commit 'fea9ab06c7a35ca17d2ba970e4eb8ea15204a7f5' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e3bef8..11e8853 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,8 +2,9 @@
 
 ### Core library changes
 
-* `dart:core`
-  * Fixed DateTime implementation in the VM (issue #19923), but no API change.
+* `dart:io`
+  * Added `SecurityContext.alpnSupported`, which is true if a platform
+    supports ALPN, and false otherwise.
 
 ### Analyzer
 
@@ -27,6 +28,16 @@
   * Both `pub get` and `pub upgrade` now have a `--no-precompile` flag that
     disables precompilation of executables and transformed dependencies.
 
+* Dart Dev Compiler
+  * The **experimental** `dartdevc` executable has been added to the SDK.
+
+  * It will help early adopters validate the implementation and provide
+    feedback. `dartdevc` **is not** yet ready for production usage.
+
+  * Read more about the Dart Dev Compiler [here][dartdevc].
+
+[dartdevc]: https://github.com/dart-lang/dev_compiler
+
 ## 1.15.0 - 2016-03-09
 
 ### Core library changes
diff --git a/DEPS b/DEPS
index a696162..3888a04 100644
--- a/DEPS
+++ b/DEPS
@@ -56,7 +56,7 @@
   "intl_rev": "@a8b480b9c436f6c0ec16730804c914bdb4e30d53",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@2.0.0",
-  "linter_rev": "@a60289545b34ab1f047a0a3f0673a4c5abde0eaf",
+  "linter_rev": "@ca7c6b3f1085cf302c4726598704d36cf240695f",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
   "matcher_tag": "@0.12.0",
diff --git a/pkg/analysis_server/benchmark/integration/input_converter.dart b/pkg/analysis_server/benchmark/integration/input_converter.dart
index 2e941ff..f619845 100644
--- a/pkg/analysis_server/benchmark/integration/input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/input_converter.dart
@@ -72,6 +72,8 @@
 
   CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap);
 
+  Map<String, dynamic> asMap(dynamic value) => value as Map<String, dynamic>;
+
   /**
    * Return an operation for the notification or `null` if none.
    */
@@ -79,9 +81,9 @@
     String event = json['event'];
     if (event == SERVER_STATUS) {
       // {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
-      Map<String, dynamic> params = json['params'];
+      Map<String, dynamic> params = asMap(json['params']);
       if (params != null) {
-        Map<String, dynamic> analysis = params['analysis'];
+        Map<String, dynamic> analysis = asMap(params['analysis']);
         if (analysis != null && analysis['isAnalyzing'] == false) {
           return new WaitForAnalysisCompleteOperation();
         }
@@ -101,7 +103,7 @@
    * Return an operation for the request or `null` if none.
    */
   Operation convertRequest(Map<String, dynamic> origJson) {
-    Map<String, dynamic> json = translateSrcPaths(origJson);
+    Map<String, dynamic> json = asMap(translateSrcPaths(origJson));
     requestMap[json['id']] = json;
     String method = json['method'];
     // Sanity check operations that modify source
@@ -172,8 +174,8 @@
    * Return an operation for the recorded/expected response.
    */
   Operation convertResponse(Map<String, dynamic> json) {
-    return new ResponseOperation(
-        this, requestMap.remove(json['id']), translateSrcPaths(json));
+    return new ResponseOperation(this, asMap(requestMap.remove(json['id'])),
+        asMap(translateSrcPaths(json)));
   }
 
   void logOverlayContent() {
diff --git a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
index 1bbd728..bcfca4e 100644
--- a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
@@ -96,7 +96,7 @@
 
   Map<String, dynamic> decodeJson(String line, String text) {
     try {
-      return JSON.decode(text);
+      return asMap(JSON.decode(text));
     } catch (e, s) {
       throw new AnalysisException(
           'Failed to decode JSON: $text\n$line', new CaughtException(e, s));
diff --git a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
index ba98b3b..3490860 100644
--- a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
@@ -32,14 +32,14 @@
       String timeStampString = _parseTimeStamp(line);
       String data = line.substring(timeStampString.length);
       if (data.startsWith(RECEIVED_FRAGMENT)) {
-        Map<String, dynamic> json = JSON.decode(data.substring(4));
+        Map<String, dynamic> json = asMap(JSON.decode(data.substring(4)));
         if (json.containsKey('event')) {
           return convertNotification(json);
         } else {
           return convertResponse(json);
         }
       } else if (data.startsWith(SENT_FRAGMENT)) {
-        Map<String, dynamic> json = JSON.decode(data.substring(4));
+        Map<String, dynamic> json = asMap(JSON.decode(data.substring(4)));
         if (json.containsKey('method')) {
           return convertRequest(json);
         }
diff --git a/pkg/analysis_server/benchmark/integration/operation.dart b/pkg/analysis_server/benchmark/integration/operation.dart
index 0033d1f..eec7d45 100644
--- a/pkg/analysis_server/benchmark/integration/operation.dart
+++ b/pkg/analysis_server/benchmark/integration/operation.dart
@@ -91,7 +91,9 @@
           .log(Level.FINE, 'Response received: $method : $elapsed\n  $result');
     }
 
-    driver.send(method, json['params']).then((Map<String, dynamic> result) {
+    driver
+        .send(method, converter.asMap(json['params']))
+        .then((Map<String, dynamic> result) {
       recordResult(true, result);
       processResult(originalId, result, stopwatch);
     }).catchError((exception) {
diff --git a/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart b/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart
index 3d18865..3e3af14 100644
--- a/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart
@@ -30,7 +30,10 @@
   }
   source = args[SOURCE_OPTION];
   priorityFile = args[PRIORITY_FILE_OPTION];
-  metricNames.addAll(args[METRIC_NAME_OPTION]);
+  List names = args[METRIC_NAME_OPTION] as List;
+  for (var name in names) {
+    metricNames.add(name as String);
+  }
   unittestConfiguration.timeout = new Duration(minutes: 20);
 
   var test;
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol.dart b/pkg/analysis_server/lib/plugin/protocol/protocol.dart
index 9daa9f0..032e4f9 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol.dart
@@ -86,9 +86,9 @@
   /**
    * Initialize a newly created instance based on the given JSON data.
    */
-  factory Notification.fromJson(Map<String, Object> json) {
-    return new Notification(
-        json[Notification.EVENT], json[Notification.PARAMS]);
+  factory Notification.fromJson(Map json) {
+    return new Notification(json[Notification.EVENT],
+        json[Notification.PARAMS] as Map<String, Object>);
   }
 
   /**
@@ -194,7 +194,7 @@
     }
     var params = result[Request.PARAMS];
     if (params is Map || params == null) {
-      return new Request(id, method, params, time);
+      return new Request(id, method, params as Map<String, Object>, time);
     } else {
       return null;
     }
@@ -224,7 +224,7 @@
     try {
       var result = JSON.decode(data);
       if (result is Map) {
-        return new Request.fromJson(result);
+        return new Request.fromJson(result as Map<String, dynamic>);
       }
       return null;
     } catch (exception) {
@@ -368,7 +368,7 @@
   /**
    * Initialize a newly created instance based on the given JSON data.
    */
-  factory Response.fromJson(Map<String, Object> json) {
+  factory Response.fromJson(Map json) {
     try {
       Object id = json[Response.ID];
       if (id is! String) {
@@ -383,7 +383,7 @@
       Object result = json[Response.RESULT];
       Map<String, Object> decodedResult;
       if (result is Map) {
-        decodedResult = result;
+        decodedResult = result as Map<String, Object>;
       }
       return new Response(id, error: decodedError, result: decodedResult);
     } catch (exception) {
diff --git a/pkg/analysis_server/lib/src/analysis_manager.dart b/pkg/analysis_server/lib/src/analysis_manager.dart
index fd9bfcd..2e9924c 100644
--- a/pkg/analysis_server/lib/src/analysis_manager.dart
+++ b/pkg/analysis_server/lib/src/analysis_manager.dart
@@ -60,19 +60,22 @@
   /**
    * Launch an analysis server and open a connection to that server.
    */
-  Future<AnalysisManager> _launchServer(String pathToServer) {
-    // TODO dynamically allocate port and/or allow client to specify port
-    List<String> serverArgs = [pathToServer, '--port', PORT.toString()];
-    return Process.start(Platform.executable, serverArgs).catchError((error) {
+  Future<AnalysisManager> _launchServer(String pathToServer) async {
+    try {
+      // TODO dynamically allocate port and/or allow client to specify port
+      List<String> serverArgs = [pathToServer, '--port', PORT.toString()];
+      Process process = await Process.start(Platform.executable, serverArgs);
+      return _listenForPort(process);
+    } catch (error) {
       exitCode = 1;
       throw 'Failed to launch analysis server: $error';
-    }).then(_listenForPort);
+    }
   }
 
   /**
    * Listen for a port from the given analysis server process.
    */
-  Future<AnalysisManager> _listenForPort(Process process) {
+  Future<AnalysisManager> _listenForPort(Process process) async {
     this.process = process;
 
     // Echo stdout and stderr
@@ -82,18 +85,18 @@
 
     // Listen for port from server
     const String pattern = 'Listening on port ';
-    return out
-        .firstWhere((String line) => line.startsWith(pattern))
-        .timeout(new Duration(seconds: 10))
-        .catchError((error) {
-      exitCode = 1;
-      process.kill();
-      throw 'Expected port from analysis server';
-    }).then((String line) {
+    try {
+      String line = await out
+          .firstWhere((String line) => line.startsWith(pattern))
+          .timeout(new Duration(seconds: 10));
       String port = line.substring(pattern.length).trim();
       String url = 'ws://${InternetAddress.LOOPBACK_IP_V4.address}:$port/';
       return _openConnection(url);
-    });
+    } catch (error) {
+      exitCode = 1;
+      process.kill();
+      throw 'Expected port from analysis server';
+    }
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 101348b..6bda5f9 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -1471,7 +1471,7 @@
     onContextsChanged.listen((ContextsChangedEvent event) {
       for (AnalysisContext context in event.added) {
         context
-            .onResultChanged(RESOLVED_UNIT2)
+            .onResultChanged(RESOLVED_UNIT3)
             .listen((ResultChangedEvent event) {
           if (event.wasComputed) {
             Object value = event.value;
diff --git a/pkg/analysis_server/lib/src/channel/web_socket_channel.dart b/pkg/analysis_server/lib/src/channel/web_socket_channel.dart
index 961bee6..0368eb6 100644
--- a/pkg/analysis_server/lib/src/channel/web_socket_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/web_socket_channel.dart
@@ -90,7 +90,7 @@
 
   @override
   void listen(void onRequest(Request request),
-      {void onError(), void onDone()}) {
+      {Function onError, void onDone()}) {
     socket.listen((data) => readRequest(data, onRequest),
         onError: onError, onDone: onDone);
   }
diff --git a/pkg/analysis_server/lib/src/collections.dart b/pkg/analysis_server/lib/src/collections.dart
index 1a1ba38..f8ae2e4 100644
--- a/pkg/analysis_server/lib/src/collections.dart
+++ b/pkg/analysis_server/lib/src/collections.dart
@@ -5,21 +5,23 @@
 library collections;
 
 /**
- * Returns the concatentation of the input iterables.
+ * Returns the concatenation of the input [iterables].
  *
  * The returned iterable is a lazily-evaluated view on the input iterables.
  */
-Iterable concat(Iterable<Iterable> iterables) => iterables.expand((x) => x);
+Iterable/*<E>*/ concat/*<E>*/(Iterable<Iterable/*<E>*/ > iterables) =>
+    iterables.expand((x) => x);
 
 /**
- * Returns the concatentation of the input iterables as a [List].
+ * Returns the concatenation of the input [iterables] as a [List].
  */
-List concatToList(Iterable<Iterable> iterables) => concat(iterables).toList();
+List/*<E>*/ concatToList/*<E>*/(Iterable<Iterable/*<E>*/ > iterables) =>
+    concat(iterables).toList();
 
 /**
  * Returns the given [list] if it is not empty, or `null` otherwise.
  */
-List nullIfEmpty(List list) {
+List/*<E>*/ nullIfEmpty/*<E>*/(List/*<E>*/ list) {
   if (list == null) {
     return null;
   }
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index fc2573c..13f2052 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -592,7 +592,7 @@
       info.context.analysisOptions = new AnalysisOptionsImpl();
 
       // Apply inherited options.
-      options = _getEmbeddedOptions(info.context);
+      options = _toStringMap(_getEmbeddedOptions(info.context));
       if (options != null) {
         configureContextOptions(info.context, options);
       }
@@ -600,7 +600,7 @@
       // Check for embedded options.
       YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
       if (embeddedOptions != null) {
-        options = new Merger().merge(embeddedOptions, options);
+        options = _toStringMap(new Merger().merge(embeddedOptions, options));
       }
     }
 
@@ -624,15 +624,13 @@
     }
 
     var analyzer = options[AnalyzerOptions.analyzer];
-    if (analyzer is! Map) {
-      // Done.
-      return;
-    }
-
-    // Set ignore patterns.
-    YamlList exclude = analyzer[AnalyzerOptions.exclude];
-    if (exclude != null) {
-      setIgnorePatternsForContext(info, exclude);
+    if (analyzer is Map) {
+      // Set ignore patterns.
+      YamlList exclude = analyzer[AnalyzerOptions.exclude];
+      List<String> excludeList = _toStringList(exclude);
+      if (excludeList != null) {
+        setIgnorePatternsForContext(info, excludeList);
+      }
     }
   }
 
@@ -1563,6 +1561,44 @@
     return false;
   }
 
+  /**
+   * If all of the elements of [list] are strings, return a list of strings
+   * containing the same elements. Otherwise, return `null`.
+   */
+  List<String> _toStringList(YamlList list) {
+    if (list == null) {
+      return null;
+    }
+    List<String> stringList = <String>[];
+    for (var element in list) {
+      if (element is String) {
+        stringList.add(element);
+      } else {
+        return null;
+      }
+    }
+    return stringList;
+  }
+
+  /**
+   * If the given [object] is a map, and all of the keys in the map are strings,
+   * return a map containing the same mappings. Otherwise, return `null`.
+   */
+  Map<String, Object> _toStringMap(Object object) {
+    if (object is Map) {
+      Map<String, Object> stringMap = new HashMap<String, Object>();
+      for (var key in object.keys) {
+        if (key is String) {
+          stringMap[key] = object[key];
+        } else {
+          return null;
+        }
+      }
+      return stringMap;
+    }
+    return null;
+  }
+
   void _updateContextPackageUriResolver(
       Folder contextFolder, FolderDisposition disposition) {
     AnalysisContext context = folderMap[contextFolder];
diff --git a/pkg/analysis_server/lib/src/protocol/protocol_internal.dart b/pkg/analysis_server/lib/src/protocol/protocol_internal.dart
index 256523a..e2697f3 100644
--- a/pkg/analysis_server/lib/src/protocol/protocol_internal.dart
+++ b/pkg/analysis_server/lib/src/protocol/protocol_internal.dart
@@ -131,16 +131,24 @@
  * Translate the input [map], applying [keyCallback] to all its keys, and
  * [valueCallback] to all its values.
  */
-mapMap(Map map, {dynamic keyCallback(key), dynamic valueCallback(value)}) {
-  Map result = {};
+Map/*<KR, VR>*/ mapMap/*<KP, VP, KR, VR>*/(Map/*<KP, VP>*/ map,
+    {dynamic/*=KR*/ keyCallback(/*<KP>*/ key),
+    dynamic/*=VR*/ valueCallback(/*<VP>*/ value)}) {
+  Map/*<KR, VR>*/ result = new HashMap/*<KR, VR>*/();
   map.forEach((key, value) {
+    Object/*=KR*/ resultKey;
+    Object/*=VR*/ resultValue;
     if (keyCallback != null) {
-      key = keyCallback(key);
+      resultKey = keyCallback(key);
+    } else {
+      resultKey = key as Object/*=KR*/;
     }
     if (valueCallback != null) {
-      value = valueCallback(value);
+      resultValue = valueCallback(value);
+    } else {
+      resultValue = value as Object/*=VR*/;
     }
-    result[key] = value;
+    result[resultKey] = resultValue;
   });
   return result;
 }
@@ -222,7 +230,7 @@
  * string describing the part of the JSON object being decoded, and [value] is
  * the part to decode.
  */
-typedef Object JsonDecoderCallback(String jsonPath, Object value);
+typedef E JsonDecoderCallback<E>(String jsonPath, Object value);
 
 /**
  * Instances of the class [HasToJson] implement [toJson] method that returns
@@ -303,14 +311,17 @@
   }
 
   /**
-   * Decode a JSON object that is expected to be a List.  [decoder] is used to
-   * decode the items in the list.
+   * Decode a JSON object that is expected to be a List. The [decoder] is used
+   * to decode the items in the list.
+   *
+   * The type parameter [E] is the expected type of the elements in the list.
    */
-  List decodeList(String jsonPath, Object json, [JsonDecoderCallback decoder]) {
+  List/*<E>*/ decodeList/*<E>*/(String jsonPath, Object json,
+      [JsonDecoderCallback/*<E>*/ decoder]) {
     if (json == null) {
-      return [];
+      return/*<E>*/ [];
     } else if (json is List) {
-      List result = [];
+      List/*<E>*/ result = /*<E>*/ [];
       for (int i = 0; i < json.length; i++) {
         result.add(decoder('$jsonPath[$i]', json[i]));
       }
@@ -324,23 +335,24 @@
    * Decode a JSON object that is expected to be a Map.  [keyDecoder] is used
    * to decode the keys, and [valueDecoder] is used to decode the values.
    */
-  Map decodeMap(String jsonPath, Object json,
-      {JsonDecoderCallback keyDecoder, JsonDecoderCallback valueDecoder}) {
+  Map/*<K, V>*/ decodeMap/*<K, V>*/(String jsonPath, Object json,
+      {JsonDecoderCallback/*<K>*/ keyDecoder,
+      JsonDecoderCallback/*<V>*/ valueDecoder}) {
     if (json == null) {
       return {};
     } else if (json is Map) {
-      Map result = {};
+      Map/*<K, V>*/ result = /*<K, V>*/ {};
       json.forEach((String key, value) {
-        Object decodedKey;
+        Object/*=K*/ decodedKey;
         if (keyDecoder != null) {
           decodedKey = keyDecoder('$jsonPath.key', key);
         } else {
-          decodedKey = key;
+          decodedKey = key as Object/*=K*/;
         }
         if (valueDecoder != null) {
           value = valueDecoder('$jsonPath[${JSON.encode(key)}]', value);
         }
-        result[decodedKey] = value;
+        result[decodedKey] = value as Object/*=V*/;
       });
       return result;
     } else {
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
index 253a4ad..ea6b489 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
@@ -55,8 +55,8 @@
    * Return a list containing all of the Dart specific completion contributors.
    */
   Iterable<DartCompletionContributor> get contributors =>
-      _contributorExtensionPoint.extensions
-          .map((DartCompletionContributorFactory factory) => factory());
+      _contributorExtensionPoint.extensions.map(
+          (Object factory) => (factory as DartCompletionContributorFactory)());
 
   @override
   String get uniqueIdentifier => UNIQUE_IDENTIFIER;
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index 0608764..74c72ef 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -46,20 +46,19 @@
    * Returns a [Future] completing with a [List] of references to [element] or
    * to the corresponding hierarchy [Element]s.
    */
-  Future<List<SearchResult>> _findElementsReferences(Element element) {
-    return _getRefElements(element).then((Iterable<Element> refElements) {
-      var futureGroup = new _ConcatFutureGroup<SearchResult>();
-      for (Element refElement in refElements) {
-        // add declaration
-        if (_isDeclarationInteresting(refElement)) {
-          SearchResult searchResult = _newDeclarationResult(refElement);
-          futureGroup.add(searchResult);
-        }
-        // do search
-        futureGroup.add(_findSingleElementReferences(refElement));
+  Future<List<SearchResult>> _findElementsReferences(Element element) async {
+    Iterable<Element> refElements = await _getRefElements(element);
+    var futureGroup = new _ConcatFutureGroup<SearchResult>();
+    for (Element refElement in refElements) {
+      // add declaration
+      if (_isDeclarationInteresting(refElement)) {
+        SearchResult searchResult = _newDeclarationResult(refElement);
+        futureGroup.add(searchResult);
       }
-      return futureGroup.future;
-    });
+      // do search
+      futureGroup.add(_findSingleElementReferences(refElement));
+    }
+    return futureGroup.future;
   }
 
   /**
@@ -149,9 +148,9 @@
    */
   void add(value) {
     if (value is Future) {
-      _futures.add(value);
+      _futures.add(value as Future<List<E>>);
     } else {
-      _futures.add(new Future.value(<E>[value]));
+      _futures.add(new Future.value(<E>[value as E]));
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/search/type_hierarchy.dart b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
index e723722..29af16e 100644
--- a/pkg/analysis_server/lib/src/search/type_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
@@ -53,15 +53,14 @@
   /**
    * Returns the computed type hierarchy, maybe `null`.
    */
-  Future<List<TypeHierarchyItem>> compute() {
+  Future<List<TypeHierarchyItem>> compute() async {
     if (_pivotClass != null) {
       InterfaceType type = _pivotClass.type;
       _createSuperItem(type);
-      return _createSubclasses(_items[0], 0, type).then((_) {
-        return new Future.value(_items);
-      });
+      await _createSubclasses(_items[0], 0, type);
+      return _items;
     }
-    return new Future.value(null);
+    return null;
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 73867fe..f04824f 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -467,7 +467,7 @@
    */
   dynamic _captureExceptions(InstrumentationService service, dynamic callback(),
       {void print(String line)}) {
-    Function errorFunction = (Zone self, ZoneDelegate parent, Zone zone,
+    var errorFunction = (Zone self, ZoneDelegate parent, Zone zone,
         dynamic exception, StackTrace stackTrace) {
       service.logPriorityException(exception, stackTrace);
       AnalysisServer analysisServer = socketServer.analysisServer;
@@ -475,11 +475,11 @@
           'Captured exception', exception, stackTrace);
       throw exception;
     };
-    Function printFunction = print == null
+    var printFunction = print == null
         ? null
         : (Zone self, ZoneDelegate parent, Zone zone, String line) {
-            // Note: we don't pass the line on to stdout, because that is reserved
-            // for communication to the client.
+            // Note: we don't pass the line on to stdout, because that is
+            // reserved for communication to the client.
             print(line);
           };
     ZoneSpecification zoneSpecification = new ZoneSpecification(
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
index f06cc07..8f27b86 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
@@ -55,7 +55,7 @@
     if (libElem is LibraryElement) {
       var unit = request.context.getResult(
           new LibrarySpecificUnit(libElem.source, request.source),
-          RESOLVED_UNIT3);
+          RESOLVED_UNIT4);
       if (unit is CompilationUnit) {
         return new CompletionTarget.forOffset(unit, request.offset);
       }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 42d6823..21ba3c7 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -299,7 +299,7 @@
       CompilationUnit unit = await _computeAsync(
           this,
           new LibrarySpecificUnit(libElem.source, unresolvedUnit.source),
-          RESOLVED_UNIT3,
+          RESOLVED_UNIT4,
           performance,
           'resolve library unit');
       checkAborted();
@@ -376,7 +376,7 @@
       unit = await _computeAsync(
           request,
           new LibrarySpecificUnit(libSource, source),
-          resultDescriptor ?? RESOLVED_UNIT3,
+          resultDescriptor ?? RESOLVED_UNIT4,
           performance,
           'resolve declarations');
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 807a02e..2867beb 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -81,7 +81,8 @@
         if (next.isSynthetic) {
           next = next.next;
         }
-        if (previous.lexeme == ')' && next.lexeme == '{') {
+        if (previous.type == TokenType.CLOSE_PAREN &&
+            next.type == TokenType.OPEN_CURLY_BRACKET) {
           _addSuggestion2(ASYNC);
           _addSuggestion2(ASYNC_STAR);
           _addSuggestion2(SYNC_STAR);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
index 9688be3..8600be2 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
@@ -191,8 +191,8 @@
 
   _LabelVisitor(DartCompletionRequest request, this.includeStatementLabels,
       this.includeCaseLabels, this.suggestions)
-      : super(request.offset),
-        request = request;
+      : request = request,
+        super(request.offset);
 
   @override
   void declaredClass(ClassDeclaration declaration) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
index b9fea93..eb527a4 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
@@ -181,8 +181,8 @@
   final List<CompletionSuggestion> suggestions;
 
   _Visitor(DartCompletionRequest request, this.suggestions)
-      : super(request.offset),
-        request = request;
+      : request = request,
+        super(request.offset);
 
   @override
   void declaredClass(ClassDeclaration declaration) {
diff --git a/pkg/analysis_server/lib/src/services/correction/sort_members.dart b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
index f1d788c..4592367 100644
--- a/pkg/analysis_server/lib/src/services/correction/sort_members.dart
+++ b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
@@ -7,7 +7,6 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
 import 'package:analysis_server/src/services/correction/strings.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
 
 /**
  * Sorter for unit/class members.
@@ -63,16 +62,9 @@
     // prepare edits
     List<SourceEdit> edits = <SourceEdit>[];
     if (code != initialCode) {
-      int prefixLength = findCommonPrefix(initialCode, code);
-      int suffixLength = findCommonSuffix(initialCode, code);
-      String prefix = code.substring(0, prefixLength);
-      String suffix = code.substring(code.length - suffixLength, code.length);
-      int commonLength = findCommonOverlap(prefix, suffix);
-      suffixLength -= commonLength;
-      SourceEdit edit = new SourceEdit(
-          prefixLength,
-          initialCode.length - suffixLength - prefixLength,
-          code.substring(prefixLength, code.length - suffixLength));
+      SimpleDiff diff = computeSimpleDiff(initialCode, code);
+      SourceEdit edit =
+          new SourceEdit(diff.offset, diff.length, diff.replacement);
       edits.add(edit);
     }
     return edits;
@@ -161,8 +153,12 @@
    * Sorts all [Directive]s.
    */
   void _sortUnitDirectives() {
+    bool hasLibraryDirective = false;
     List<_DirectiveInfo> directives = [];
     for (Directive directive in unit.directives) {
+      if (directive is LibraryDirective) {
+        hasLibraryDirective = true;
+      }
       if (directive is! UriBasedDirective) {
         continue;
       }
@@ -195,10 +191,17 @@
         kind = _DirectivePriority.PART;
       }
       if (kind != null) {
-        int offset = directive.offset;
-        int length = directive.length;
+        String documentationText;
+        if (directive.documentationComment != null) {
+          documentationText = code.substring(
+              directive.documentationComment.offset,
+              directive.documentationComment.end);
+        }
+        int offset = directive.firstTokenAfterCommentAndMetadata.offset;
+        int length = directive.end - offset;
         String text = code.substring(offset, offset + length);
-        directives.add(new _DirectiveInfo(directive, kind, uriContent, text));
+        directives.add(new _DirectiveInfo(
+            directive, kind, uriContent, documentationText, text));
       }
     }
     // nothing to do
@@ -207,6 +210,12 @@
     }
     int firstDirectiveOffset = directives[0].directive.offset;
     int lastDirectiveEnd = directives[directives.length - 1].directive.end;
+    // Without a library directive, the library comment is the comment of the
+    // first directive.
+    _DirectiveInfo libraryDocumentationDirective;
+    if (!hasLibraryDirective && directives.isNotEmpty) {
+      libraryDocumentationDirective = directives.first;
+    }
     // do sort
     directives.sort();
     // append directives with grouping
@@ -215,6 +224,7 @@
       StringBuffer sb = new StringBuffer();
       String endOfLine = this.endOfLine;
       _DirectivePriority currentPriority = null;
+      bool firstOutputDirective = true;
       for (_DirectiveInfo directive in directives) {
         if (currentPriority != directive.priority) {
           if (sb.length != 0) {
@@ -222,35 +232,25 @@
           }
           currentPriority = directive.priority;
         }
+        if (directive != libraryDocumentationDirective &&
+            directive.documentationText != null) {
+          sb.write(directive.documentationText);
+          sb.write(endOfLine);
+        }
+        if (firstOutputDirective) {
+          firstOutputDirective = false;
+          if (libraryDocumentationDirective != null &&
+              libraryDocumentationDirective.documentationText != null) {
+            sb.write(libraryDocumentationDirective.documentationText);
+            sb.write(endOfLine);
+          }
+        }
         sb.write(directive.text);
         sb.write(endOfLine);
       }
       directivesCode = sb.toString();
       directivesCode = directivesCode.trimRight();
     }
-    // append comment tokens which otherwise would be removed completely
-    {
-      bool firstCommentToken = true;
-      Token token = unit.beginToken;
-      while (token != null &&
-          token.type != TokenType.EOF &&
-          token.end < lastDirectiveEnd) {
-        Token commentToken = token.precedingComments;
-        while (commentToken != null) {
-          int offset = commentToken.offset;
-          int end = commentToken.end;
-          if (offset > firstDirectiveOffset && offset < lastDirectiveEnd) {
-            if (firstCommentToken) {
-              directivesCode += endOfLine;
-              firstCommentToken = false;
-            }
-            directivesCode += code.substring(offset, end) + endOfLine;
-          }
-          commentToken = commentToken.next;
-        }
-        token = token.next;
-      }
-    }
     // prepare code
     String beforeDirectives = code.substring(0, firstDirectiveOffset);
     String afterDirectives = code.substring(lastDirectiveEnd);
@@ -368,9 +368,11 @@
   final Directive directive;
   final _DirectivePriority priority;
   final String uri;
+  final String documentationText;
   final String text;
 
-  _DirectiveInfo(this.directive, this.priority, this.uri, this.text);
+  _DirectiveInfo(this.directive, this.priority, this.uri,
+      this.documentationText, this.text);
 
   @override
   int compareTo(_DirectiveInfo other) {
diff --git a/pkg/analysis_server/lib/src/services/correction/strings.dart b/pkg/analysis_server/lib/src/services/correction/strings.dart
index 4a0ff76..1c38cbf6 100644
--- a/pkg/analysis_server/lib/src/services/correction/strings.dart
+++ b/pkg/analysis_server/lib/src/services/correction/strings.dart
@@ -41,6 +41,24 @@
   return a.compareTo(b);
 }
 
+/**
+ * Return a simple difference between the given [oldStr] and [newStr].
+ */
+SimpleDiff computeSimpleDiff(String oldStr, String newStr) {
+  int prefixLength = findCommonPrefix(oldStr, newStr);
+  int suffixLength = findCommonSuffix(oldStr, newStr);
+  while (prefixLength >= 0) {
+    int oldReplaceLength = oldStr.length - prefixLength - suffixLength;
+    int newReplaceLength = newStr.length - prefixLength - suffixLength;
+    if (oldReplaceLength >= 0 && newReplaceLength >= 0) {
+      return new SimpleDiff(prefixLength, oldReplaceLength,
+          newStr.substring(prefixLength, newStr.length - suffixLength));
+    }
+    prefixLength--;
+  }
+  return new SimpleDiff(0, oldStr.length, newStr);
+}
+
 int countLeadingWhitespaces(String str) {
   int i = 0;
   for (; i < str.length; i++) {
@@ -279,3 +297,15 @@
   }
   return str.substring(pos + separator.length);
 }
+
+/**
+ * Information about a single replacement that should be made to convert the
+ * "old" string to the "new" one.
+ */
+class SimpleDiff {
+  final int offset;
+  final int length;
+  final String replacement;
+
+  SimpleDiff(this.offset, this.length, this.replacement);
+}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 8e059bc..106684a 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -55,9 +55,9 @@
 /**
  * Returns the [Map] which maps [map] values to their keys.
  */
-Map<String, String> _inverseMap(Map map) {
-  Map result = {};
-  map.forEach((key, value) {
+Map<String, String> _inverseMap(Map<String, String> map) {
+  Map<String, String> result = <String, String>{};
+  map.forEach((String key, String value) {
     result[value] = key;
   });
   return result;
@@ -420,7 +420,7 @@
       return validateCreateMethod(searchEngine, classElement, name);
     }
     // OK
-    return new Future.value(result);
+    return new Future<RefactoringStatus>.value(result);
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
index 6312658..141eb8a 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
@@ -84,7 +84,7 @@
       result = new RefactoringStatus.fatal(
           'Local variable declaration or reference must be selected '
           'to activate this refactoring.');
-      return new Future.value(result);
+      return new Future<RefactoringStatus>.value(result);
     }
     // should have initializer at declaration
     if (_variableNode.initializer == null) {
@@ -93,7 +93,7 @@
           _variableElement.displayName);
       result = new RefactoringStatus.fatal(
           message, newLocation_fromNode(_variableNode));
-      return new Future.value(result);
+      return new Future<RefactoringStatus>.value(result);
     }
     // prepare references
     _references = await searchEngine.searchReferences(_variableElement);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index c136c21..ca243c4 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -280,12 +280,12 @@
     // prepare method information
     result.addStatus(_prepareMethod());
     if (result.hasFatalError) {
-      return new Future.value(result);
+      return new Future<RefactoringStatus>.value(result);
     }
     // maybe operator
     if (_methodElement.isOperator) {
       result = new RefactoringStatus.fatal('Cannot inline operator.');
-      return new Future.value(result);
+      return new Future<RefactoringStatus>.value(result);
     }
     // analyze method body
     result.addStatus(_prepareMethodParts());
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
index b6f54c1..df0bf60 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
@@ -128,10 +128,11 @@
 abstract class RenameRefactoringImpl extends RefactoringImpl
     implements RenameRefactoring {
   final SearchEngine searchEngine;
-  final Element element;
+  final Element _element;
   final AnalysisContext context;
   final String elementKindName;
   final String oldName;
+  Element get element => _element;
 
   SourceChange change;
 
@@ -139,7 +140,7 @@
 
   RenameRefactoringImpl(SearchEngine searchEngine, Element element)
       : searchEngine = searchEngine,
-        element = element,
+        _element = element,
         context = element.context,
         elementKindName = element.kind.displayName,
         oldName = _getDisplayName(element);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index cdc8c2d..5c9e12f 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -63,7 +63,7 @@
     if (element is MethodElement && (element as MethodElement).isOperator) {
       result.addFatalError('Cannot rename operator.');
     }
-    return new Future.value(result);
+    return new Future<RefactoringStatus>.value(result);
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
index 831fadb..11500fc 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
@@ -6,7 +6,6 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
@@ -44,7 +43,7 @@
   }
 
   @override
-  Future<SourceChange> fillChange() {
+  Future fillChange() {
     addDeclarationEdit(element);
     return searchEngine.searchReferences(element).then(addReferenceEdits);
   }
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index f3ad992..c6b552f 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -35,13 +35,13 @@
   List<Element> members = <Element>[];
   visitChildren(clazz, (Element element) {
     if (element.isSynthetic) {
-      return;
+      return false;
     }
     if (element is ConstructorElement) {
-      return;
+      return false;
     }
     if (name != null && element.displayName != name) {
-      return;
+      return false;
     }
     if (element is ExecutableElement) {
       members.add(element);
@@ -49,6 +49,7 @@
     if (element is FieldElement) {
       members.add(element);
     }
+    return false;
   });
   return members;
 }
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 47cbcbd..a2cc48f 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -457,6 +457,10 @@
     if (unit != null) {
       return unit;
     }
+    unit = entry.getValue(RESOLVED_UNIT12);
+    if (unit != null) {
+      return unit;
+    }
     return entry.getValue(RESOLVED_UNIT);
   }
 
@@ -526,6 +530,7 @@
       results.add(RESOLVED_UNIT9);
       results.add(RESOLVED_UNIT10);
       results.add(RESOLVED_UNIT11);
+      results.add(RESOLVED_UNIT12);
       results.add(RESOLVED_UNIT);
       results.add(STRONG_MODE_ERRORS);
       results.add(USED_IMPORTED_ELEMENTS);
@@ -886,12 +891,11 @@
     Map<Folder, List<CacheEntry>> entryMap =
         new HashMap<Folder, List<CacheEntry>>();
     StringBuffer invalidKeysBuffer = new StringBuffer();
-    analysisServer.folderMap
-        .forEach((Folder folder, InternalAnalysisContext context) {
+    analysisServer.folderMap.forEach((Folder folder, AnalysisContext context) {
       Source source = context.sourceFactory.forUri(sourceUri);
       if (source != null) {
         MapIterator<AnalysisTarget, CacheEntry> iterator =
-            context.analysisCache.iterator();
+            (context as InternalAnalysisContext).analysisCache.iterator();
         while (iterator.moveNext()) {
           if (source == iterator.key.source) {
             if (!allContexts.contains(folder)) {
@@ -1223,15 +1227,15 @@
       return _returnFailure(request, 'Invalid context: $contextFilter');
     }
 
-    List<String> priorityNames;
+    List<String> priorityNames = <String>[];
     List<String> explicitNames = <String>[];
     List<String> implicitNames = <String>[];
     Map<String, String> links = new HashMap<String, String>();
     List<CaughtException> exceptions = <CaughtException>[];
     InternalAnalysisContext context = analysisServer.folderMap[folder];
-    priorityNames = context.prioritySources
-        .map((Source source) => source.fullName)
-        .toList();
+    context.prioritySources.forEach((Source source) {
+      priorityNames.add(source.fullName);
+    });
     MapIterator<AnalysisTarget, CacheEntry> iterator =
         context.analysisCache.iterator(context: context);
     while (iterator.moveNext()) {
@@ -1885,7 +1889,7 @@
     buffer.write(_diagnosticCallAverage.value);
     buffer.write(' (ms)</p>&nbsp;');
 
-    var json = response.toJson()[Response.RESULT];
+    Map json = response.toJson()[Response.RESULT];
     List contexts = json['contexts'];
     contexts.sort((first, second) => first['name'].compareTo(second['name']));
 
@@ -2232,7 +2236,7 @@
     _writeTwoColumns(buffer, (StringBuffer buffer) {
       if (analysisServer == null) {
         buffer.write('Status: <span style="color:red">Not running</span>');
-        return false;
+        return;
       }
       buffer.write('<p>');
       buffer.write('Status: Running<br>');
@@ -2261,7 +2265,7 @@
     }, (StringBuffer buffer) {
       _writeSubscriptionList(buffer, ServerService.VALUES, services);
     });
-    return true;
+    return analysisServer != null;
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/status/validator.dart b/pkg/analysis_server/lib/src/status/validator.dart
index 75793e0..7c995ea 100644
--- a/pkg/analysis_server/lib/src/status/validator.dart
+++ b/pkg/analysis_server/lib/src/status/validator.dart
@@ -64,12 +64,12 @@
   void compareElements(Element expected, Element actual) {
     if (expected == null) {
       if (actual != null) {
-        _writeMismatch(expected, actual, (Element element) {
+        _writeMismatch(expected, actual, (Object element) {
           return element == null ? 'null' : 'non null ${element.runtimeType}';
         });
       }
     } else if (actual == null) {
-      _writeMismatch(expected, actual, (Element element) {
+      _writeMismatch(expected, actual, (Object element) {
         return element == null ? 'null' : 'non null ${element.runtimeType}';
       });
     } else if (expected is ClassElement && actual is ClassElement) {
@@ -135,7 +135,7 @@
       _writeMismatch(
           expected,
           actual,
-          (ClassElement element) => element.hasReferenceToSuper
+          (Object element) => (element as ClassElement).hasReferenceToSuper
               ? 'a class that references super'
               : 'a class that does not reference super');
     }
@@ -143,25 +143,26 @@
       _writeMismatch(
           expected,
           actual,
-          (ClassElement element) =>
-              element.isAbstract ? 'an abstract class' : 'a concrete class');
+          (Object element) => (element as ClassElement).isAbstract
+              ? 'an abstract class'
+              : 'a concrete class');
     }
     if (expected.isEnum != actual.isEnum ||
         expected.isMixinApplication != actual.isMixinApplication) {
-      _writeMismatch(
-          expected,
-          actual,
-          (ClassElement element) => element.isEnum
-              ? 'an enum'
-              : (element.isMixinApplication
-                  ? 'a mixin application'
-                  : 'a class'));
+      _writeMismatch(expected, actual, (Object element) {
+        ClassElement classElement = element as ClassElement;
+        return classElement.isEnum
+            ? 'an enum'
+            : (classElement.isMixinApplication
+                ? 'a mixin application'
+                : 'a class');
+      });
     }
     if (expected.isOrInheritsProxy != actual.isOrInheritsProxy) {
       _writeMismatch(
           expected,
           actual,
-          (ClassElement element) => element.isOrInheritsProxy
+          (Object element) => (element as ClassElement).isOrInheritsProxy
               ? 'a class that is marked as a proxy'
               : 'a class that is not marked as a proxy');
     }
@@ -169,8 +170,9 @@
       _writeMismatch(
           expected,
           actual,
-          (ClassElement element) =>
-              element.isValidMixin ? 'a valid mixin' : 'an invalid mixin');
+          (Object element) => (element as ClassElement).isValidMixin
+              ? 'a valid mixin'
+              : 'an invalid mixin');
     }
     _compareTypes('supertype', expected.supertype, actual.supertype);
     _compareTypeLists('mixin', expected.mixins, actual.mixins);
@@ -210,7 +212,7 @@
       _writeMismatch(
           expected,
           actual,
-          (ConstructorElement element) => element.isConst
+          (Object element) => (element as ConstructorElement).isConst
               ? 'a const constructor'
               : 'a non-const constructor');
     }
@@ -218,7 +220,7 @@
       _writeMismatch(
           expected,
           actual,
-          (ConstructorElement element) => element.isFactory
+          (Object element) => (element as ConstructorElement).isFactory
               ? 'a factory constructor'
               : 'a non-factory constructor');
     }
@@ -233,9 +235,10 @@
       _writeMismatch(
           expected,
           actual,
-          (ConstructorElement element) => element.redirectedConstructor == null
-              ? 'a redirecting constructor'
-              : 'a non-redirecting constructor');
+          (Object element) =>
+              (element as ConstructorElement).redirectedConstructor == null
+                  ? 'a redirecting constructor'
+                  : 'a non-redirecting constructor');
     }
   }
 
@@ -292,22 +295,24 @@
       _writeMismatch(
           expected,
           actual,
-          (ExecutableElement element) => element.hasImplicitReturnType
-              ? 'an implicit return type'
-              : 'an explicit return type');
+          (Object element) =>
+              (element as ExecutableElement).hasImplicitReturnType
+                  ? 'an implicit return type'
+                  : 'an explicit return type');
     }
     if (expected.isAbstract != actual.isAbstract) {
       _writeMismatch(
           expected,
           actual,
-          (ExecutableElement element) =>
-              element.isAbstract ? 'an abstract $kind' : 'a concrete $kind');
+          (Object element) => (element as ExecutableElement).isAbstract
+              ? 'an abstract $kind'
+              : 'a concrete $kind');
     }
     if (expected.isAsynchronous != actual.isAsynchronous) {
       _writeMismatch(
           expected,
           actual,
-          (ExecutableElement element) => element.isAsynchronous
+          (Object element) => (element as ExecutableElement).isAsynchronous
               ? 'an asynchronous $kind'
               : 'a synchronous $kind');
     }
@@ -315,7 +320,7 @@
       _writeMismatch(
           expected,
           actual,
-          (ExecutableElement element) => element.isExternal
+          (Object element) => (element as ExecutableElement).isExternal
               ? 'an external $kind'
               : 'a non-external $kind');
     }
@@ -323,7 +328,7 @@
       _writeMismatch(
           expected,
           actual,
-          (ExecutableElement element) => element.isGenerator
+          (Object element) => (element as ExecutableElement).isGenerator
               ? 'a generator $kind'
               : 'a non-generator $kind');
     }
@@ -331,21 +336,23 @@
       _writeMismatch(
           expected,
           actual,
-          (ExecutableElement element) =>
-              element.isOperator ? 'an operator' : 'a non-operator $kind');
+          (Object element) => (element as ExecutableElement).isOperator
+              ? 'an operator'
+              : 'a non-operator $kind');
     }
     if (expected.isStatic != actual.isStatic) {
       _writeMismatch(
           expected,
           actual,
-          (ExecutableElement element) =>
-              element.isStatic ? 'a static $kind' : 'an instance $kind');
+          (Object element) => (element as ExecutableElement).isStatic
+              ? 'a static $kind'
+              : 'an instance $kind');
     }
     if ((expected.returnType == null) != (actual.returnType == null)) {
       _writeMismatch(
           expected,
           actual,
-          (ExecutableElement element) => element.returnType == null
+          (Object element) => (element as ExecutableElement).returnType == null
               ? 'a $kind with no return type'
               : 'a $kind with a return type');
     } else {
@@ -369,12 +376,12 @@
     if ((expected.exportedLibrary == null) !=
         (actual.exportedLibrary == null)) {
       // TODO(brianwilkerson) Check for more than existence?
-      _writeMismatch(
-          expected,
-          actual,
-          (ExportElement element) => element.exportedLibrary == null
-              ? 'unresolved uri'
-              : 'uri resolved to ${element.exportedLibrary.source.fullName}');
+      _writeMismatch(expected, actual, (Object element) {
+        ExportElement exportElement = element as ExportElement;
+        return exportElement.exportedLibrary == null
+            ? 'unresolved uri'
+            : 'uri resolved to ${exportElement.exportedLibrary.source.fullName}';
+      });
     }
     //
     // Compare children.
@@ -391,8 +398,9 @@
       _writeMismatch(
           expected,
           actual,
-          (FieldElement element) =>
-              element.isEnumConstant ? 'an enum constant' : 'a normal field');
+          (Object element) => (element as FieldElement).isEnumConstant
+              ? 'an enum constant'
+              : 'a normal field');
     }
   }
 
@@ -443,26 +451,26 @@
       _writeMismatch(
           expected,
           actual,
-          (ImportElement element) => element.isDeferred
+          (Object element) => (element as ImportElement).isDeferred
               ? 'a deferred import'
               : 'a non-deferred import');
     }
     if ((expected.importedLibrary == null) !=
         (actual.importedLibrary == null)) {
-      _writeMismatch(
-          expected,
-          actual,
-          (ImportElement element) => element.importedLibrary == null
-              ? 'unresolved uri'
-              : 'uri resolved to ${element.importedLibrary.source.fullName}');
+      _writeMismatch(expected, actual, (Object element) {
+        ImportElement importElement = element as ImportElement;
+        return importElement.importedLibrary == null
+            ? 'unresolved uri'
+            : 'uri resolved to ${importElement.importedLibrary.source.fullName}';
+      });
     }
     if ((expected.prefix == null) != (actual.prefix == null)) {
-      _writeMismatch(
-          expected,
-          actual,
-          (ImportElement element) => element.prefix == null
-              ? 'no prefix'
-              : 'a prefix named ${element.prefix.name}');
+      _writeMismatch(expected, actual, (Object element) {
+        ImportElement importElement = element as ImportElement;
+        return importElement.prefix == null
+            ? 'no prefix'
+            : 'a prefix named ${importElement.prefix.name}';
+      });
     }
     if (expected.prefixOffset != actual.prefixOffset) {
       _write('Expected a prefix offset of ');
@@ -519,8 +527,9 @@
       _writeMismatch(
           expected,
           actual,
-          (FieldElement element) =>
-              element.isStatic ? 'a static field' : 'an instance field');
+          (Object element) => (element as FieldElement).isStatic
+              ? 'a static field'
+              : 'an instance field');
     }
   }
 
@@ -683,7 +692,7 @@
       _writeMismatch(
           expected,
           actual,
-          (VariableElement element) => element.constantValue == null
+          (Object element) => (element as VariableElement).constantValue == null
               ? 'a $kind with no constant value'
               : 'a $kind with a constant value');
     }
@@ -691,7 +700,7 @@
       _writeMismatch(
           expected,
           actual,
-          (VariableElement element) => element.hasImplicitType
+          (Object element) => (element as VariableElement).hasImplicitType
               ? 'a $kind with an implicit type'
               : 'a $kind with an explicit type');
     }
@@ -699,22 +708,25 @@
       _writeMismatch(
           expected,
           actual,
-          (VariableElement element) =>
-              element.isConst ? 'a const $kind' : 'a non-const $kind');
+          (Object element) => (element as VariableElement).isConst
+              ? 'a const $kind'
+              : 'a non-const $kind');
     }
     if (expected.isFinal != actual.isFinal) {
       _writeMismatch(
           expected,
           actual,
-          (VariableElement element) =>
-              element.isFinal ? 'a final $kind' : 'a non-final $kind');
+          (Object element) => (element as VariableElement).isFinal
+              ? 'a final $kind'
+              : 'a non-final $kind');
     }
     if (expected.isStatic != actual.isStatic) {
       _writeMismatch(
           expected,
           actual,
-          (VariableElement element) =>
-              element.isStatic ? 'a static $kind' : 'an instance $kind');
+          (Object element) => (element as VariableElement).isStatic
+              ? 'a static $kind'
+              : 'an instance $kind');
     }
     //
     // Compare children.
diff --git a/pkg/analysis_server/lib/src/utilities/change_builder_core.dart b/pkg/analysis_server/lib/src/utilities/change_builder_core.dart
index cb103f8..199fa90 100644
--- a/pkg/analysis_server/lib/src/utilities/change_builder_core.dart
+++ b/pkg/analysis_server/lib/src/utilities/change_builder_core.dart
@@ -235,7 +235,7 @@
   }
 
   @override
-  void addSuggestions(LinkedEditSuggestionKind kind, List<String> values) {
+  void addSuggestions(LinkedEditSuggestionKind kind, Iterable<String> values) {
     values.forEach((value) => addSuggestion(kind, value));
   }
 
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index a2ae03b..6ab4706 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_test.dart
@@ -30,7 +30,7 @@
 
 @reflectiveTest
 class UpdateContentTest extends AbstractAnalysisTest {
-  Map<String, List<AnalysisError>> filesErrors = {};
+  Map<String, List<String>> filesErrors = {};
   int serverErrorCount = 0;
   int navigationCount = 0;
 
@@ -42,7 +42,8 @@
   void processNotification(Notification notification) {
     if (notification.event == ANALYSIS_ERRORS) {
       var decoded = new AnalysisErrorsParams.fromNotification(notification);
-      _format(AnalysisError e) => "${e.location.startLine}: ${e.message}";
+      String _format(AnalysisError e) =>
+          "${e.location.startLine}: ${e.message}";
       filesErrors[decoded.file] = decoded.errors.map(_format).toList();
     }
     if (notification.event == ANALYSIS_NAVIGATION) {
diff --git a/pkg/analysis_server/test/channel/web_socket_channel_test.dart b/pkg/analysis_server/test/channel/web_socket_channel_test.dart
index a9d42ed..77c47bc 100644
--- a/pkg/analysis_server/test/channel/web_socket_channel_test.dart
+++ b/pkg/analysis_server/test/channel/web_socket_channel_test.dart
@@ -35,9 +35,9 @@
   static WebSocketClientChannel client;
   static WebSocketServerChannel server;
 
-  static List requestsReceived;
-  static List responsesReceived;
-  static List notificationsReceived;
+  static List<Request> requestsReceived;
+  static List<Response> responsesReceived;
+  static List<Notification> notificationsReceived;
 
   static Future close() {
     var timeout = new Duration(seconds: 1);
@@ -144,9 +144,9 @@
     server = new WebSocketServerChannel(
         socket.twin, InstrumentationService.NULL_SERVICE);
 
-    requestsReceived = [];
-    responsesReceived = [];
-    notificationsReceived = [];
+    requestsReceived = <Request>[];
+    responsesReceived = <Response>[];
+    notificationsReceived = <Notification>[];
 
     // Allow multiple listeners on server side for testing.
     socket.twin.allowMultipleListeners();
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index cee64f0..4a78b6b 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -145,7 +145,8 @@
     manager.processPlugins(plugins);
   }
 
-  UriResolver provideEmbeddedUriResolver(Folder folder) => embeddedUriResolver;
+  EmbedderUriResolver provideEmbeddedUriResolver(Folder folder) =>
+      embeddedUriResolver;
 
   UriResolver providePackageResolver(Folder folder) => packageResolver;
 
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index da13829..ad5319e 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -70,7 +70,7 @@
             new AnalysisGetReachableSourcesParams(fileA).toRequest('0');
         var response = handler.handleRequest(request);
 
-        var json = response.toJson()[Response.RESULT];
+        Map json = response.toJson()[Response.RESULT];
 
         // Sanity checks.
         expect(json['sources'], hasLength(6));
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 3435be7..edce0d5 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -512,6 +512,20 @@
       assertNoResult('HtmlElement');
     });
   }
+
+  test_import_uri_with_trailing() {
+    addFile('/project/bin/testA.dart', 'library libA;');
+    addTestFile('''
+      import '/project/bin/t^.dart';
+      main() {}''');
+    return getSuggestions().then((_) {
+      expect(replacementOffset, equals(completionOffset - 14));
+      expect(replacementLength, equals(5 + 14));
+      assertHasResult(
+          CompletionSuggestionKind.IMPORT, '/project/bin/testA.dart');
+      assertNoResult('test');
+    });
+  }
 }
 
 class MockRelevancySorter implements DartContributionSorter {
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index d6de07f..d2288ae 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -73,7 +73,7 @@
 
       int fileCount = 1 /* test.dart */;
 
-      var json = response.toJson()[Response.RESULT];
+      Map json = response.toJson()[Response.RESULT];
       expect(json['contexts'], hasLength(1));
       var context = json['contexts'][0];
       expect(context['name'], '/project');
@@ -86,7 +86,7 @@
     test('getDiagnostics - (no root)', () async {
       var request = new DiagnosticGetDiagnosticsParams().toRequest('0');
       var response = handler.handleRequest(request);
-      var json = response.toJson()[Response.RESULT];
+      Map json = response.toJson()[Response.RESULT];
       expect(json['contexts'], hasLength(0));
     });
   });
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index 54a4e11..7c9223a 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -653,11 +653,10 @@
 ''');
   }
 
-  Future<Response> _computeChange() {
-    return _prepareOptions().then((_) {
-      // send request with the options
-      return _sendExtractRequest();
-    });
+  Future<Response> _computeChange() async {
+    await _prepareOptions();
+    // send request with the options
+    return _sendExtractRequest();
   }
 
   Future<ExtractMethodFeedback> _computeInitialFeedback() {
@@ -1867,12 +1866,10 @@
   }
 
   Future<EditGetRefactoringResult> getRefactoringResult(
-      Future<Response> requestSender()) {
-    return waitForTasksFinished().then((_) {
-      return requestSender().then((Response response) {
-        return new EditGetRefactoringResult.fromResponse(response);
-      });
-    });
+      Future<Response> requestSender()) async {
+    await waitForTasksFinished();
+    Response response = await requestSender();
+    return new EditGetRefactoringResult.fromResponse(response);
   }
 
   Future<Response> sendRequest(
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index 5361816..9b58405 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -404,7 +404,7 @@
    * the [Completer] objects which should be completed when acknowledgement is
    * received.
    */
-  final HashMap<String, Completer> _pendingCommands = <String, Completer>{};
+  final Map<String, Completer> _pendingCommands = <String, Completer>{};
 
   /**
    * Number which should be used to compute the 'id' to send in the next command
@@ -844,7 +844,8 @@
   @override
   Description describeMismatch(
       item, Description mismatchDescription, Map matchState, bool verbose) {
-    List<MismatchDescriber> mismatches = matchState['mismatches'];
+    List<MismatchDescriber> mismatches =
+        matchState['mismatches'] as List<MismatchDescriber>;
     if (mismatches != null) {
       for (int i = 0; i < mismatches.length; i++) {
         MismatchDescriber mismatch = mismatches[i];
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index dc028c4..335a9b3 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -211,8 +211,8 @@
   InternalAnalysisContext _analysisContext;
 
   MockSdk() {
-    LIBRARIES.forEach((_MockSdkLibrary library) {
-      provider.newFile(library.path, library.content);
+    LIBRARIES.forEach((SdkLibrary library) {
+      provider.newFile(library.path, (library as _MockSdkLibrary).content);
     });
   }
 
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index a22efee..4a667bb 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -173,7 +173,8 @@
         return;
       }
       String enumName = MirrorSystem.getName(symbol);
-      EngineEnum engineValue = engineClass.getField(symbol).reflectee;
+      EngineEnum engineValue =
+          engineClass.getField(symbol).reflectee as EngineEnum;
       expect(engineValue, new isInstanceOf<EngineEnum>());
       if (exceptions.containsKey(engineValue)) {
         ApiEnum expectedResult = exceptions[engineValue];
diff --git a/pkg/analysis_server/test/protocol_test.dart b/pkg/analysis_server/test/protocol_test.dart
index 93dde63..6428c62 100644
--- a/pkg/analysis_server/test/protocol_test.dart
+++ b/pkg/analysis_server/test/protocol_test.dart
@@ -266,7 +266,8 @@
     Response original = new Response('myId', result: {'foo': 'bar'});
     Response response = new Response.fromJson(original.toJson());
     expect(response.id, equals('myId'));
-    Map<String, Object> result = response.toJson()['result'];
+    Map<String, Object> result =
+        response.toJson()['result'] as Map<String, Object>;
     expect(result.length, equals(1));
     expect(result['foo'], equals('bar'));
   }
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 549c8f1..9589874 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -519,9 +519,13 @@
     return cs;
   }
 
-  Future performAnalysis(int times, Completer completer) {
-    if (completer.isCompleted) return completer.future;
-    if (times == 0 || context == null) return new Future.value();
+  Future/*<E>*/ performAnalysis/*<E>*/(int times, Completer/*<E>*/ completer) {
+    if (completer.isCompleted) {
+      return completer.future;
+    }
+    if (times == 0 || context == null) {
+      return new Future.value();
+    }
     context.performAnalysisTask();
     // We use a delayed future to allow microtask events to finish. The
     // Future.value or Future() constructors use scheduleMicrotask themselves and
diff --git a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
index f120744..8bd4e6b 100644
--- a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
@@ -258,6 +258,18 @@
         csKind: CompletionSuggestionKind.IMPORT);
   }
 
+  test_import_package2_with_trailing() async {
+    addPackageSource('foo', 'foo.dart', 'library foo;');
+    addPackageSource('foo', 'baz/too.dart', 'library too;');
+    addPackageSource('bar', 'bar.dart', 'library bar;');
+    addTestSource('import "package:foo/baz/^.dart" import');
+    await computeSuggestions();
+    assertSuggest('package:foo/baz/too.dart',
+        csKind: CompletionSuggestionKind.IMPORT);
+    expect(replacementOffset, completionOffset - 16);
+    expect(replacementLength, 5 + 16);
+  }
+
   test_import_package2_raw() async {
     addPackageSource('foo', 'foo.dart', 'library foo;');
     addPackageSource('foo', 'baz/too.dart', 'library too;');
diff --git a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
index d74328f..76b7409 100644
--- a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
+++ b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
@@ -28,7 +28,7 @@
   var res = sortedNodes as String;
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     var expr = findNodeAtString('as String', (node) => node is AsExpression);
     expect(getVariableNameSuggestionsForExpression(null, expr, excluded),
         unorderedEquals(['sortedNodes', 'nodes']));
@@ -41,7 +41,7 @@
   TreeNode node = null;
 }
 ''');
-    Set excluded = new Set.from([]);
+    Set<String> excluded = new Set<String>.from([]);
     DartType expectedType = (findElement('node') as LocalVariableElement).type;
     Expression assignedExpression =
         findNodeAtString('null;', (node) => node is NullLiteral);
@@ -115,7 +115,7 @@
   new NoSuchClass.named();
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     expect(
         getVariableNameSuggestionsForExpression(
             null, findNodeAtString('new NoSuchClass()'), excluded),
@@ -141,7 +141,7 @@
   foo(a: 111, c: 333, b: 222);
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     {
       var expr = findNodeAtString('111');
       expect(getVariableNameSuggestionsForExpression(null, expr, excluded),
@@ -166,7 +166,7 @@
   foo(111, 222, 333);
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     {
       var expr = findNodeAtString('111');
       expect(getVariableNameSuggestionsForExpression(null, expr, excluded),
@@ -191,7 +191,7 @@
   foo(111, 222);
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     {
       var expr = findNodeAtString('111');
       expect(getVariableNameSuggestionsForExpression(null, expr, excluded),
@@ -210,7 +210,7 @@
   var res = p.getSortedNodes();
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     var expr = findNodeAtString('p.get', (node) => node is MethodInvocation);
     expect(getVariableNameSuggestionsForExpression(null, expr, excluded),
         unorderedEquals(['sortedNodes', 'nodes']));
@@ -222,7 +222,7 @@
   var res = p.sortedNodes();
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     var expr = findNodeAtString('p.sorted', (node) => node is MethodInvocation);
     expect(getVariableNameSuggestionsForExpression(null, expr, excluded),
         unorderedEquals(['sortedNodes', 'nodes']));
@@ -234,7 +234,7 @@
   var res = p.get();
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     var expr = findNodeAtString('p.get', (node) => node is MethodInvocation);
     expect(getVariableNameSuggestionsForExpression(null, expr, excluded),
         unorderedEquals([]));
@@ -246,7 +246,7 @@
   var res = p.sortedNodes;
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     expect(
         getVariableNameSuggestionsForExpression(
             null,
@@ -262,7 +262,7 @@
   p._computeSuffix();
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     expect(
         getVariableNameSuggestionsForExpression(
             null,
@@ -283,7 +283,7 @@
   var res = p.q.sortedNodes;
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     PropertyAccess expression =
         findNodeAtString('p.q.sorted', (node) => node is PropertyAccess);
     expect(getVariableNameSuggestionsForExpression(null, expression, excluded),
@@ -297,7 +297,7 @@
   var res = sortedNodes;
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     var expr = findNodeAtString('sortedNodes;');
     expect(getVariableNameSuggestionsForExpression(null, expr, excluded),
         unorderedEquals(['sortedNodes', 'nodes']));
@@ -310,7 +310,7 @@
   var res = getSortedNodes();
 }
 ''');
-    var excluded = new Set.from([]);
+    var excluded = new Set<String>.from([]);
     expect(
         getVariableNameSuggestionsForExpression(
             null,
@@ -322,14 +322,14 @@
 
   void test_forText() {
     {
-      Set excluded = new Set.from([]);
+      Set<String> excluded = new Set<String>.from([]);
       List<String> suggestions =
           getVariableNameSuggestionsForText('Goodbye, cruel world!', excluded);
       expect(suggestions,
           unorderedEquals(['goodbyeCruelWorld', 'cruelWorld', 'world']));
     }
     {
-      Set excluded = new Set.from(['world']);
+      Set<String> excluded = new Set<String>.from(['world']);
       List<String> suggestions =
           getVariableNameSuggestionsForText('Goodbye, cruel world!', excluded);
       expect(suggestions,
diff --git a/pkg/analysis_server/test/services/correction/sort_members_test.dart b/pkg/analysis_server/test/services/correction/sort_members_test.dart
index bcc9c0c..d3f6950 100644
--- a/pkg/analysis_server/test/services/correction/sort_members_test.dart
+++ b/pkg/analysis_server/test/services/correction/sort_members_test.dart
@@ -371,34 +371,119 @@
 ''');
   }
 
-  void test_directives_comments() {
+  void test_directives_docComment_hasLibrary_lines() {
     _parseTestUnit(r'''
-// header
-library lib;
+/// Library documentation comment A.
+/// Library documentation comment B.
+library foo.bar;
 
-import 'c.dart';// c
-import 'a.dart';// aa
-import 'b.dart';// bbb
-
-/** doc */
-main() {
-}
+/// bbb1
+/// bbb2
+/// bbb3
+import 'b.dart';
+/// aaa1
+/// aaa2
+import 'a.dart';
 ''');
     // validate change
     _assertSort(r'''
-// header
-library lib;
+/// Library documentation comment A.
+/// Library documentation comment B.
+library foo.bar;
 
+/// aaa1
+/// aaa2
+import 'a.dart';
+/// bbb1
+/// bbb2
+/// bbb3
+import 'b.dart';
+''');
+  }
+
+  void test_directives_docComment_hasLibrary_stars() {
+    _parseTestUnit(r'''
+/**
+ * Library documentation comment A.
+ * Library documentation comment B.
+ */
+library foo.bar;
+
+/**
+ * bbb
+ */
+import 'b.dart';
+/**
+ * aaa
+ * aaa
+ */
+import 'a.dart';
+''');
+    // validate change
+    _assertSort(r'''
+/**
+ * Library documentation comment A.
+ * Library documentation comment B.
+ */
+library foo.bar;
+
+/**
+ * aaa
+ * aaa
+ */
+import 'a.dart';
+/**
+ * bbb
+ */
+import 'b.dart';
+''');
+  }
+
+  void test_directives_docComment_noLibrary_lines() {
+    _parseTestUnit(r'''
+/// Library documentation comment A
+/// Library documentation comment B
+import 'b.dart';
+/// aaa1
+/// aaa2
+import 'a.dart';
+''');
+    // validate change
+    _assertSort(r'''
+/// aaa1
+/// aaa2
+/// Library documentation comment A
+/// Library documentation comment B
 import 'a.dart';
 import 'b.dart';
-import 'c.dart';
-// c
-// aa
-// bbb
+''');
+  }
 
-/** doc */
-main() {
-}
+  void test_directives_docComment_noLibrary_stars() {
+    _parseTestUnit(r'''
+/**
+ * Library documentation comment A.
+ * Library documentation comment B.
+ */
+import 'b.dart';
+/**
+ * aaa
+ * aaa
+ */
+import 'a.dart';
+''');
+    // validate change
+    _assertSort(r'''
+/**
+ * aaa
+ * aaa
+ */
+/**
+ * Library documentation comment A.
+ * Library documentation comment B.
+ */
+import 'a.dart';
+import 'b.dart';
 ''');
   }
 
diff --git a/pkg/analysis_server/test/services/correction/strings_test.dart b/pkg/analysis_server/test/services/correction/strings_test.dart
index 3fb37fb..a5b4779 100644
--- a/pkg/analysis_server/test/services/correction/strings_test.dart
+++ b/pkg/analysis_server/test/services/correction/strings_test.dart
@@ -33,6 +33,27 @@
     expect(compareStrings('b', 'a'), 1);
   }
 
+  void test_computeSimpleDiff() {
+    assertDiff(String oldStr, String newStr) {
+      SimpleDiff diff = computeSimpleDiff(oldStr, newStr);
+      expect(diff.offset, isNonNegative);
+      expect(diff.length, isNonNegative);
+      String applied = oldStr.substring(0, diff.offset) +
+          diff.replacement +
+          oldStr.substring(diff.offset + diff.length);
+      expect(applied, newStr);
+    }
+    assertDiff('', '');
+    assertDiff('', 'a');
+    assertDiff('abc', '');
+    assertDiff('abcd', 'acd');
+    assertDiff('a', 'b');
+    assertDiff('12345xyz', '12345abcxyz');
+    assertDiff('12345xyz', '12345xyzabc');
+    assertDiff('abbc', 'abbbc');
+    assertDiff('abbbbc', 'abbbbbbc');
+  }
+
   void test_countMatches() {
     expect(countMatches(null, null), 0);
     expect(countMatches('abc', null), 0);
@@ -42,15 +63,6 @@
     expect(countMatches('aaabaa', 'aa'), 2);
   }
 
-  void test_findCommonOverlap() {
-    expect(findCommonOverlap('', 'abcd'), 0);
-    expect(findCommonOverlap('abc', 'abcd'), 3);
-    expect(findCommonOverlap('123456', 'abcd'), 0);
-    expect(findCommonOverlap('123456xxx', 'xxxabcd'), 3);
-    expect(findCommonOverlap('123456', '56'), 2);
-    expect(findCommonOverlap('56', '56789'), 2);
-  }
-
   void test_findCommonPrefix() {
     expect(findCommonPrefix('abc', 'xyz'), 0);
     expect(findCommonPrefix('1234abcdef', '1234xyz'), 4);
diff --git a/pkg/analysis_server/test/services/index/index_test.dart b/pkg/analysis_server/test/services/index/index_test.dart
index 1787407..a99d34a 100644
--- a/pkg/analysis_server/test/services/index/index_test.dart
+++ b/pkg/analysis_server/test/services/index/index_test.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
 
 import '../../abstract_single_unit.dart';
@@ -257,6 +258,14 @@
     index.indexDeclarations(testUnit);
   }
 
+  test_indexUnit_nullLibraryElement() async {
+    resolveTestUnit('');
+    CompilationUnitElement unitElement = new _CompilationUnitElementMock();
+    expect(unitElement.library, isNull);
+    testUnit.element = unitElement;
+    index.indexUnit(testUnit);
+  }
+
   test_indexUnit_nullUnit() async {
     index.indexUnit(null);
   }
@@ -341,3 +350,6 @@
     return source;
   }
 }
+
+class _CompilationUnitElementMock extends TypedMock
+    implements CompilationUnitElement {}
diff --git a/pkg/analysis_server/test/services/linter/linter_test.dart b/pkg/analysis_server/test/services/linter/linter_test.dart
index 00a9fd6..1017bd6 100644
--- a/pkg/analysis_server/test/services/linter/linter_test.dart
+++ b/pkg/analysis_server/test/services/linter/linter_test.dart
@@ -74,7 +74,7 @@
         [UNDEFINED_LINT_WARNING]);
   }
 
-  validate(String source, List<AnalysisOptionsErrorCode> expected) {
+  validate(String source, List<ErrorCode> expected) {
     var options = optionsProvider.getOptionsFromString(source);
     validator.validate(reporter, options);
     expect(errors.map((AnalysisError e) => e.errorCode),
diff --git a/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart b/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
index 9aa321b..98f1165 100644
--- a/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
+++ b/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
@@ -45,7 +45,7 @@
       packages.forEach((String name, String path) {
         resProvider.newFolder(path);
       });
-      List<String> inputFiles = result['input_files'];
+      List<String> inputFiles = result['input_files'] as List<String>;
       for (String path in inputFiles) {
         resProvider.newFile(path, '');
       }
@@ -282,7 +282,7 @@
 
 _assertError(PackageMapInfo info, Map expected) {
   expect(info.packageMap, isNull);
-  List<String> expectedFiles = expected['input_files'];
+  List<String> expectedFiles = expected['input_files'] as List<String>;
   expect(info.dependencies, hasLength(expectedFiles.length));
   for (String path in expectedFiles) {
     expect(info.dependencies, contains(path));
@@ -290,14 +290,15 @@
 }
 
 _assertInfo(PackageMapInfo info, Map expected) {
-  Map<String, String> expectedPackages = expected['packages'];
+  Map<String, String> expectedPackages =
+      expected['packages'] as Map<String, String>;
   expect(info.packageMap, hasLength(expectedPackages.length));
   for (String key in expectedPackages.keys) {
     List<Folder> packageList = info.packageMap[key];
     expect(packageList, hasLength(1));
     expect(packageList[0].path, expectedPackages[key]);
   }
-  List<String> expectedFiles = expected['input_files'];
+  List<String> expectedFiles = expected['input_files'] as List<String>;
   expect(info.dependencies, hasLength(expectedFiles.length));
   for (String path in expectedFiles) {
     expect(info.dependencies, contains(path));
diff --git a/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart b/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart
index 4eb855f..c36c700 100644
--- a/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart
+++ b/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart
@@ -74,12 +74,12 @@
     ChangeBuilderImpl builder = new ChangeBuilderImpl();
     int offset = 10;
     String text = 'content';
-    builder.addFileEdit(source, 0, (FileEditBuilderImpl builder) {
-      builder.addInsertion(10, (EditBuilderImpl builder) {
+    builder.addFileEdit(source, 0, (FileEditBuilder builder) {
+      builder.addInsertion(10, (EditBuilder builder) {
         builder.addLinkedEdit('a', (LinkedEditBuilder builder) {
           builder.write(text);
         });
-        SourceEdit sourceEdit = builder.sourceEdit;
+        SourceEdit sourceEdit = (builder as EditBuilderImpl).sourceEdit;
         expect(sourceEdit.replacement, text);
       });
     });
@@ -97,9 +97,10 @@
 
   void test_createLinkedEditBuilder() {
     ChangeBuilderImpl builder = new ChangeBuilderImpl();
-    builder.addFileEdit(source, 0, (FileEditBuilderImpl builder) {
-      builder.addInsertion(10, (EditBuilderImpl builder) {
-        LinkedEditBuilderImpl linkBuilder = builder.createLinkedEditBuilder();
+    builder.addFileEdit(source, 0, (FileEditBuilder builder) {
+      builder.addInsertion(10, (EditBuilder builder) {
+        LinkedEditBuilderImpl linkBuilder =
+            (builder as EditBuilderImpl).createLinkedEditBuilder();
         expect(linkBuilder, new isInstanceOf<LinkedEditBuilder>());
       });
     });
@@ -110,8 +111,8 @@
     int timeStamp = 93;
     int offset = 10;
     String text = 'write';
-    builder.addFileEdit(source, timeStamp, (FileEditBuilderImpl builder) {
-      builder.addInsertion(offset, (EditBuilderImpl builder) {
+    builder.addFileEdit(source, timeStamp, (FileEditBuilder builder) {
+      builder.addInsertion(offset, (EditBuilder builder) {
         builder.write(text);
       });
     });
@@ -140,8 +141,8 @@
     int timeStamp = 39;
     int offset = 52;
     int length = 12;
-    builder.addFileEdit(source, timeStamp, (FileEditBuilderImpl builder) {
-      builder.addReplacement(offset, length, (EditBuilderImpl builder) {
+    builder.addFileEdit(source, timeStamp, (FileEditBuilder builder) {
+      builder.addReplacement(offset, length, (EditBuilder builder) {
         builder.writeln();
       });
     });
@@ -171,8 +172,8 @@
     int offset = 52;
     int length = 12;
     String text = 'writeln';
-    builder.addFileEdit(source, timeStamp, (FileEditBuilderImpl builder) {
-      builder.addReplacement(offset, length, (EditBuilderImpl builder) {
+    builder.addFileEdit(source, timeStamp, (FileEditBuilder builder) {
+      builder.addReplacement(offset, length, (EditBuilder builder) {
         builder.writeln(text);
       });
     });
@@ -204,8 +205,8 @@
 
   void test_addInsertion() {
     ChangeBuilderImpl builder = new ChangeBuilderImpl();
-    builder.addFileEdit(source, 0, (FileEditBuilderImpl builder) {
-      builder.addInsertion(10, (EditBuilderImpl builder) {
+    builder.addFileEdit(source, 0, (FileEditBuilder builder) {
+      builder.addInsertion(10, (EditBuilder builder) {
         expect(builder, isNotNull);
       });
     });
@@ -214,7 +215,7 @@
   void test_addLinkedPosition() {
     ChangeBuilderImpl changeBuilder = new ChangeBuilderImpl();
     String groupName = 'a';
-    changeBuilder.addFileEdit(source, 0, (FileEditBuilderImpl builder) {
+    changeBuilder.addFileEdit(source, 0, (FileEditBuilder builder) {
       builder.addLinkedPosition(3, 6, groupName);
     });
 
@@ -229,8 +230,8 @@
 
   void test_addReplacement() {
     ChangeBuilderImpl builder = new ChangeBuilderImpl();
-    builder.addFileEdit(source, 0, (FileEditBuilderImpl builder) {
-      builder.addReplacement(4, 5, (EditBuilderImpl builder) {
+    builder.addFileEdit(source, 0, (FileEditBuilder builder) {
+      builder.addReplacement(4, 5, (EditBuilder builder) {
         expect(builder, isNotNull);
       });
     });
@@ -238,10 +239,11 @@
 
   void test_createEditBuilder() {
     ChangeBuilderImpl builder = new ChangeBuilderImpl();
-    builder.addFileEdit(source, 0, (FileEditBuilderImpl builder) {
+    builder.addFileEdit(source, 0, (FileEditBuilder builder) {
       int offset = 4;
       int length = 5;
-      EditBuilderImpl editBuilder = builder.createEditBuilder(offset, length);
+      EditBuilderImpl editBuilder =
+          (builder as FileEditBuilderImpl).createEditBuilder(offset, length);
       expect(editBuilder, new isInstanceOf<EditBuilder>());
       SourceEdit sourceEdit = editBuilder.sourceEdit;
       expect(sourceEdit.length, length);
@@ -258,9 +260,9 @@
   void test_addSuggestion() {
     String groupName = 'a';
     ChangeBuilderImpl builder = new ChangeBuilderImpl();
-    builder.addFileEdit(source, 0, (FileEditBuilderImpl builder) {
-      builder.addInsertion(10, (EditBuilderImpl builder) {
-        builder.addLinkedEdit(groupName, (LinkedEditBuilderImpl builder) {
+    builder.addFileEdit(source, 0, (FileEditBuilder builder) {
+      builder.addInsertion(10, (EditBuilder builder) {
+        builder.addLinkedEdit(groupName, (LinkedEditBuilder builder) {
           builder.addSuggestion(LinkedEditSuggestionKind.TYPE, 'A');
         });
       });
@@ -273,9 +275,9 @@
   void test_addSuggestions() {
     String groupName = 'a';
     ChangeBuilderImpl builder = new ChangeBuilderImpl();
-    builder.addFileEdit(source, 0, (FileEditBuilderImpl builder) {
-      builder.addInsertion(10, (EditBuilderImpl builder) {
-        builder.addLinkedEdit(groupName, (LinkedEditBuilderImpl builder) {
+    builder.addFileEdit(source, 0, (FileEditBuilder builder) {
+      builder.addInsertion(10, (EditBuilder builder) {
+        builder.addLinkedEdit(groupName, (LinkedEditBuilder builder) {
           builder.addSuggestions(LinkedEditSuggestionKind.TYPE, ['A', 'B']);
         });
       });
diff --git a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
index e8fdbee..61f8328 100644
--- a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
+++ b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
@@ -5,9 +5,11 @@
 library analysis_server.test.src.utilities.change_builder_dart_test;
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/edit/utilities/change_builder_core.dart';
 import 'package:analysis_server/src/provisional/edit/utilities/change_builder_dart.dart';
 import 'package:analysis_server/src/utilities/change_builder_dart.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
@@ -58,9 +60,9 @@
     ClassDeclaration declaration = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(0, (DartEditBuilder builder) {
-        builder
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder)
             .writeClassDeclaration('C', interfaces: [declaration.element.type]);
       });
     });
@@ -74,9 +76,10 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(0, (DartEditBuilder builder) {
-        builder.writeClassDeclaration('C', isAbstract: true);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeClassDeclaration('C', isAbstract: true);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -88,9 +91,10 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(0, (DartEditBuilder builder) {
-        builder.writeClassDeclaration('C', memberWriter: () {
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeClassDeclaration('C',
+            memberWriter: () {
           builder.write('/**/');
         });
       });
@@ -105,9 +109,10 @@
     ClassDeclaration classA = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(0, (DartEditBuilder builder) {
-        builder.writeClassDeclaration('C', mixins: [classA.element.type]);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeClassDeclaration('C', mixins: [classA.element.type]);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -122,9 +127,9 @@
     ClassDeclaration classB = unit.declarations[1];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(0, (DartEditBuilder builder) {
-        builder.writeClassDeclaration('C',
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeClassDeclaration('C',
             mixins: [classB.element.type], superclass: classA.element.type);
       });
     });
@@ -138,9 +143,10 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(0, (DartEditBuilder builder) {
-        builder.writeClassDeclaration('C', nameGroupName: 'name');
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeClassDeclaration('C', nameGroupName: 'name');
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -160,10 +166,10 @@
     ClassDeclaration declaration = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(0, (DartEditBuilder builder) {
-        builder.writeClassDeclaration('C',
-            superclass: declaration.element.type);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeClassDeclaration('C', superclass: declaration.element.type);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -176,9 +182,10 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeFieldDeclaration('f', initializerWriter: () {
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeFieldDeclaration('f',
+            initializerWriter: () {
           builder.write('e');
         });
       });
@@ -193,9 +200,9 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeFieldDeclaration('f', isConst: true);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeFieldDeclaration('f', isConst: true);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -208,9 +215,10 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeFieldDeclaration('f', isConst: true, isFinal: true);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeFieldDeclaration('f', isConst: true, isFinal: true);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -223,9 +231,9 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeFieldDeclaration('f', isFinal: true);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeFieldDeclaration('f', isFinal: true);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -238,9 +246,9 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeFieldDeclaration('f', isStatic: true);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeFieldDeclaration('f', isStatic: true);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -253,9 +261,10 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeFieldDeclaration('f', nameGroupName: 'name');
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeFieldDeclaration('f', nameGroupName: 'name');
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -278,9 +287,9 @@
     ClassDeclaration declaration = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeFieldDeclaration('f',
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeFieldDeclaration('f',
             type: declaration.element.type, typeGroupName: 'type');
       });
     });
@@ -303,9 +312,10 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilderImpl builder) {
-        builder.writeGetterDeclaration('g', bodyWriter: () {
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeGetterDeclaration('g',
+            bodyWriter: () {
           builder.write('{}');
         });
       });
@@ -320,9 +330,10 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilderImpl builder) {
-        builder.writeGetterDeclaration('g', isStatic: true);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeGetterDeclaration('g', isStatic: true);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -335,9 +346,10 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilderImpl builder) {
-        builder.writeGetterDeclaration('g', nameGroupName: 'name');
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeGetterDeclaration('g', nameGroupName: 'name');
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -360,9 +372,9 @@
     ClassDeclaration classA = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilderImpl builder) {
-        builder.writeGetterDeclaration('g',
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeGetterDeclaration('g',
             returnType: classA.element.type, returnTypeGroupName: 'returnType');
       });
     });
@@ -391,9 +403,10 @@
     ClassDeclaration declaration = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeOverrideOfInheritedMember(declaration.element.methods[0]);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeOverrideOfInheritedMember(declaration.element.methods[0]);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -411,13 +424,13 @@
     CompilationUnit unit = resolveLibraryUnit(source);
     FunctionDeclaration f = unit.declarations[0];
     FormalParameterList parameters = f.functionExpression.parameters;
-    Iterable elements = parameters.parameters
+    Iterable<ParameterElement> elements = parameters.parameters
         .map((FormalParameter parameter) => parameter.element);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeParameters(elements);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeParameters(elements);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -430,13 +443,13 @@
     CompilationUnit unit = resolveLibraryUnit(source);
     FunctionDeclaration f = unit.declarations[0];
     FormalParameterList parameters = f.functionExpression.parameters;
-    Iterable elements = parameters.parameters
+    Iterable<ParameterElement> elements = parameters.parameters
         .map((FormalParameter parameter) => parameter.element);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeParameters(elements);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeParameters(elements);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -449,13 +462,13 @@
     CompilationUnit unit = resolveLibraryUnit(source);
     FunctionDeclaration f = unit.declarations[0];
     FormalParameterList parameters = f.functionExpression.parameters;
-    Iterable elements = parameters.parameters
+    Iterable<ParameterElement> elements = parameters.parameters
         .map((FormalParameter parameter) => parameter.element);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeParameters(elements);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeParameters(elements);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -475,9 +488,10 @@
     MethodInvocation invocation = statement.expression;
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeParametersMatchingArguments(invocation.argumentList);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeParametersMatchingArguments(invocation.argumentList);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -498,9 +512,10 @@
     MethodInvocation invocation = statement.expression;
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeParametersMatchingArguments(invocation.argumentList);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeParametersMatchingArguments(invocation.argumentList);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -514,9 +529,10 @@
     ClassDeclaration classA = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeParameterSource(classA.element.type, 'a');
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeParameterSource(classA.element.type, 'a');
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -529,9 +545,10 @@
     CompilationUnit unit = resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeType(unit.element.context.typeProvider.dynamicType);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeType(unit.element.context.typeProvider.dynamicType);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -546,9 +563,9 @@
     ClassDeclaration classB = unit.declarations[1];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
             .writeType(classB.element.type.instantiate([classA.element.type]));
       });
     });
@@ -563,9 +580,10 @@
     ClassDeclaration classC = unit.declarations[2];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeType(classC.element.type, groupName: 'type');
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeType(classC.element.type, groupName: 'type');
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -585,9 +603,9 @@
     ClassDeclaration classC = unit.declarations[2];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeType(classC.element.type,
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeType(classC.element.type,
             addSupertypeProposals: true, groupName: 'type');
       });
     });
@@ -617,9 +635,9 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeType(null);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeType(null);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -632,9 +650,10 @@
     CompilationUnit unit = resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeType(unit.element.context.typeProvider.dynamicType,
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeType(
+            unit.element.context.typeProvider.dynamicType,
             required: true);
       });
     });
@@ -649,9 +668,10 @@
     ClassDeclaration classA = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeType(classA.element.type, required: true);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeType(classA.element.type, required: true);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -664,9 +684,9 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeType(null, required: true);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeType(null, required: true);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -680,9 +700,9 @@
     ClassDeclaration classA = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
-        builder.writeType(classA.element.type);
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeType(classA.element.type);
       });
     });
     SourceEdit edit = getEdit(builder);
@@ -695,8 +715,8 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
         (builder as DartEditBuilderImpl).writeTypes([]);
       });
     });
@@ -712,8 +732,8 @@
     ClassDeclaration classB = unit.declarations[1];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
         (builder as DartEditBuilderImpl)
             .writeTypes([classA.element.type, classB.element.type]);
       });
@@ -728,8 +748,8 @@
     resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
         (builder as DartEditBuilderImpl).writeTypes(null);
       });
     });
@@ -745,8 +765,8 @@
     ClassDeclaration classB = unit.declarations[1];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, 1, (DartFileEditBuilderImpl builder) {
-      builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
+    builder.addFileEdit(source, 1, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 1, (EditBuilder builder) {
         (builder as DartEditBuilderImpl).writeTypes(
             [classA.element.type, classB.element.type],
             prefix: 'implements ');
@@ -764,11 +784,11 @@
     resolveLibraryUnit(source);
     int timeStamp = 65;
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
-    builder.addFileEdit(source, timeStamp, (DartFileEditBuilderImpl builder) {
+    builder.addFileEdit(source, timeStamp, (FileEditBuilder builder) {
       int offset = 4;
       int length = 5;
-      DartEditBuilderImpl editBuilder =
-          builder.createEditBuilder(offset, length);
+      DartEditBuilderImpl editBuilder = (builder as DartFileEditBuilderImpl)
+          .createEditBuilder(offset, length);
       expect(editBuilder, new isInstanceOf<DartEditBuilder>());
       SourceEdit sourceEdit = editBuilder.sourceEdit;
       expect(sourceEdit.length, length);
diff --git a/pkg/analysis_server/test/timing/timing_framework.dart b/pkg/analysis_server/test/timing/timing_framework.dart
index cdf24fe..8861f94 100644
--- a/pkg/analysis_server/test/timing/timing_framework.dart
+++ b/pkg/analysis_server/test/timing/timing_framework.dart
@@ -224,17 +224,13 @@
    * number of milliseconds required to perform the operation the specified
    * number of times.
    */
-  Future<TimingResult> run() {
+  Future<TimingResult> run() async {
     List<int> times = new List<int>();
-    return oneTimeSetUp().then((_) {
-      return _repeat(warmupCount, null).then((_) {
-        return _repeat(timingCount, times).then((_) {
-          return oneTimeTearDown().then((_) {
-            return new Future.value(new TimingResult(times));
-          });
-        });
-      });
-    });
+    await oneTimeSetUp();
+    await _repeat(warmupCount, null);
+    await _repeat(timingCount, times);
+    await oneTimeTearDown();
+    return new Future<TimingResult>.value(new TimingResult(times));
   }
 
   /**
diff --git a/pkg/analysis_server/tool/spec/api.dart b/pkg/analysis_server/tool/spec/api.dart
index b5443aa..d542551 100644
--- a/pkg/analysis_server/tool/spec/api.dart
+++ b/pkg/analysis_server/tool/spec/api.dart
@@ -52,7 +52,7 @@
   /**
    * Dispatch the given [type] to the visitor.
    */
-  T visitTypeDecl(TypeDecl type) => type.accept(this);
+  T visitTypeDecl(TypeDecl type) => type.accept(this) as T;
   T visitTypeEnum(TypeEnum typeEnum);
   T visitTypeList(TypeList typeList);
   T visitTypeMap(TypeMap typeMap);
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index fc389a4..02855a6 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -79,9 +79,9 @@
   final Map<String, ImpliedType> impliedTypes;
 
   CodegenProtocolVisitor(Api api)
-      : super(api),
-        toHtmlVisitor = new ToHtmlVisitor(api),
-        impliedTypes = computeImpliedTypes(api) {
+      : toHtmlVisitor = new ToHtmlVisitor(api),
+        impliedTypes = computeImpliedTypes(api),
+        super(api) {
     codeGeneratorSettings.commentLineLength = 79;
     codeGeneratorSettings.languageName = 'dart';
   }
diff --git a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
index 3b5fde0..5819e20 100644
--- a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
@@ -45,8 +45,8 @@
   List<String> notificationSwitchContents = <String>[];
 
   CodegenInttestMethodsVisitor(Api api)
-      : super(api),
-        toHtmlVisitor = new ToHtmlVisitor(api) {
+      : toHtmlVisitor = new ToHtmlVisitor(api),
+        super(api) {
     codeGeneratorSettings.commentLineLength = 79;
     codeGeneratorSettings.languageName = 'dart';
   }
diff --git a/pkg/analysis_server/tool/spec/codegen_java.dart b/pkg/analysis_server/tool/spec/codegen_java.dart
index 3b7a4d2..9c4dd83 100644
--- a/pkg/analysis_server/tool/spec/codegen_java.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java.dart
@@ -68,8 +68,8 @@
   final ToHtmlVisitor toHtmlVisitor;
 
   CodegenJavaVisitor(Api api)
-      : super(api),
-        toHtmlVisitor = new ToHtmlVisitor(api);
+      : toHtmlVisitor = new ToHtmlVisitor(api),
+        super(api);
 
   /**
    * Create a constructor, using [callback] to create its contents.
@@ -262,7 +262,7 @@
   }
 
   @override
-  TypeReference resolveTypeReferenceChain(TypeReference type) {
+  TypeDecl resolveTypeReferenceChain(TypeDecl type) {
     TypeDecl typeDecl = super.resolveTypeReferenceChain(type);
     if (typeDecl is TypeEnum) {
       return new TypeReference('String', null);
diff --git a/pkg/analysis_server/tool/spec/codegen_matchers.dart b/pkg/analysis_server/tool/spec/codegen_matchers.dart
index be2f847..10c5b85 100644
--- a/pkg/analysis_server/tool/spec/codegen_matchers.dart
+++ b/pkg/analysis_server/tool/spec/codegen_matchers.dart
@@ -35,8 +35,8 @@
   String context;
 
   CodegenMatchersVisitor(Api api)
-      : super(api),
-        toHtmlVisitor = new ToHtmlVisitor(api) {
+      : toHtmlVisitor = new ToHtmlVisitor(api),
+        super(api) {
     codeGeneratorSettings.commentLineLength = 79;
     codeGeneratorSettings.languageName = 'dart';
   }
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index a8babb1..6e1bf7c 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -172,8 +172,8 @@
   ApiMappings apiMappings;
 
   ToHtmlVisitor(Api api)
-      : super(api),
-        apiMappings = new ApiMappings(api) {
+      : apiMappings = new ApiMappings(api),
+        super(api) {
     apiMappings.visitApi();
   }
 
diff --git a/pkg/analyzer/benchmark/errors_in_all_libraries.dart b/pkg/analyzer/benchmark/errors_in_all_libraries.dart
index f428191..0d68c2f 100644
--- a/pkg/analyzer/benchmark/errors_in_all_libraries.dart
+++ b/pkg/analyzer/benchmark/errors_in_all_libraries.dart
@@ -40,8 +40,9 @@
       new PackageUriResolver([new JavaFile(packageRoot)])
     ]);
 
-    context.analysisOptions.strongMode = true;
-    context.analysisOptions.strongModeHints = true;
+    AnalysisOptionsImpl options = context.analysisOptions;
+    options.strongMode = true;
+    options.strongModeHints = true;
 
     var mainSource =
         new FileBasedSource(new JavaFile(p.fromUri(Platform.script)));
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 385849f..860c029 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -646,6 +646,11 @@
   bool get isPublic;
 
   /**
+   * Return `true` if this element has an annotation of the form '@required'.
+   */
+  bool get isRequired;
+
+  /**
    * Return `true` if this element is synthetic. A synthetic element is an
    * element that is not represented in the source code explicitly, but is
    * implied by the source code, such as the default constructor for a class
@@ -830,6 +835,12 @@
    * a proxy object.
    */
   bool get isProxy;
+
+  /**
+   * Return `true` if this annotation marks the associated member as being
+   * required.
+   */
+  bool get isRequired;
 }
 
 /**
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 93428bc..5035b93 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -296,7 +296,7 @@
   }
 
   @override
-  Resource renameSync(String newPath) {
+  File renameSync(String newPath) {
     throw new FileSystemException(path, 'File could not be renamed');
   }
 
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 1088fcc..e259f75 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -132,7 +132,7 @@
   }
 
   @override
-  Resource renameSync(String newPath) {
+  File renameSync(String newPath) {
     try {
       io.File file = _entry as io.File;
       io.File newFile = file.renameSync(newPath);
diff --git a/pkg/analyzer/lib/src/cancelable_future.dart b/pkg/analyzer/lib/src/cancelable_future.dart
index 8ae070b..803137d 100644
--- a/pkg/analyzer/lib/src/cancelable_future.dart
+++ b/pkg/analyzer/lib/src/cancelable_future.dart
@@ -252,11 +252,11 @@
       _completer._outerCompleter.future.catchError(onError, test: test);
 
   @override
-  Future then(onValue(T value), {Function onError}) =>
+  Future/*<S>*/ then/*<S>*/(/*=S*/ onValue(T value), {Function onError}) =>
       _completer._outerCompleter.future.then(onValue, onError: onError);
 
   @override
-  Future timeout(Duration timeLimit, {onTimeout()}) {
+  Future<T> timeout(Duration timeLimit, {onTimeout()}) {
     // TODO(paulberry): Implement this in such a way that a timeout cancels
     // the future.
     return _completer._outerCompleter.future
@@ -288,11 +288,11 @@
       _future.catchError(onError, test: test);
 
   @override
-  Future then(onValue(value), {Function onError}) =>
+  Future/*<S>*/ then/*<S>*/(/*=S*/ onValue(T value), {Function onError}) =>
       _future.then(onValue, onError: onError);
 
   @override
-  Future timeout(Duration timeLimit, {onTimeout()}) =>
+  Future<T> timeout(Duration timeLimit, {onTimeout()}) =>
       _future.timeout(timeLimit, onTimeout: onTimeout);
 
   @override
diff --git a/pkg/analyzer/lib/src/codegen/tools.dart b/pkg/analyzer/lib/src/codegen/tools.dart
index 763359a..cccab10 100644
--- a/pkg/analyzer/lib/src/codegen/tools.dart
+++ b/pkg/analyzer/lib/src/codegen/tools.dart
@@ -511,7 +511,8 @@
    * Execute [callback], wrapping its output in an element with the given
    * [name] and [attributes].
    */
-  void element(String name, Map<String, String> attributes, [void callback()]) {
+  void element(String name, Map<dynamic, String> attributes,
+      [void callback()]) {
     add(makeElement(name, attributes, collectHtml(callback)));
   }
 
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 98e0451..8be0a41 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -173,12 +173,13 @@
    * It does not update the cache, if the corresponding [CacheEntry] does not
    * exist, then the default value is returned.
    */
-  Object getValue(AnalysisTarget target, ResultDescriptor result) {
+  Object/*=V*/ getValue/*<V>*/(
+      AnalysisTarget target, ResultDescriptor/*<V>*/ result) {
     CacheEntry entry = get(target);
     if (entry == null) {
       return result.defaultValue;
     }
-    return entry.getValue(result);
+    return entry.getValue(result) as Object/*=V*/;
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index d2659ba..1603fac 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -833,8 +833,8 @@
   }
 
   @override
-  Object getConfigurationData(ResultDescriptor key) =>
-      _configurationData[key] ?? key?.defaultValue;
+  Object/*=V*/ getConfigurationData/*<V>*/(ResultDescriptor/*<V>*/ key) =>
+      (_configurationData[key] ?? key?.defaultValue) as Object/*=V*/;
 
   @override
   TimestampedData<String> getContents(Source source) {
@@ -1238,6 +1238,7 @@
       entry.setState(RESOLVED_UNIT9, CacheState.FLUSHED);
       entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
       entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
+      entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
       // USED_IMPORTED_ELEMENTS
       // USED_LOCAL_ELEMENTS
       setValue(STRONG_MODE_ERRORS, AnalysisError.NO_ERRORS);
@@ -1316,6 +1317,7 @@
     entry.setState(RESOLVED_UNIT9, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
   }
 
@@ -1551,12 +1553,12 @@
         new LibrarySpecificUnit(librarySource, unitSource);
     for (ResultDescriptor result in [
       RESOLVED_UNIT,
+      RESOLVED_UNIT12,
       RESOLVED_UNIT11,
       RESOLVED_UNIT10,
       RESOLVED_UNIT9,
       RESOLVED_UNIT8,
-      RESOLVED_UNIT7,
-      RESOLVED_UNIT6
+      RESOLVED_UNIT7
     ]) {
       CompilationUnit unit = getResult(target, result);
       if (unit != null) {
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index a8d1917..4555a80 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -7600,8 +7600,7 @@
   /**
    * The node that is the parent of each of the elements in the list.
    */
-  @override
-  AstNodeImpl owner;
+  AstNodeImpl _owner;
 
   /**
    * The elements contained in the list.
@@ -7613,7 +7612,7 @@
    * are added to the list will have their parent set to the given [owner]. The
    * list will initially be populated with the given [elements].
    */
-  NodeListImpl(this.owner, [List<E> elements]) {
+  NodeListImpl(this._owner, [List<E> elements]) {
     addAll(elements);
   }
 
@@ -7642,6 +7641,14 @@
     throw new UnsupportedError("Cannot resize NodeList.");
   }
 
+  @override
+  AstNode get owner => _owner;
+
+  @override
+  void set owner(AstNode value) {
+    _owner = value as AstNodeImpl;
+  }
+
   E operator [](int index) {
     if (index < 0 || index >= _elements.length) {
       throw new RangeError("Index: $index, Size: ${_elements.length}");
@@ -7653,7 +7660,7 @@
     if (index < 0 || index >= _elements.length) {
       throw new RangeError("Index: $index, Size: ${_elements.length}");
     }
-    owner._becomeParentOf(node);
+    _owner._becomeParentOf(node);
     _elements[index] = node;
   }
 
@@ -7675,7 +7682,7 @@
     if (nodes != null && !nodes.isEmpty) {
       _elements.addAll(nodes);
       for (E node in nodes) {
-        owner._becomeParentOf(node);
+        _owner._becomeParentOf(node);
       }
       return true;
     }
@@ -7693,7 +7700,7 @@
     if (index < 0 || index > length) {
       throw new RangeError("Index: $index, Size: ${_elements.length}");
     }
-    owner._becomeParentOf(node);
+    _owner._becomeParentOf(node);
     if (length == 0) {
       _elements.add(node);
     } else {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 01da784f..ba28157 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1649,6 +1649,17 @@
   static String PROXY_VARIABLE_NAME = "proxy";
 
   /**
+   * The name of the class used to mark a parameter as being required.
+   */
+  static String _REQUIRED_CLASS_NAME = "Required";
+
+  /**
+   * The name of the top-level variable used to mark a parameter as being
+   * required.
+   */
+  static String _REQUIRED_VARIABLE_NAME = "required";
+
+  /**
    * The element representing the field, variable, or constructor being used as
    * an annotation.
    */
@@ -1720,6 +1731,15 @@
       element.name == PROXY_VARIABLE_NAME &&
       element.library?.isDartCore == true;
 
+  @override
+  bool get isRequired =>
+      element is ConstructorElement &&
+          element.enclosingElement.name == _REQUIRED_CLASS_NAME &&
+          element.library?.name == _META_LIB_NAME ||
+      element is PropertyAccessorElement &&
+          element.name == _REQUIRED_VARIABLE_NAME &&
+          element.library?.name == _META_LIB_NAME;
+
   /**
    * Get the library containing this annotation.
    */
@@ -1935,6 +1955,16 @@
   bool get isPublic => !isPrivate;
 
   @override
+  bool get isRequired {
+    for (ElementAnnotation annotation in metadata) {
+      if (annotation.isRequired) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
   bool get isSynthetic => hasModifier(Modifier.SYNTHETIC);
 
   @override
@@ -4093,6 +4123,9 @@
   bool get isPublic => !isPrivate;
 
   @override
+  bool get isRequired => false;
+
+  @override
   bool get isSynthetic => true;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 8cde8d0..99b87b2 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -71,6 +71,9 @@
   bool get isProxy => actualElement.isProxy;
 
   @override
+  bool get isRequired => actualElement.isRequired;
+
+  @override
   bool get isValidMixin => actualElement.isValidMixin;
 
   @override
@@ -95,6 +98,9 @@
   ConstructorElement get unnamedConstructor => actualElement.unnamedConstructor;
 
   @override
+  NamedCompilationUnitMember computeNode() => super.computeNode();
+
+  @override
   FieldElement getField(String fieldName) => actualElement.getField(fieldName);
 
   @override
@@ -359,6 +365,9 @@
   bool get isPublic => actualElement.isPublic;
 
   @override
+  bool get isRequired => actualElement.isRequired;
+
+  @override
   bool get isSynthetic => actualElement.isSynthetic;
 
   @override
@@ -895,6 +904,9 @@
 
   @override
   SourceRange get visibleRange => actualElement.visibleRange;
+
+  @override
+  FormalParameter computeNode() => super.computeNode();
 }
 
 /**
@@ -1013,6 +1025,9 @@
 
   @override
   ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
+
+  @override
+  VariableDeclaration computeNode() => super.computeNode();
 }
 
 /**
@@ -1075,10 +1090,12 @@
   @override
   bool get isFinal => actualElement.isFinal;
 
+  @deprecated
   @override
   bool get isPotentiallyMutatedInClosure =>
       actualElement.isPotentiallyMutatedInClosure;
 
+  @deprecated
   @override
   bool get isPotentiallyMutatedInScope =>
       actualElement.isPotentiallyMutatedInScope;
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 0ac6d4a..f467ce2 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -473,6 +473,9 @@
   bool get isPublic => _baseElement.isPublic;
 
   @override
+  bool get isRequired => _baseElement.isRequired;
+
+  @override
   bool get isSynthetic => _baseElement.isSynthetic;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index aedd7b2..475383e 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -688,7 +688,7 @@
       // base types.
       assert(this.prunedTypedefs == null);
       List<DartType> typeArgs = typeArguments
-          .map((TypeImpl t) => t.pruned(prune))
+          .map((DartType t) => (t as TypeImpl).pruned(prune))
           .toList(growable: false);
       return new FunctionTypeImpl._(
           element, name, prune, typeArgs, _isInstantiated);
@@ -1616,8 +1616,9 @@
       // base types.
       assert(this.prunedTypedefs == null);
       InterfaceTypeImpl result = new InterfaceTypeImpl._(element, name, prune);
-      result.typeArguments =
-          typeArguments.map((TypeImpl t) => t.pruned(prune)).toList();
+      result.typeArguments = typeArguments
+          .map((DartType t) => (t as TypeImpl).pruned(prune))
+          .toList();
       return result;
     }
   }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 846b27b..2a75edf 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -346,7 +346,7 @@
    *
    * See [setConfigurationData].
    */
-  Object getConfigurationData(ResultDescriptor key);
+  Object/*=V*/ getConfigurationData/*<V>*/(ResultDescriptor/*<V>*/ key);
 
   /**
    * Return the contents and timestamp of the given [source].
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 4b67db5..4a78c0d 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -177,7 +177,7 @@
    * Return the value of the given [property], or `null` if the given property
    * is not defined for this error.
    */
-  Object getProperty(ErrorProperty property) => null;
+  Object/*=V*/ getProperty/*<V>*/(ErrorProperty/*<V>*/ property) => null;
 
   @override
   String toString() {
@@ -256,13 +256,14 @@
       : super(source, offset, length, errorCode, arguments);
 
   @override
-  Object getProperty(ErrorProperty property) => _propertyMap[property];
+  Object/*=V*/ getProperty/*<V>*/(ErrorProperty/*<V>*/ property) =>
+      _propertyMap[property] as Object/*=V*/;
 
   /**
    * Set the value of the given [property] to the given [value]. Using a value
    * of `null` will effectively remove the property from this error.
    */
-  void setProperty(ErrorProperty property, Object value) {
+  void setProperty/*<V>*/(ErrorProperty/*<V>*/ property, Object/*=V*/ value) {
     _propertyMap[property] = value;
   }
 }
@@ -2682,6 +2683,7 @@
     HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
     HintCode.INVALID_ASSIGNMENT,
     HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
+    HintCode.MISSING_REQUIRED_PARAM,
     HintCode.MISSING_RETURN,
     HintCode.NULL_AWARE_IN_CONDITION,
     HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER,
@@ -3068,28 +3070,28 @@
 /**
  * The properties that can be associated with an [AnalysisError].
  */
-class ErrorProperty extends Enum<ErrorProperty> {
+class ErrorProperty<V> extends Enum<ErrorProperty> {
   /**
    * A property whose value is a list of [FieldElement]s that are final, but
    * not initialized by a constructor.
    */
-  static const ErrorProperty NOT_INITIALIZED_FIELDS =
-      const ErrorProperty('NOT_INITIALIZED_FIELDS', 0);
+  static const ErrorProperty<List<FieldElement>> NOT_INITIALIZED_FIELDS =
+      const ErrorProperty<List<FieldElement>>('NOT_INITIALIZED_FIELDS', 0);
 
   /**
    * A property whose value is the name of the library that is used by all
    * of the "part of" directives, so should be used in the "library" directive.
    * Is `null` if there is no a single name used by all of the parts.
    */
-  static const ErrorProperty PARTS_LIBRARY_NAME =
-      const ErrorProperty('PARTS_LIBRARY_NAME', 1);
+  static const ErrorProperty<String> PARTS_LIBRARY_NAME =
+      const ErrorProperty<String>('PARTS_LIBRARY_NAME', 1);
 
   /**
    * A property whose value is a list of [ExecutableElement] that should
    * be but are not implemented by a concrete class.
    */
-  static const ErrorProperty UNIMPLEMENTED_METHODS =
-      const ErrorProperty('UNIMPLEMENTED_METHODS', 2);
+  static const ErrorProperty<List<ExecutableElement>> UNIMPLEMENTED_METHODS =
+      const ErrorProperty<List<ExecutableElement>>('UNIMPLEMENTED_METHODS', 2);
 
   static const List<ErrorProperty> values = const [
     NOT_INITIALIZED_FIELDS,
@@ -3571,6 +3573,17 @@
       "The member '{0}' can only be used within instance members of subclasses of '{1}'");
 
   /**
+   * Generate a hint for a constructor, function or method invocation where a
+   * required parameter is missing.
+   *
+   * Parameters:
+   * 0: the name of the parameter
+   * 1: an optional reason
+   */
+  static const HintCode MISSING_REQUIRED_PARAM = const HintCode(
+      'MISSING_REQUIRED_PARAM', "The parameter '{0}' is required. {1}");
+
+  /**
    * Generate a hint for methods or functions that have a return type, but do
    * not have a non-void return statement on all branches. At the end of methods
    * or functions with no return, Dart implicitly returns `null`, avoiding these
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index c77d13a..aa3651e 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -818,6 +818,8 @@
         InterfaceType interfaceType = type;
         _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
         _checkForConstOrNewWithEnum(node, typeName, interfaceType);
+        _checkForMissingRequiredParam(
+            node.staticElement?.type, node.argumentList, node.constructorName);
         if (_isInConstInstanceCreation) {
           _checkForConstWithNonConst(node);
           _checkForConstWithUndefinedConstructor(
@@ -929,6 +931,8 @@
     } else {
       _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName);
     }
+    _checkForMissingRequiredParam(
+        node.staticInvokeType, node.argumentList, methodName);
     return super.visitMethodInvocation(node);
   }
 
@@ -3725,6 +3729,50 @@
         [name.name]);
   }
 
+  void _checkForMissingRequiredParam(
+      DartType type, ArgumentList argumentList, AstNode node) {
+    if (type is FunctionType) {
+      List<ParameterElement> parameters = type.parameters;
+      for (ParameterElement param in parameters) {
+        if (param.parameterKind == ParameterKind.NAMED) {
+          ElementAnnotationImpl annotation = _getRequiredAnnotation(param);
+          if (annotation != null) {
+            String paramName = param.name;
+            if (!_containsNamedExpression(argumentList, paramName)) {
+              DartObject constantValue = annotation.constantValue;
+              String reason =
+                  constantValue.getField('reason')?.toStringValue() ?? '';
+              // Append a `.` if needed.
+              if (reason != null &&
+                  reason.isNotEmpty &&
+                  !reason.endsWith('.')) {
+                reason += '.';
+              }
+
+              _errorReporter.reportErrorForNode(
+                  HintCode.MISSING_REQUIRED_PARAM, node, [paramName, reason]);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param
+      .metadata
+      .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null);
+
+  bool _containsNamedExpression(ArgumentList args, String name) {
+    for (Expression expression in args.arguments) {
+      if (expression is NamedExpression) {
+        if (expression.name.label.name == name) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
   /**
    * Check whether the given [executableElement] collides with the name of a
    * static method in one of its superclasses, and reports the appropriate
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 61c8570..3d3d7d8 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -928,6 +928,7 @@
         isByTask(PropagateVariableTypeTask.DESCRIPTOR) ||
         isByTask(ScanDartTask.DESCRIPTOR) ||
         isByTask(ResolveConstantExpressionTask.DESCRIPTOR) ||
+        isByTask(ResolveDirectiveElementsTask.DESCRIPTOR) ||
         isByTask(ResolveInstanceFieldsInUnitTask.DESCRIPTOR) ||
         isByTask(ResolveLibraryReferencesTask.DESCRIPTOR) ||
         isByTask(ResolveLibraryTask.DESCRIPTOR) ||
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 7e5bee8..28cc6f4 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -3816,7 +3816,7 @@
       return _createSyntheticToken(TokenType.SEMICOLON);
     }
     _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
-    return _currentToken;
+    return _createSyntheticToken(type);
   }
 
   /**
@@ -8634,8 +8634,10 @@
             return null;
           } else if (type == TokenType.OPEN_CURLY_BRACKET) {
             bracketNestingLevel++;
+            token = token.next;
           } else if (type == TokenType.CLOSE_CURLY_BRACKET) {
             bracketNestingLevel--;
+            token = token.next;
           } else if (type == TokenType.STRING) {
             token = _skipStringLiteral(token);
             if (token == null) {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 4849014..0a3fdb8 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2852,6 +2852,13 @@
     }
     for (ExportElement export in exports) {
       if (export.exportedLibrary.source == source) {
+        // Must have the same offset.
+        if (export.nameOffset != node.offset) {
+          continue;
+        }
+        // In general we should also match combinators.
+        // But currently we invalidate element model on any directive change.
+        // So, either the combinators are the same, or we build new elements.
         return export;
       }
     }
@@ -2874,17 +2881,18 @@
     for (ImportElement element in imports) {
       if (element.importedLibrary.source == source) {
         foundSource = true;
-        PrefixElement prefixElement = element.prefix;
-        if (prefix == null) {
-          if (prefixElement == null) {
-            return element;
-          }
-        } else {
-          if (prefixElement != null &&
-              prefix.name == prefixElement.displayName) {
-            return element;
-          }
+        // Must have the same offset.
+        if (element.nameOffset != node.offset) {
+          continue;
         }
+        // Must have the same prefix.
+        if (element.prefix?.displayName != prefix?.name) {
+          continue;
+        }
+        // In general we should also match combinators.
+        // But currently we invalidate element model on any directive change.
+        // So, either the combinators are the same, or we build new elements.
+        return element;
       }
     }
     if (foundSource) {
@@ -4082,17 +4090,17 @@
 
   @override
   void visitExportDirective(ExportDirective node) {
-    _visitMetadata(node.metadata);
+    _visitDirective(node);
   }
 
   @override
   void visitImportDirective(ImportDirective node) {
-    _visitMetadata(node.metadata);
+    _visitDirective(node);
   }
 
   @override
   void visitLibraryDirective(LibraryDirective node) {
-    _visitMetadata(node.metadata);
+    _visitDirective(node);
   }
 
   @override
@@ -4116,6 +4124,14 @@
     _visitIdentifier(node.staticElement, node.name);
   }
 
+  /**
+   * Visit identifiers used by the given [directive].
+   */
+  void _visitDirective(Directive directive) {
+    directive.documentationComment?.accept(this);
+    directive.metadata.accept(this);
+  }
+
   void _visitIdentifier(Element element, String name) {
     if (element == null) {
       return;
@@ -4150,20 +4166,6 @@
     // Remember the element.
     usedElements.elements.add(element);
   }
-
-  /**
-   * Given some [NodeList] of [Annotation]s, ensure that the identifiers are visited by
-   * this visitor. Specifically, this covers the cases where AST nodes don't have their identifiers
-   * visited by this visitor, but still need their annotations visited.
-   *
-   * @param annotations the list of annotations to visit
-   */
-  void _visitMetadata(NodeList<Annotation> annotations) {
-    int count = annotations.length;
-    for (int i = 0; i < count; i++) {
-      annotations[i].accept(this);
-    }
-  }
 }
 
 /**
@@ -4463,7 +4465,7 @@
  * While this class does not yet have support for an "Organize Imports" action, this logic built up
  * in this class could be used for such an action in the future.
  */
-class ImportsVerifier /*extends RecursiveAstVisitor<Object>*/ {
+class ImportsVerifier {
   /**
    * A list of [ImportDirective]s that the current library imports, as identifiers are visited
    * by this visitor and an import has been identified as being used by the library, the
@@ -7543,8 +7545,10 @@
 
     // Same number of type formals. Instantiate the function type so its
     // parameter and return type are in terms of the surrounding context.
-    return fnType.instantiate(
-        typeParameters.map((t) => t.name.staticElement.type).toList());
+    return fnType.instantiate(typeParameters
+        .map((TypeParameter t) =>
+            (t.name.staticElement as TypeParameterElement).type)
+        .toList());
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 9dc5506..9caffef 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -873,7 +873,7 @@
     // Walk the superinterface hierarchy looking for [genericType].
     List<DartType> candidates = <DartType>[];
     HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    void recurse(InterfaceTypeImpl interface) {
+    void recurse(InterfaceType interface) {
       if (interface.element == genericType.element &&
           interface.typeArguments.isNotEmpty) {
         candidates.add(interface.typeArguments[0]);
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index 545064a..145c4aa 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -224,6 +224,7 @@
     registerExtension(taskId, ReadyLibraryElement6Task.DESCRIPTOR);
     registerExtension(taskId, ReadyResolvedUnitTask.DESCRIPTOR);
     registerExtension(taskId, ResolveConstantExpressionTask.DESCRIPTOR);
+    registerExtension(taskId, ResolveDirectiveElementsTask.DESCRIPTOR);
     registerExtension(taskId, ResolveInstanceFieldsInUnitTask.DESCRIPTOR);
     registerExtension(taskId, ResolveLibraryReferencesTask.DESCRIPTOR);
     registerExtension(taskId, ResolveLibraryTask.DESCRIPTOR);
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 43b5547..5cb69d9 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -115,6 +115,19 @@
   }
 }
 
+class _UnlinkedExprAssignOperatorReader extends fb.Reader<idl.UnlinkedExprAssignOperator> {
+  const _UnlinkedExprAssignOperatorReader() : super();
+
+  @override
+  int get size => 1;
+
+  @override
+  idl.UnlinkedExprAssignOperator read(fb.BufferPointer bp) {
+    int index = const fb.Uint8Reader().read(bp);
+    return index < idl.UnlinkedExprAssignOperator.values.length ? idl.UnlinkedExprAssignOperator.values[index] : idl.UnlinkedExprAssignOperator.assign;
+  }
+}
+
 class _UnlinkedParamKindReader extends fb.Reader<idl.UnlinkedParamKind> {
   const _UnlinkedParamKindReader() : super();
 
@@ -3234,14 +3247,26 @@
 class UnlinkedConstBuilder extends Object with _UnlinkedConstMixin implements idl.UnlinkedConst {
   bool _finished = false;
 
+  List<idl.UnlinkedExprAssignOperator> _assignmentOperators;
   List<double> _doubles;
   List<int> _ints;
-  bool _isInvalid;
+  bool _isValidConst;
   List<idl.UnlinkedConstOperation> _operations;
   List<EntityRefBuilder> _references;
   List<String> _strings;
 
   @override
+  List<idl.UnlinkedExprAssignOperator> get assignmentOperators => _assignmentOperators ??= <idl.UnlinkedExprAssignOperator>[];
+
+  /**
+   * Sequence of operators used by assignment operations.
+   */
+  void set assignmentOperators(List<idl.UnlinkedExprAssignOperator> _value) {
+    assert(!_finished);
+    _assignmentOperators = _value;
+  }
+
+  @override
   List<double> get doubles => _doubles ??= <double>[];
 
   /**
@@ -3267,15 +3292,15 @@
   }
 
   @override
-  bool get isInvalid => _isInvalid ??= false;
+  bool get isValidConst => _isValidConst ??= false;
 
   /**
-   * Indicates whether the expression is not a valid potentially constant
+   * Indicates whether the expression is a valid potentially constant
    * expression.
    */
-  void set isInvalid(bool _value) {
+  void set isValidConst(bool _value) {
     assert(!_finished);
-    _isInvalid = _value;
+    _isValidConst = _value;
   }
 
   @override
@@ -3316,10 +3341,11 @@
     _strings = _value;
   }
 
-  UnlinkedConstBuilder({List<double> doubles, List<int> ints, bool isInvalid, List<idl.UnlinkedConstOperation> operations, List<EntityRefBuilder> references, List<String> strings})
-    : _doubles = doubles,
+  UnlinkedConstBuilder({List<idl.UnlinkedExprAssignOperator> assignmentOperators, List<double> doubles, List<int> ints, bool isValidConst, List<idl.UnlinkedConstOperation> operations, List<EntityRefBuilder> references, List<String> strings})
+    : _assignmentOperators = assignmentOperators,
+      _doubles = doubles,
       _ints = ints,
-      _isInvalid = isInvalid,
+      _isValidConst = isValidConst,
       _operations = operations,
       _references = references,
       _strings = strings;
@@ -3334,11 +3360,15 @@
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
+    fb.Offset offset_assignmentOperators;
     fb.Offset offset_doubles;
     fb.Offset offset_ints;
     fb.Offset offset_operations;
     fb.Offset offset_references;
     fb.Offset offset_strings;
+    if (!(_assignmentOperators == null || _assignmentOperators.isEmpty)) {
+      offset_assignmentOperators = fbBuilder.writeListUint8(_assignmentOperators.map((b) => b.index).toList());
+    }
     if (!(_doubles == null || _doubles.isEmpty)) {
       offset_doubles = fbBuilder.writeListFloat64(_doubles);
     }
@@ -3355,13 +3385,16 @@
       offset_strings = fbBuilder.writeList(_strings.map((b) => fbBuilder.writeString(b)).toList());
     }
     fbBuilder.startTable();
+    if (offset_assignmentOperators != null) {
+      fbBuilder.addOffset(6, offset_assignmentOperators);
+    }
     if (offset_doubles != null) {
       fbBuilder.addOffset(4, offset_doubles);
     }
     if (offset_ints != null) {
       fbBuilder.addOffset(1, offset_ints);
     }
-    if (_isInvalid == true) {
+    if (_isValidConst == true) {
       fbBuilder.addBool(5, true);
     }
     if (offset_operations != null) {
@@ -3389,14 +3422,21 @@
 
   _UnlinkedConstImpl(this._bp);
 
+  List<idl.UnlinkedExprAssignOperator> _assignmentOperators;
   List<double> _doubles;
   List<int> _ints;
-  bool _isInvalid;
+  bool _isValidConst;
   List<idl.UnlinkedConstOperation> _operations;
   List<idl.EntityRef> _references;
   List<String> _strings;
 
   @override
+  List<idl.UnlinkedExprAssignOperator> get assignmentOperators {
+    _assignmentOperators ??= const fb.ListReader<idl.UnlinkedExprAssignOperator>(const _UnlinkedExprAssignOperatorReader()).vTableGet(_bp, 6, const <idl.UnlinkedExprAssignOperator>[]);
+    return _assignmentOperators;
+  }
+
+  @override
   List<double> get doubles {
     _doubles ??= const fb.Float64ListReader().vTableGet(_bp, 4, const <double>[]);
     return _doubles;
@@ -3409,9 +3449,9 @@
   }
 
   @override
-  bool get isInvalid {
-    _isInvalid ??= const fb.BoolReader().vTableGet(_bp, 5, false);
-    return _isInvalid;
+  bool get isValidConst {
+    _isValidConst ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    return _isValidConst;
   }
 
   @override
@@ -3437,9 +3477,10 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
+    if (assignmentOperators.isNotEmpty) _result["assignmentOperators"] = assignmentOperators.map((_value) => _value.toString().split('.')[1]).toList();
     if (doubles.isNotEmpty) _result["doubles"] = doubles.map((_value) => _value.isFinite ? _value : _value.toString()).toList();
     if (ints.isNotEmpty) _result["ints"] = ints;
-    if (isInvalid != false) _result["isInvalid"] = isInvalid;
+    if (isValidConst != false) _result["isValidConst"] = isValidConst;
     if (operations.isNotEmpty) _result["operations"] = operations.map((_value) => _value.toString().split('.')[1]).toList();
     if (references.isNotEmpty) _result["references"] = references.map((_value) => _value.toJson()).toList();
     if (strings.isNotEmpty) _result["strings"] = strings;
@@ -3448,9 +3489,10 @@
 
   @override
   Map<String, Object> toMap() => {
+    "assignmentOperators": assignmentOperators,
     "doubles": doubles,
     "ints": ints,
-    "isInvalid": isInvalid,
+    "isValidConst": isValidConst,
     "operations": operations,
     "references": references,
     "strings": strings,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 3457613..2a41e6c 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -178,11 +178,6 @@
   method,
 
   /**
-   * The `length` property access.
-   */
-  length,
-
-  /**
    * The entity is a typedef.
    */
   typedef,
@@ -307,6 +302,13 @@
   pushReference,
 
   /**
+   * Pop the top value from the stack, extract the value of the property with
+   * the name obtained from [UnlinkedConst.strings], and push the result back
+   * onto the stack.
+   */
+  extractProperty,
+
+  /**
    * Pop the top `n` values from the stack (where `n` is obtained from
    * [UnlinkedConst.ints]) into a list (filled from the end) and take the next
    * `n` values from [UnlinkedConst.strings] and use the lists of names and
@@ -358,12 +360,6 @@
   makeTypedMap,
 
   /**
-   * Pop the top 2 values from the stack, pass them to the predefined Dart
-   * function `identical`, and push the result back onto the stack.
-   */
-  identical,
-
-  /**
    * Pop the top 2 values from the stack, evaluate `v1 == v2`, and push the
    * result back onto the stack.
    */
@@ -502,10 +498,118 @@
   conditional,
 
   /**
-   * Pop the top value from the stack, evaluate `v.length`, and push the result
-   * back onto the stack.
+   * Pop from the stack `value` and get the next `target` reference from
+   * [UnlinkedConst.references] - a top-level variable (prefixed or not), an
+   * assignable field of a class (prefixed or not), or a sequence of getters
+   * ending with an assignable property `a.b.b.c.d.e`.  In general `a.b` cannot
+   * not be distinguished between: `a` is a prefix and `b` is a top-level
+   * variable; or `a` is an object and `b` is the name of a property.  Perform
+   * `reference op= value` where `op` is the next assignment operator from
+   * [UnlinkedConst.assignmentOperators].  Push `value` back into the stack.
+   *
+   * If the assignment operator is a prefix/postfix increment/decrement, then
+   * `value` is not present in the stack, so it should not be popped and the
+   * corresponding value of the `target` after/before update is pushed into the
+   * stack instead.
    */
-  length
+  assignToRef,
+
+  /**
+   * Pop from the stack `target` and `value`.  Get the name of the property from
+   * `UnlinkedConst.strings` and assign the `value` to the named property of the
+   * `target`.  This operation is used when we know that the `target` is an
+   * object reference expression, e.g. `new Foo().a.b.c` or `a.b[0].c.d`.
+   * Perform `target.property op= value` where `op` is the next assignment
+   * operator from [UnlinkedConst.assignmentOperators].  Push `value` back into
+   * the stack.
+   *
+   * If the assignment operator is a prefix/postfix increment/decrement, then
+   * `value` is not present in the stack, so it should not be popped and the
+   * corresponding value of the `target` after/before update is pushed into the
+   * stack instead.
+   */
+  assignToProperty,
+
+  /**
+   * Pop from the stack `index`, `target` and `value`.  Perform
+   * `target[index] op= value`  where `op` is the next assignment operator from
+   * [UnlinkedConst.assignmentOperators].  Push `value` back into the stack.
+   *
+   * If the assignment operator is a prefix/postfix increment/decrement, then
+   * `value` is not present in the stack, so it should not be popped and the
+   * corresponding value of the `target` after/before update is pushed into the
+   * stack instead.
+   */
+  assignToIndex,
+
+  /**
+   * Pop from the stack `index` and `target`.  Push into the stack the result
+   * of evaluation of `target[index]`.
+   */
+  extractIndex,
+
+  /**
+   * Pop the top `n` values from the stack (where `n` is obtained from
+   * [UnlinkedConst.ints]) into a list (filled from the end) and take the next
+   * `n` values from [UnlinkedConst.strings] and use the lists of names and
+   * values to create named arguments.  Then pop the top `m` values from the
+   * stack (where `m` is obtained from [UnlinkedConst.ints]) into a list (filled
+   * from the end) and use them as positional arguments.  Use the lists of
+   * positional and names arguments to invoke a method (or a function) with
+   * the reference from [UnlinkedConst.references].  Push the result of
+   * invocation value into the stack.
+   *
+   * In general `a.b` cannot not be distinguished between: `a` is a prefix and
+   * `b` is a top-level function; or `a` is an object and `b` is the name of a
+   * method.  This operation should be used for a sequence of identifiers
+   * `a.b.b.c.d.e` ending with an invokable result.
+   */
+  invokeMethodRef,
+
+  /**
+   * Pop the top `n` values from the stack (where `n` is obtained from
+   * [UnlinkedConst.ints]) into a list (filled from the end) and take the next
+   * `n` values from [UnlinkedConst.strings] and use the lists of names and
+   * values to create named arguments.  Then pop the top `m` values from the
+   * stack (where `m` is obtained from [UnlinkedConst.ints]) into a list (filled
+   * from the end) and use them as positional arguments.  Use the lists of
+   * positional and names arguments to invoke the method with the name from
+   * [UnlinkedConst.strings] of the target popped from the stack, and push the
+   * resulting value into the stack.
+   *
+   * This operation should be used for invocation of a method invocation
+   * where `target` is know to be an object instance.
+   */
+  invokeMethod,
+
+  /**
+   * Begin a new cascade section.  Duplicate the top value of the stack.
+   */
+  cascadeSectionBegin,
+
+  /**
+   * End a new cascade section.  Pop the top value from the stack and throw it
+   * away.
+   */
+  cascadeSectionEnd,
+
+  /**
+   * Pop the top value from the stack and cast it to the type with reference
+   * from [UnlinkedConst.references], push the result into the stack.
+   */
+  typeCast,
+
+  /**
+   * Pop the top value from the stack and check whether is is a subclass of the
+   * type with reference from [UnlinkedConst.references], push the result into
+   * the stack.
+   */
+  typeCheck,
+
+  /**
+   * Pop the top value from the stack and raise an exception with this value.
+   */
+  throwException
 }
 
 /**
@@ -554,6 +658,100 @@
 }
 
 /**
+ * Enum representing the various kinds of assignment operations combined
+ * with:
+ *    [UnlinkedConstOperation.assignToRef],
+ *    [UnlinkedConstOperation.assignToProperty],
+ *    [UnlinkedConstOperation.assignToIndex].
+ */
+enum UnlinkedExprAssignOperator : byte {
+  /**
+   * Perform simple assignment `target = operand`.
+   */
+  assign,
+
+  /**
+   * Perform `target ??= operand`.
+   */
+  ifNull,
+
+  /**
+   * Perform `target *= operand`.
+   */
+  multiply,
+
+  /**
+   * Perform `target /= operand`.
+   */
+  divide,
+
+  /**
+   * Perform `target ~/= operand`.
+   */
+  floorDivide,
+
+  /**
+   * Perform `target %= operand`.
+   */
+  modulo,
+
+  /**
+   * Perform `target += operand`.
+   */
+  plus,
+
+  /**
+   * Perform `target -= operand`.
+   */
+  minus,
+
+  /**
+   * Perform `target <<= operand`.
+   */
+  shiftLeft,
+
+  /**
+   * Perform `target >>= operand`.
+   */
+  shiftRight,
+
+  /**
+   * Perform `target &= operand`.
+   */
+  bitAnd,
+
+  /**
+   * Perform `target ^= operand`.
+   */
+  bitXor,
+
+  /**
+   * Perform `target |= operand`.
+   */
+  bitOr,
+
+  /**
+   * Perform `++target`.
+   */
+  prefixIncrement,
+
+  /**
+   * Perform `--target`.
+   */
+  prefixDecrement,
+
+  /**
+   * Perform `target++`.
+   */
+  postfixIncrement,
+
+  /**
+   * Perform `target++`.
+   */
+  postfixDecrement
+}
+
+/**
  * Enum used to indicate the kind of a parameter.
  */
 enum UnlinkedParamKind : byte {
@@ -1208,6 +1406,11 @@
  */
 table UnlinkedConst {
   /**
+   * Sequence of operators used by assignment operations.
+   */
+  assignmentOperators:[UnlinkedExprAssignOperator] (id: 6);
+
+  /**
    * Sequence of 64-bit doubles consumed by the operation `pushDouble`.
    */
   doubles:[double] (id: 4);
@@ -1220,10 +1423,10 @@
   ints:[uint] (id: 1);
 
   /**
-   * Indicates whether the expression is not a valid potentially constant
+   * Indicates whether the expression is a valid potentially constant
    * expression.
    */
-  isInvalid:bool (id: 5);
+  isValidConst:bool (id: 5);
 
   /**
    * Sequence of operations to execute (starting with an empty stack) to form
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 31acca9..8f86380 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -718,11 +718,6 @@
   method,
 
   /**
-   * The `length` property access.
-   */
-  length,
-
-  /**
    * The entity is a typedef.
    */
   typedef,
@@ -996,6 +991,12 @@
  */
 abstract class UnlinkedConst extends base.SummaryClass {
   /**
+   * Sequence of operators used by assignment operations.
+   */
+  @Id(6)
+  List<UnlinkedExprAssignOperator> get assignmentOperators;
+
+  /**
    * Sequence of 64-bit doubles consumed by the operation `pushDouble`.
    */
   @Id(4)
@@ -1010,11 +1011,11 @@
   List<int> get ints;
 
   /**
-   * Indicates whether the expression is not a valid potentially constant
+   * Indicates whether the expression is a valid potentially constant
    * expression.
    */
   @Id(5)
-  bool get isInvalid;
+  bool get isValidConst;
 
   /**
    * Sequence of operations to execute (starting with an empty stack) to form
@@ -1129,6 +1130,13 @@
   pushReference,
 
   /**
+   * Pop the top value from the stack, extract the value of the property with
+   * the name obtained from [UnlinkedConst.strings], and push the result back
+   * onto the stack.
+   */
+  extractProperty,
+
+  /**
    * Pop the top `n` values from the stack (where `n` is obtained from
    * [UnlinkedConst.ints]) into a list (filled from the end) and take the next
    * `n` values from [UnlinkedConst.strings] and use the lists of names and
@@ -1180,12 +1188,6 @@
   makeTypedMap,
 
   /**
-   * Pop the top 2 values from the stack, pass them to the predefined Dart
-   * function `identical`, and push the result back onto the stack.
-   */
-  identical,
-
-  /**
    * Pop the top 2 values from the stack, evaluate `v1 == v2`, and push the
    * result back onto the stack.
    */
@@ -1324,10 +1326,118 @@
   conditional,
 
   /**
-   * Pop the top value from the stack, evaluate `v.length`, and push the result
-   * back onto the stack.
+   * Pop from the stack `value` and get the next `target` reference from
+   * [UnlinkedConst.references] - a top-level variable (prefixed or not), an
+   * assignable field of a class (prefixed or not), or a sequence of getters
+   * ending with an assignable property `a.b.b.c.d.e`.  In general `a.b` cannot
+   * not be distinguished between: `a` is a prefix and `b` is a top-level
+   * variable; or `a` is an object and `b` is the name of a property.  Perform
+   * `reference op= value` where `op` is the next assignment operator from
+   * [UnlinkedConst.assignmentOperators].  Push `value` back into the stack.
+   *
+   * If the assignment operator is a prefix/postfix increment/decrement, then
+   * `value` is not present in the stack, so it should not be popped and the
+   * corresponding value of the `target` after/before update is pushed into the
+   * stack instead.
    */
-  length,
+  assignToRef,
+
+  /**
+   * Pop from the stack `target` and `value`.  Get the name of the property from
+   * `UnlinkedConst.strings` and assign the `value` to the named property of the
+   * `target`.  This operation is used when we know that the `target` is an
+   * object reference expression, e.g. `new Foo().a.b.c` or `a.b[0].c.d`.
+   * Perform `target.property op= value` where `op` is the next assignment
+   * operator from [UnlinkedConst.assignmentOperators].  Push `value` back into
+   * the stack.
+   *
+   * If the assignment operator is a prefix/postfix increment/decrement, then
+   * `value` is not present in the stack, so it should not be popped and the
+   * corresponding value of the `target` after/before update is pushed into the
+   * stack instead.
+   */
+  assignToProperty,
+
+  /**
+   * Pop from the stack `index`, `target` and `value`.  Perform
+   * `target[index] op= value`  where `op` is the next assignment operator from
+   * [UnlinkedConst.assignmentOperators].  Push `value` back into the stack.
+   *
+   * If the assignment operator is a prefix/postfix increment/decrement, then
+   * `value` is not present in the stack, so it should not be popped and the
+   * corresponding value of the `target` after/before update is pushed into the
+   * stack instead.
+   */
+  assignToIndex,
+
+  /**
+   * Pop from the stack `index` and `target`.  Push into the stack the result
+   * of evaluation of `target[index]`.
+   */
+  extractIndex,
+
+  /**
+   * Pop the top `n` values from the stack (where `n` is obtained from
+   * [UnlinkedConst.ints]) into a list (filled from the end) and take the next
+   * `n` values from [UnlinkedConst.strings] and use the lists of names and
+   * values to create named arguments.  Then pop the top `m` values from the
+   * stack (where `m` is obtained from [UnlinkedConst.ints]) into a list (filled
+   * from the end) and use them as positional arguments.  Use the lists of
+   * positional and names arguments to invoke a method (or a function) with
+   * the reference from [UnlinkedConst.references].  Push the result of
+   * invocation value into the stack.
+   *
+   * In general `a.b` cannot not be distinguished between: `a` is a prefix and
+   * `b` is a top-level function; or `a` is an object and `b` is the name of a
+   * method.  This operation should be used for a sequence of identifiers
+   * `a.b.b.c.d.e` ending with an invokable result.
+   */
+  invokeMethodRef,
+
+  /**
+   * Pop the top `n` values from the stack (where `n` is obtained from
+   * [UnlinkedConst.ints]) into a list (filled from the end) and take the next
+   * `n` values from [UnlinkedConst.strings] and use the lists of names and
+   * values to create named arguments.  Then pop the top `m` values from the
+   * stack (where `m` is obtained from [UnlinkedConst.ints]) into a list (filled
+   * from the end) and use them as positional arguments.  Use the lists of
+   * positional and names arguments to invoke the method with the name from
+   * [UnlinkedConst.strings] of the target popped from the stack, and push the
+   * resulting value into the stack.
+   *
+   * This operation should be used for invocation of a method invocation
+   * where `target` is know to be an object instance.
+   */
+  invokeMethod,
+
+  /**
+   * Begin a new cascade section.  Duplicate the top value of the stack.
+   */
+  cascadeSectionBegin,
+
+  /**
+   * End a new cascade section.  Pop the top value from the stack and throw it
+   * away.
+   */
+  cascadeSectionEnd,
+
+  /**
+   * Pop the top value from the stack and cast it to the type with reference
+   * from [UnlinkedConst.references], push the result into the stack.
+   */
+  typeCast,
+
+  /**
+   * Pop the top value from the stack and check whether is is a subclass of the
+   * type with reference from [UnlinkedConst.references], push the result into
+   * the stack.
+   */
+  typeCheck,
+
+  /**
+   * Pop the top value from the stack and raise an exception with this value.
+   */
+  throwException,
 }
 
 /**
@@ -1768,6 +1878,100 @@
 }
 
 /**
+ * Enum representing the various kinds of assignment operations combined
+ * with:
+ *    [UnlinkedConstOperation.assignToRef],
+ *    [UnlinkedConstOperation.assignToProperty],
+ *    [UnlinkedConstOperation.assignToIndex].
+ */
+enum UnlinkedExprAssignOperator {
+  /**
+   * Perform simple assignment `target = operand`.
+   */
+  assign,
+
+  /**
+   * Perform `target ??= operand`.
+   */
+  ifNull,
+
+  /**
+   * Perform `target *= operand`.
+   */
+  multiply,
+
+  /**
+   * Perform `target /= operand`.
+   */
+  divide,
+
+  /**
+   * Perform `target ~/= operand`.
+   */
+  floorDivide,
+
+  /**
+   * Perform `target %= operand`.
+   */
+  modulo,
+
+  /**
+   * Perform `target += operand`.
+   */
+  plus,
+
+  /**
+   * Perform `target -= operand`.
+   */
+  minus,
+
+  /**
+   * Perform `target <<= operand`.
+   */
+  shiftLeft,
+
+  /**
+   * Perform `target >>= operand`.
+   */
+  shiftRight,
+
+  /**
+   * Perform `target &= operand`.
+   */
+  bitAnd,
+
+  /**
+   * Perform `target ^= operand`.
+   */
+  bitXor,
+
+  /**
+   * Perform `target |= operand`.
+   */
+  bitOr,
+
+  /**
+   * Perform `++target`.
+   */
+  prefixIncrement,
+
+  /**
+   * Perform `--target`.
+   */
+  prefixDecrement,
+
+  /**
+   * Perform `target++`.
+   */
+  postfixIncrement,
+
+  /**
+   * Perform `target++`.
+   */
+  postfixDecrement,
+}
+
+/**
  * Unlinked summary information about an import declaration.
  */
 abstract class UnlinkedImport extends base.SummaryClass {
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 279bd78..0f642ef 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -58,13 +58,18 @@
  *   checks.  E.g. see [ReferenceableElementForLink.asConstructor].
  */
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/constant/value.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/prelink.dart';
+import 'package:analyzer/src/task/strong_mode.dart';
 
 /**
  * Link together the build unit consisting of [libraryUris], using
@@ -72,12 +77,17 @@
  * build units, and [getUnit] to fetch the [UnlinkedUnit] objects from
  * both this build unit and other build units.
  *
+ * The [strong] flag controls whether type inference is performed in strong
+ * mode or spec mode.  Note that in spec mode, the only types that are inferred
+ * are the types of initializing formals, which are inferred from the types of
+ * the corresponding fields.
+ *
  * A map is returned whose keys are the URIs of the libraries in this
  * build unit, and whose values are the corresponding
  * [LinkedLibraryBuilder]s.
  */
 Map<String, LinkedLibraryBuilder> link(Set<String> libraryUris,
-    GetDependencyCallback getDependency, GetUnitCallback getUnit) {
+    GetDependencyCallback getDependency, GetUnitCallback getUnit, bool strong) {
   Map<String, LinkedLibraryBuilder> linkedLibraries =
       <String, LinkedLibraryBuilder>{};
   for (String absoluteUri in libraryUris) {
@@ -89,7 +99,7 @@
         getRelativeUnit,
         (String relativeUri) => getRelativeUnit(relativeUri)?.publicNamespace);
   }
-  relink(linkedLibraries, getDependency, getUnit);
+  relink(linkedLibraries, getDependency, getUnit, strong);
   return linkedLibraries;
 }
 
@@ -100,10 +110,69 @@
  * objects from other build units, and [getUnit] to fetch the
  * [UnlinkedUnit] objects from both this build unit and other build
  * units.
+ *
+ * The [strong] flag controls whether type inference is performed in strong
+ * mode or spec mode.  Note that in spec mode, the only types that are inferred
+ * are the types of initializing formals, which are inferred from the types of
+ * the corresponding fields.
  */
 void relink(Map<String, LinkedLibraryBuilder> libraries,
-    GetDependencyCallback getDependency, GetUnitCallback getUnit) {
-  new _Linker(libraries, getDependency, getUnit).link();
+    GetDependencyCallback getDependency, GetUnitCallback getUnit, bool strong) {
+  new _Linker(libraries, getDependency, getUnit, strong).link();
+}
+
+/**
+ * Create an [EntityRefBuilder] representing the given [type], in a form
+ * suitable for inclusion in [LinkedUnit.types].  [compilationUnit] is the
+ * compilation unit in which the type will be used.  If [slot] is provided, it
+ * is stored in [EntityRefBuilder.slot].
+ */
+EntityRefBuilder _createLinkedType(
+    DartType type,
+    CompilationUnitElementInBuildUnit compilationUnit,
+    TypeParameterizedElementForLink typeParameterContext,
+    {int slot}) {
+  EntityRefBuilder result = new EntityRefBuilder(slot: slot);
+  if (type is InterfaceType) {
+    ClassElementForLink element = type.element;
+    result.reference = compilationUnit.addReference(element);
+    if (type.typeArguments.isNotEmpty) {
+      result.typeArguments = type.typeArguments
+          .map((DartType t) =>
+              _createLinkedType(t, compilationUnit, typeParameterContext))
+          .toList();
+    }
+    return result;
+  } else if (type is VoidTypeImpl) {
+    result.reference = compilationUnit.addRawReference('void');
+    return result;
+  } else if (type is BottomTypeImpl) {
+    result.reference = compilationUnit.addRawReference('*bottom*');
+    return result;
+  } else if (type is TypeParameterType) {
+    TypeParameterElementForLink element = type.element;
+    result.paramReference =
+        typeParameterContext.typeParameterNestingLevel - element.nestingLevel;
+    return result;
+  } else if (type is FunctionType) {
+    Element element = type.element;
+    if (element is FunctionElementForLink_FunctionTypedParam) {
+      result.reference =
+          compilationUnit.addReference(element.enclosingExecutable);
+      result.implicitFunctionTypeIndices = element.implicitFunctionTypeIndices;
+      if (type.typeArguments.isNotEmpty) {
+        result.typeArguments = type.typeArguments
+            .map((DartType t) =>
+                _createLinkedType(t, compilationUnit, typeParameterContext))
+            .toList();
+      }
+      return result;
+    }
+    // TODO(paulberry): implement other cases.
+    throw new UnimplementedError('${element.runtimeType}');
+  }
+  // TODO(paulberry): implement other cases.
+  throw new UnimplementedError('${type.runtimeType}');
 }
 
 /**
@@ -123,10 +192,20 @@
  * during linking.
  */
 abstract class ClassElementForLink
-    implements ClassElement, ReferenceableElementForLink {
+    implements ClassElementImpl, ReferenceableElementForLink {
   Map<String, ReferenceableElementForLink> _containedNames;
 
   @override
+  final CompilationUnitElementForLink enclosingElement;
+
+  @override
+  bool hasBeenInferred;
+
+  ClassElementForLink(CompilationUnitElementForLink enclosingElement)
+      : enclosingElement = enclosingElement,
+        hasBeenInferred = !enclosingElement.isInBuildUnit;
+
+  @override
   ConstructorElementForLink get asConstructor => unnamedConstructor;
 
   @override
@@ -138,6 +217,13 @@
   }
 
   @override
+  DartType get asStaticType =>
+      enclosingElement.enclosingElement._linker.typeProvider.typeType;
+
+  @override
+  TypeInferenceNode get asTypeInferenceNode => null;
+
+  @override
   List<ConstructorElementForLink> get constructors;
 
   @override
@@ -149,6 +235,9 @@
   bool get isObject;
 
   @override
+  LibraryElementForLink get library => enclosingElement.library;
+
+  @override
   String get name;
 
   @override
@@ -177,9 +266,9 @@
 
   /**
    * Perform type inference and cycle detection on this class and
-   * store the resulting information in the enclosing elements.
+   * store the resulting information in [compilationUnit].
    */
-  void link(LinkedUnitBuilder linkedUnit);
+  void link(CompilationUnitElementInBuildUnit compilationUnit);
 
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@@ -190,24 +279,58 @@
  * linking.
  */
 class ClassElementForLink_Class extends ClassElementForLink
-    implements TypeParameterContext {
+    with TypeParameterizedElementForLink {
   /**
    * The unlinked representation of the class in the summary.
    */
   final UnlinkedClass _unlinkedClass;
 
-  @override
-  final CompilationUnitElementForLink enclosingElement;
-
   List<ConstructorElementForLink> _constructors;
   ConstructorElementForLink _unnamedConstructor;
   bool _unnamedConstructorComputed = false;
   List<FieldElementForLink_ClassField> _fields;
   InterfaceType _supertype;
   InterfaceType _type;
-  List<TypeParameterType> _typeParameterTypes;
+  List<MethodElementForLink> _methods;
+  List<InterfaceType> _mixins;
+  List<InterfaceType> _interfaces;
+  List<PropertyAccessorElementForLink> _accessors;
 
-  ClassElementForLink_Class(this.enclosingElement, this._unlinkedClass);
+  ClassElementForLink_Class(
+      CompilationUnitElementForLink enclosingElement, this._unlinkedClass)
+      : super(enclosingElement);
+
+  @override
+  List<PropertyAccessorElementForLink> get accessors {
+    if (_accessors == null) {
+      _accessors = <PropertyAccessorElementForLink>[];
+      Map<String, SyntheticVariableElementForLink> syntheticVariables =
+          <String, SyntheticVariableElementForLink>{};
+      for (UnlinkedExecutable unlinkedExecutable
+          in _unlinkedClass.executables) {
+        if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter ||
+            unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
+          String name = unlinkedExecutable.name;
+          if (unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
+            assert(name.endsWith('='));
+            name = name.substring(0, name.length - 1);
+          }
+          SyntheticVariableElementForLink syntheticVariable = syntheticVariables
+              .putIfAbsent(name, () => new SyntheticVariableElementForLink());
+          PropertyAccessorElementForLink accessor =
+              new PropertyAccessorElementForLink(
+                  this, unlinkedExecutable, syntheticVariable);
+          _accessors.add(accessor);
+          if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter) {
+            syntheticVariable._getter = accessor;
+          } else {
+            syntheticVariable._setter = accessor;
+          }
+        }
+      }
+    }
+    return _accessors;
+  }
 
   @override
   List<ConstructorElementForLink> get constructors {
@@ -228,6 +351,9 @@
   String get displayName => _unlinkedClass.name;
 
   @override
+  TypeParameterizedElementForLink get enclosingTypeParameterContext => null;
+
+  @override
   List<FieldElementForLink_ClassField> get fields {
     if (_fields == null) {
       _fields = <FieldElementForLink_ClassField>[];
@@ -239,9 +365,35 @@
   }
 
   @override
+  List<InterfaceType> get interfaces => _interfaces ??=
+      _unlinkedClass.interfaces.map(_computeInterfaceType).toList();
+
+  @override
   bool get isObject => _unlinkedClass.hasNoSupertype;
 
   @override
+  LibraryElementForLink get library => enclosingElement.library;
+
+  @override
+  List<MethodElementForLink> get methods {
+    if (_methods == null) {
+      _methods = <MethodElementForLink>[];
+      for (UnlinkedExecutable unlinkedExecutable
+          in _unlinkedClass.executables) {
+        if (unlinkedExecutable.kind ==
+            UnlinkedExecutableKind.functionOrMethod) {
+          _methods.add(new MethodElementForLink(this, unlinkedExecutable));
+        }
+      }
+    }
+    return _methods;
+  }
+
+  @override
+  List<InterfaceType> get mixins =>
+      _mixins ??= _unlinkedClass.mixins.map(_computeInterfaceType).toList();
+
+  @override
   String get name => _unlinkedClass.name;
 
   @override
@@ -249,22 +401,12 @@
     if (isObject) {
       return null;
     }
-    return _supertype ??= _computeSupertype();
+    return _supertype ??= _computeInterfaceType(_unlinkedClass.supertype);
   }
 
-  /**
-   * Get a list of [TypeParameterType] objects corresponding to the
-   * class's type parameters.
-   */
-  List<TypeParameterType> get typeParameterTypes {
-    if (_typeParameterTypes == null) {
-      _typeParameterTypes = _unlinkedClass.typeParameters
-          .map((UnlinkedTypeParam p) =>
-              new TypeParameterTypeImpl(new TypeParameterElementForLink(p)))
-          .toList();
-    }
-    return _typeParameterTypes;
-  }
+  @override
+  DartType get type =>
+      _type ??= buildType((int i) => typeParameterTypes[i], null);
 
   @override
   ConstructorElementForLink get unnamedConstructor {
@@ -281,41 +423,50 @@
   }
 
   @override
+  List<UnlinkedTypeParam> get _unlinkedTypeParams =>
+      _unlinkedClass.typeParameters;
+
+  @override
   DartType buildType(
       DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
     int numTypeParameters = _unlinkedClass.typeParameters.length;
     if (numTypeParameters != 0) {
-      return new InterfaceTypeImpl(this);
-    } else {
-      if (_type == null) {
-        List<DartType> typeArguments = new List<DartType>(numTypeParameters);
-        for (int i = 0; i < numTypeParameters; i++) {
-          typeArguments[i] = getTypeArgument(i);
-        }
-        _type = new InterfaceTypeImpl.elementWithNameAndArgs(
-            this, name, typeArguments);
+      List<DartType> typeArguments = new List<DartType>(numTypeParameters);
+      for (int i = 0; i < numTypeParameters; i++) {
+        typeArguments[i] = getTypeArgument(i);
       }
-      return _type;
+      return new InterfaceTypeImpl.elementWithNameAndArgs(
+          this, name, typeArguments);
+    } else {
+      return _type ??= new InterfaceTypeImpl(this);
     }
   }
 
   @override
-  TypeParameterType getTypeParameterType(int index) {
-    List<TypeParameterType> types = typeParameterTypes;
-    return types[types.length - index];
-  }
-
-  @override
-  void link(LinkedUnitBuilder linkedUnit) {
+  void link(CompilationUnitElementInBuildUnit compilationUnit) {
     for (ConstructorElementForLink constructorElement in constructors) {
-      constructorElement.link(linkedUnit);
+      constructorElement.link(compilationUnit);
+    }
+    if (compilationUnit.library._linker.strongMode) {
+      for (MethodElementForLink methodElement in methods) {
+        methodElement.link(compilationUnit);
+      }
+      for (PropertyAccessorElementForLink propertyAccessorElement
+          in accessors) {
+        propertyAccessorElement.link(compilationUnit);
+      }
+      for (FieldElementForLink_ClassField fieldElement in fields) {
+        fieldElement.link(compilationUnit);
+      }
     }
   }
 
-  InterfaceType _computeSupertype() {
+  /**
+   * Convert [typeRef] into an [InterfaceType].
+   */
+  InterfaceType _computeInterfaceType(EntityRef typeRef) {
     if (_unlinkedClass.supertype != null) {
-      DartType supertype =
-          enclosingElement._resolveTypeRef(_unlinkedClass.supertype, this);
+      DartType supertype = enclosingElement._resolveTypeRef(typeRef, this);
       if (supertype is InterfaceType) {
         return supertype;
       }
@@ -323,7 +474,7 @@
       // happen in the event of erroneous code) just fall through and pretend
       // the supertype is `Object`.
     }
-    return enclosingElement.enclosingElement._linker.objectType;
+    return enclosingElement.enclosingElement._linker.typeProvider.objectType;
   }
 }
 
@@ -340,7 +491,15 @@
   InterfaceType _type;
   List<FieldElementForLink_EnumField> _fields;
 
-  ClassElementForLink_Enum(this._unlinkedEnum);
+  ClassElementForLink_Enum(
+      CompilationUnitElementForLink enclosingElement, this._unlinkedEnum)
+      : super(enclosingElement);
+
+  @override
+  List<PropertyAccessorElement> get accessors {
+    // TODO(paulberry): do we need to include synthetic accessors?
+    return const [];
+  }
 
   @override
   List<ConstructorElementForLink> get constructors => const [];
@@ -361,12 +520,24 @@
   }
 
   @override
+  List<InterfaceType> get interfaces => const [];
+
+  @override
   bool get isObject => false;
 
   @override
+  List<MethodElement> get methods => const [];
+
+  @override
+  List<InterfaceType> get mixins => const [];
+
+  @override
   String get name => _unlinkedEnum.name;
 
   @override
+  InterfaceType get supertype => library._linker.typeProvider.objectType;
+
+  @override
   ConstructorElementForLink get unnamedConstructor => null;
 
   @override
@@ -375,7 +546,7 @@
       _type ??= new InterfaceTypeImpl(this);
 
   @override
-  void link(LinkedUnitBuilder linkedUnit) {}
+  void link(CompilationUnitElementInBuildUnit compilationUnit) {}
 }
 
 /**
@@ -396,25 +567,30 @@
   final List<ReferenceableElementForLink> _references;
 
   List<ClassElementForLink_Class> _types;
+
   Map<String, ReferenceableElementForLink> _containedNames;
   List<TopLevelVariableElementForLink> _topLevelVariables;
   List<ClassElementForLink_Enum> _enums;
 
-  @override
-  final LibraryElementForLink enclosingElement;
+  /**
+   * Index of this unit in the list of units in the enclosing library.
+   */
+  final int unitNum;
 
-  CompilationUnitElementForLink(
-      this.enclosingElement, UnlinkedUnit unlinkedUnit)
+  CompilationUnitElementForLink(UnlinkedUnit unlinkedUnit, this.unitNum)
       : _references = new List<ReferenceableElementForLink>(
             unlinkedUnit.references.length),
         _unlinkedUnit = unlinkedUnit;
 
   @override
+  LibraryElementForLink get enclosingElement;
+
+  @override
   List<ClassElementForLink_Enum> get enums {
     if (_enums == null) {
       _enums = <ClassElementForLink_Enum>[];
       for (UnlinkedEnum unlinkedEnum in _unlinkedUnit.enums) {
-        _enums.add(new ClassElementForLink_Enum(unlinkedEnum));
+        _enums.add(new ClassElementForLink_Enum(this, unlinkedEnum));
       }
     }
     return _enums;
@@ -427,6 +603,9 @@
   bool get isInBuildUnit;
 
   @override
+  LibraryElementForLink get library => enclosingElement;
+
+  @override
   List<TopLevelVariableElementForLink> get topLevelVariables {
     if (_topLevelVariables == null) {
       _topLevelVariables = <TopLevelVariableElementForLink>[];
@@ -517,7 +696,7 @@
    * unresolved type, for consistency with the full element model?
    */
   DartType _resolveTypeRef(
-      EntityRef type, TypeParameterContext typeParameterContext,
+      EntityRef type, TypeParameterizedElementForLink typeParameterContext,
       {bool defaultVoid: false}) {
     if (type == null) {
       if (defaultVoid) {
@@ -531,6 +710,9 @@
     } else if (type.syntheticReturnType != null) {
       // TODO(paulberry): implement.
       throw new UnimplementedError();
+    } else if (type.implicitFunctionTypeIndices.isNotEmpty) {
+      // TODO(paulberry): implement.
+      throw new UnimplementedError();
     } else {
       DartType getTypeArgument(int i) {
         if (i < type.typeArguments.length) {
@@ -554,44 +736,163 @@
   @override
   final LinkedUnitBuilder _linkedUnit;
 
-  CompilationUnitElementInBuildUnit(LibraryElementInBuildUnit libraryElement,
-      UnlinkedUnit unlinkedUnit, this._linkedUnit)
-      : super(libraryElement, unlinkedUnit);
+  @override
+  final LibraryElementInBuildUnit enclosingElement;
+
+  CompilationUnitElementInBuildUnit(this.enclosingElement,
+      UnlinkedUnit unlinkedUnit, this._linkedUnit, int unitNum)
+      : super(unlinkedUnit, unitNum);
 
   @override
   bool get isInBuildUnit => true;
 
+  @override
+  LibraryElementInBuildUnit get library => enclosingElement;
+
+  /**
+   * If this compilation unit already has a reference in its references table
+   * matching [dependency], [name], [numTypeParameters], [unitNum],
+   * [containingReference], and [kind], return its index.  Otherwise add a new reference to
+   * the table and return its index.
+   */
+  int addRawReference(String name,
+      {int dependency: 0,
+      int numTypeParameters: 0,
+      int unitNum: 0,
+      int containingReference: 0,
+      ReferenceKind kind: ReferenceKind.classOrEnum}) {
+    List<LinkedReferenceBuilder> linkedReferences = _linkedUnit.references;
+    List<UnlinkedReference> unlinkedReferences = _unlinkedUnit.references;
+    for (int i = 0; i < linkedReferences.length; i++) {
+      LinkedReferenceBuilder linkedReference = linkedReferences[i];
+      if (linkedReference.dependency == dependency &&
+          (i < unlinkedReferences.length
+                  ? unlinkedReferences[i].name
+                  : linkedReference.name) ==
+              name &&
+          linkedReference.numTypeParameters == numTypeParameters &&
+          linkedReference.unit == unitNum &&
+          (i < unlinkedReferences.length
+                  ? unlinkedReferences[i].prefixReference
+                  : linkedReference.containingReference) ==
+              containingReference &&
+          linkedReference.kind == kind) {
+        return i;
+      }
+    }
+    int result = linkedReferences.length;
+    linkedReferences.add(new LinkedReferenceBuilder(
+        dependency: dependency,
+        name: name,
+        numTypeParameters: numTypeParameters,
+        unit: unitNum,
+        containingReference: containingReference,
+        kind: kind));
+    return result;
+  }
+
+  /**
+   * If this compilation unit already has a reference in its references table
+   * to [element], return its index.  Otherwise add a new reference to the table
+   * and return its index.
+   */
+  int addReference(Element element) {
+    if (element is ClassElementForLink) {
+      return addRawReference(element.name,
+          dependency: library.addDependency(element.library),
+          numTypeParameters: element.typeParameters.length,
+          unitNum: element.enclosingElement.unitNum);
+    } else if (element is ExecutableElementForLink) {
+      // TODO(paulberry): will this code ever be executed for an executable
+      // element that's not inside a class?
+      assert(element.enclosingElement is ClassElementForLink_Class);
+      ReferenceKind kind;
+      switch (element._unlinkedExecutable.kind) {
+        case UnlinkedExecutableKind.functionOrMethod:
+          kind = ReferenceKind.method;
+          break;
+        case UnlinkedExecutableKind.setter:
+          kind = ReferenceKind.propertyAccessor;
+          break;
+        default:
+          // TODO(paulberry): implement other cases as necessary
+          throw new UnimplementedError('${element._unlinkedExecutable.kind}');
+      }
+      return addRawReference(element.name,
+          numTypeParameters: element.typeParameters.length,
+          containingReference: addReference(element.enclosingElement),
+          kind: kind);
+    }
+    // TODO(paulberry): implement other cases
+    throw new UnimplementedError('${element.runtimeType}');
+  }
+
   /**
    * Perform type inference and const cycle detection on this
    * compilation unit.
    */
   void link() {
+    if (library._linker.strongMode) {
+      new InstanceMemberInferrer(enclosingElement._linker.typeProvider,
+              enclosingElement.inheritanceManager)
+          .inferCompilationUnit(this);
+    }
     for (ClassElementForLink classElement in types) {
-      classElement.link(_linkedUnit);
+      classElement.link(this);
     }
   }
 
   /**
-   * Throw away any information produced by a previous call to [link].
+   * Throw away any information stored in the summary by a previous call to
+   * [link].
    */
   void unlink() {
     _linkedUnit.constCycles.clear();
     _linkedUnit.references.length = _unlinkedUnit.references.length;
     _linkedUnit.types.clear();
   }
+
+  /**
+   * Store the fact that the given [slot] represents a constant constructor
+   * that is part of a cycle.
+   */
+  void _storeConstCycle(int slot) {
+    _linkedUnit.constCycles.add(slot);
+  }
+
+  /**
+   * Store the given [linkedType] in the given [slot] of the this compilation
+   * unit's linked type list.
+   */
+  void _storeLinkedType(int slot, DartType linkedType,
+      TypeParameterizedElementForLink typeParameterContext) {
+    if (slot != 0) {
+      if (linkedType != null && !linkedType.isDynamic) {
+        _linkedUnit.types.add(_createLinkedType(
+            linkedType, this, typeParameterContext,
+            slot: slot));
+      }
+    }
+  }
 }
 
 /**
  * Element representing a compilation unit which is depended upon
  * (either directly or indirectly) by the build unit being linked.
+ *
+ * TODO(paulberry): ensure that inferred types in dependencies are properly
+ * resynthesized.
  */
 class CompilationUnitElementInDependency extends CompilationUnitElementForLink {
   @override
   final LinkedUnit _linkedUnit;
 
-  CompilationUnitElementInDependency(LibraryElementInDependency libraryElement,
-      UnlinkedUnit unlinkedUnit, this._linkedUnit)
-      : super(libraryElement, unlinkedUnit);
+  @override
+  final LibraryElementInDependency enclosingElement;
+
+  CompilationUnitElementInDependency(this.enclosingElement,
+      UnlinkedUnit unlinkedUnit, this._linkedUnit, int unitNum)
+      : super(unlinkedUnit, unitNum);
 
   @override
   bool get isInBuildUnit => false;
@@ -817,13 +1118,8 @@
  * Element representing a constructor resynthesized from a summary
  * during linking.
  */
-class ConstructorElementForLink
-    implements ConstructorElement, ReferenceableElementForLink {
-  /**
-   * The unlinked representation of the constructor in the summary.
-   */
-  final UnlinkedExecutable _unlinkedExecutable;
-
+class ConstructorElementForLink extends ExecutableElementForLink
+    implements ConstructorElementImpl, ReferenceableElementForLink {
   /**
    * If this is a `const` constructor and the enclosing library is
    * part of the build unit being linked, the constructor's node in
@@ -831,12 +1127,9 @@
    */
   ConstConstructorNode _constNode;
 
-  @override
-  final ClassElementForLink_Class enclosingElement;
-
-  List<ParameterElementForLink> _parameters;
-
-  ConstructorElementForLink(this.enclosingElement, this._unlinkedExecutable) {
+  ConstructorElementForLink(ClassElementForLink_Class enclosingElement,
+      UnlinkedExecutable unlinkedExecutable)
+      : super(enclosingElement, unlinkedExecutable) {
     if (enclosingElement.enclosingElement.isInBuildUnit &&
         _unlinkedExecutable.constCycleSlot != 0) {
       _constNode = new ConstConstructorNode(this);
@@ -850,6 +1143,16 @@
   ConstVariableNode get asConstVariable => null;
 
   @override
+  DartType get asStaticType {
+    // Referring to a constructor directly is an error, so just use
+    // `dynamic`.
+    return DynamicTypeImpl.instance;
+  }
+
+  @override
+  TypeInferenceNode get asTypeInferenceNode => null;
+
+  @override
   bool get isCycleFree {
     if (!_constNode.isEvaluated) {
       new ConstDependencyWalker().walk(_constNode);
@@ -858,21 +1161,6 @@
   }
 
   @override
-  String get name => _unlinkedExecutable.name;
-
-  @override
-  List<ParameterElementForLink> get parameters {
-    if (_parameters == null) {
-      _parameters = <ParameterElementForLink>[];
-      for (UnlinkedParam unlinkedParam in _unlinkedExecutable.parameters) {
-        _parameters.add(new ParameterElementForLink(
-            unlinkedParam, enclosingElement.enclosingElement));
-      }
-    }
-    return _parameters;
-  }
-
-  @override
   DartType buildType(DartType getTypeArgument(int i),
           List<int> implicitFunctionTypeIndices) =>
       DynamicTypeImpl.instance;
@@ -884,10 +1172,11 @@
   /**
    * Perform const cycle detection on this constructor.
    */
-  void link(LinkedUnitBuilder linkedUnit) {
+  void link(CompilationUnitElementInBuildUnit compilationUnit) {
     if (_constNode != null && !isCycleFree) {
-      linkedUnit.constCycles.add(_unlinkedExecutable.constCycleSlot);
+      compilationUnit._storeConstCycle(_unlinkedExecutable.constCycleSlot);
     }
+    // TODO(paulberry): call super.
   }
 
   @override
@@ -1045,6 +1334,119 @@
 }
 
 /**
+ * Base class for executable elements resynthesized from a summary during
+ * linking.
+ */
+abstract class ExecutableElementForLink extends Object
+    with TypeParameterizedElementForLink
+    implements ExecutableElementImpl {
+  /**
+   * The unlinked representation of the method in the summary.
+   */
+  final UnlinkedExecutable _unlinkedExecutable;
+
+  DartType _declaredReturnType;
+  DartType _inferredReturnType;
+  FunctionTypeImpl _type;
+  List<TypeParameterElementForLink> _typeParameters;
+  List<ParameterElementForLink> _parameters;
+
+  /**
+   * TODO(paulberry): this won't always be a class element.
+   */
+  @override
+  final ClassElementForLink_Class enclosingElement;
+
+  ExecutableElementForLink(this.enclosingElement, this._unlinkedExecutable);
+
+  @override
+  TypeParameterizedElementForLink get enclosingTypeParameterContext =>
+      enclosingElement;
+
+  @override
+  bool get hasImplicitReturnType => _unlinkedExecutable.returnType == null;
+
+  @override
+  bool get isStatic => _unlinkedExecutable.isStatic;
+
+  @override
+  bool get isSynthetic => false;
+
+  @override
+  LibraryElementForLink get library => enclosingElement.library;
+
+  @override
+  String get name => _unlinkedExecutable.name;
+
+  @override
+  List<ParameterElementForLink> get parameters {
+    if (_parameters == null) {
+      int numParameters = _unlinkedExecutable.parameters.length;
+      _parameters = new List<ParameterElementForLink>(numParameters);
+      for (int i = 0; i < numParameters; i++) {
+        UnlinkedParam unlinkedParam = _unlinkedExecutable.parameters[i];
+        _parameters[i] = new ParameterElementForLink(
+            this, unlinkedParam, this, enclosingElement.enclosingElement, i);
+      }
+    }
+    return _parameters;
+  }
+
+  @override
+  DartType get returnType {
+    if (_inferredReturnType != null) {
+      return _inferredReturnType;
+    } else if (_declaredReturnType == null) {
+      if (_unlinkedExecutable.returnType == null) {
+        if (_unlinkedExecutable.kind == UnlinkedExecutableKind.constructor) {
+          // TODO(paulberry): implement.
+          throw new UnimplementedError();
+        } else if (_unlinkedExecutable.kind == UnlinkedExecutableKind.setter &&
+            library._linker.strongMode) {
+          // In strong mode, setters without an explicit return type are
+          // considered to return `void`.
+          _declaredReturnType = VoidTypeImpl.instance;
+        } else {
+          _declaredReturnType = DynamicTypeImpl.instance;
+        }
+      } else {
+        _declaredReturnType = enclosingElement.enclosingElement
+            ._resolveTypeRef(_unlinkedExecutable.returnType, this);
+      }
+    }
+    return _declaredReturnType;
+  }
+
+  @override
+  void set returnType(DartType inferredType) {
+    assert(_inferredReturnType == null);
+    _inferredReturnType = inferredType;
+  }
+
+  @override
+  FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
+
+  @override
+  List<UnlinkedTypeParam> get _unlinkedTypeParams =>
+      _unlinkedExecutable.typeParameters;
+
+  @override
+  bool isAccessibleIn(LibraryElement library) =>
+      !Identifier.isPrivateName(name) || identical(this.library, library);
+
+  /**
+   * Store the results of type inference for this method in [compilationUnit].
+   */
+  void link(CompilationUnitElementInBuildUnit compilationUnit) {
+    compilationUnit._storeLinkedType(
+        _unlinkedExecutable.inferredReturnTypeSlot, returnType, this);
+    for (ParameterElementForLink parameterElement in parameters) {
+      parameterElement.link(compilationUnit);
+    }
+  }
+}
+
+/**
  * Element representing a field resynthesized from a summary during
  * linking.
  */
@@ -1059,6 +1461,14 @@
   @override
   final ClassElementForLink_Class enclosingElement;
 
+  /**
+   * If this is an instance field, the type that was computed by
+   * [InstanceMemberInferrer].
+   */
+  DartType _inferredInstanceType;
+
+  DartType _declaredType;
+
   FieldElementForLink_ClassField(ClassElementForLink_Class enclosingElement,
       UnlinkedVariable unlinkedVariable)
       : enclosingElement = enclosingElement,
@@ -1066,6 +1476,48 @@
 
   @override
   bool get isStatic => unlinkedVariable.isStatic;
+
+  @override
+  DartType get type {
+    assert(!isStatic);
+    if (_inferredInstanceType != null) {
+      return _inferredInstanceType;
+    } else if (_declaredType == null) {
+      if (unlinkedVariable.type == null) {
+        _declaredType = DynamicTypeImpl.instance;
+      } else {
+        _declaredType = compilationUnit._resolveTypeRef(
+            unlinkedVariable.type, enclosingElement);
+      }
+    }
+    return _declaredType;
+  }
+
+  @override
+  void set type(DartType inferredType) {
+    assert(!isStatic);
+    assert(_inferredInstanceType == null);
+    _inferredInstanceType = inferredType;
+  }
+
+  /**
+   * Store the results of type inference for this field in
+   * [compilationUnit].
+   */
+  void link(CompilationUnitElementInBuildUnit compilationUnit) {
+    if (hasImplicitType) {
+      if (isStatic) {
+        TypeInferenceNode typeInferenceNode = this.asTypeInferenceNode;
+        if (typeInferenceNode != null) {
+          compilationUnit._storeLinkedType(unlinkedVariable.inferredTypeSlot,
+              typeInferenceNode.inferredType, enclosingElement);
+        }
+      } else {
+        compilationUnit._storeLinkedType(unlinkedVariable.inferredTypeSlot,
+            _inferredInstanceType, enclosingElement);
+      }
+    }
+  }
 }
 
 /**
@@ -1093,9 +1545,21 @@
   }
 
   @override
+  DartType get asStaticType {
+    // TODO(paulberry): implement.
+    throw new UnimplementedError();
+  }
+
+  @override
+  TypeInferenceNode get asTypeInferenceNode => null;
+
+  @override
   bool get isStatic => true;
 
   @override
+  bool get isSynthetic => false;
+
+  @override
   String get name =>
       unlinkedEnumValue == null ? 'values' : unlinkedEnumValue.name;
 
@@ -1113,6 +1577,104 @@
 }
 
 /**
+ * Element representing a function-typed parameter resynthesied from a summary
+ * during linking.
+ */
+class FunctionElementForLink_FunctionTypedParam implements FunctionElement {
+  @override
+  final ParameterElementForLink enclosingElement;
+
+  /**
+   * The executable element containing this function-typed parameter.
+   */
+  final Element enclosingExecutable;
+
+  /**
+   * The appropriate integer list to store in
+   * [EntityRef.implicitFunctionTypeIndices] to refer to this function-typed
+   * parameter.
+   */
+  final List<int> implicitFunctionTypeIndices;
+
+  DartType _returnType;
+
+  FunctionElementForLink_FunctionTypedParam(this.enclosingElement,
+      this.enclosingExecutable, this.implicitFunctionTypeIndices);
+
+  @override
+  DartType get returnType {
+    if (_returnType == null) {
+      if (enclosingElement._unlinkedParam.type == null) {
+        _returnType = DynamicTypeImpl.instance;
+      } else {
+        _returnType = enclosingElement.compilationUnit._resolveTypeRef(
+            enclosingElement._unlinkedParam.type,
+            enclosingElement._typeParameterContext);
+      }
+    }
+    return _returnType;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => const [];
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
+ * Element representing the initializer expression of a variable.
+ */
+class FunctionElementForLink_Initializer implements FunctionElementImpl {
+  /**
+   * The variable for which this element is the initializer.
+   */
+  final VariableElementForLink _variable;
+
+  FunctionElementForLink_Initializer(this._variable);
+
+  @override
+  DartType get returnType {
+    // If this is a variable whose type needs inferring, infer it.
+    TypeInferenceNode typeInferenceNode = _variable._typeInferenceNode;
+    if (typeInferenceNode != null) {
+      return typeInferenceNode.inferredType;
+    } else {
+      // There's no reason linking should need to access the type of
+      // this FunctionElement, since the variable doesn't need its
+      // type inferred.
+      assert(false);
+      // But for robustness, return the dynamic type.
+      return DynamicTypeImpl.instance;
+    }
+  }
+
+  @override
+  void set returnType(DartType newType) {
+    // TODO(paulberry): store inferred type.
+  }
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
+ * An instance of [LibraryCycleForLink] represents a single library cycle
+ * discovered during linking; it consists of one or more libraries in the build
+ * unit being linked.
+ *
+ * This is a stub implementation; at the moment all libraries in the build unit
+ * being linked are considered to be part of the same library cycle.  Hence
+ * there is just a singleton instance of this class.
+ * TODO(paulberry): replace this with a correct implementation.
+ */
+class LibraryCycleForLink {
+  static final LibraryCycleForLink instance = const LibraryCycleForLink._();
+
+  const LibraryCycleForLink._();
+}
+
+/**
  * Element representing a library resynthesied from a summary during
  * linking.  The type parameter, [UnitElement], represents the type
  * that will be used for the compilation unit elements.
@@ -1134,15 +1696,31 @@
   final Map<String, ReferenceableElementForLink> _containedNames =
       <String, ReferenceableElementForLink>{};
   final List<LibraryElementForLink> _dependencies = <LibraryElementForLink>[];
+  UnlinkedUnit _definingUnlinkedUnit;
 
   LibraryElementForLink(this._linker, this._absoluteUri) {
     _dependencies.length = _linkedLibrary.dependencies.length;
   }
 
+  /**
+   * Get the [UnlinkedUnit] for the defining compilation unit of this library.
+   */
+  UnlinkedUnit get definingUnlinkedUnit =>
+      _definingUnlinkedUnit ??= _linker.getUnit(_absoluteUri.toString());
+
+  @override
+  Element get enclosingElement => null;
+
+  /**
+   * If this library is part of the build unit being linked, return the library
+   * cycle it is part of.  Otherwise return `null`.
+   */
+  LibraryCycleForLink get libraryCycleForLink;
+
   @override
   List<UnitElement> get units {
     if (_units == null) {
-      UnlinkedUnit definingUnit = _linker.getUnit(_absoluteUri.toString());
+      UnlinkedUnit definingUnit = definingUnlinkedUnit;
       _units = <UnitElement>[_makeUnitElement(definingUnit, 0)];
       int numParts = definingUnit.parts.length;
       for (int i = 0; i < numParts; i++) {
@@ -1169,7 +1747,7 @@
    * [name].  If no name is found, return the singleton instance of
    * [UndefinedElementForLink].
    */
-  ReferenceableElementForLink getContainedName(name) =>
+  ReferenceableElementForLink getContainedName(String name) =>
       _containedNames.putIfAbsent(name, () {
         for (UnitElement unit in units) {
           ReferenceableElementForLink element = unit.getContainedName(name);
@@ -1207,11 +1785,41 @@
   @override
   final LinkedLibraryBuilder _linkedLibrary;
 
+  InheritanceManager _inheritanceManager;
+
   LibraryElementInBuildUnit(
       _Linker linker, Uri absoluteUri, this._linkedLibrary)
       : super(linker, absoluteUri);
 
   /**
+   * Get the inheritance manager for this library (creating it if necessary).
+   */
+  InheritanceManager get inheritanceManager =>
+      _inheritanceManager ??= new InheritanceManager(this);
+
+  @override
+  LibraryCycleForLink get libraryCycleForLink => LibraryCycleForLink.instance;
+
+  /**
+   * If this library already has a dependency in its dependencies table matching
+   * [library], return its index.  Otherwise add a new dependency to table and
+   * return its index.
+   */
+  int addDependency(LibraryElementForLink library) {
+    for (int i = 0; i < _linkedLibrary.dependencies.length; i++) {
+      if (identical(_getDependency(i), library)) {
+        return i;
+      }
+    }
+    int result = _linkedLibrary.dependencies.length;
+    _linkedLibrary.dependencies.add(new LinkedDependencyBuilder(
+        parts: library.definingUnlinkedUnit.publicNamespace.parts,
+        uri: library._absoluteUri.toString()));
+    _dependencies.add(library);
+    return result;
+  }
+
+  /**
    * Perform type inference and const cycle detection on this library.
    */
   void link() {
@@ -1221,13 +1829,14 @@
   }
 
   /**
-   * Throw away any information produced by a previous call to [link].
+   * Throw away any information stored in the summary by a previous call to
+   * [link].
    */
   void unlink() {
     _linkedLibrary.dependencies.length =
         _linkedLibrary.numPrelinkedDependencies;
     for (CompilationUnitElementInBuildUnit unit in units) {
-      unit.link();
+      unit.unlink();
     }
   }
 
@@ -1235,7 +1844,7 @@
   CompilationUnitElementInBuildUnit _makeUnitElement(
           UnlinkedUnit unlinkedUnit, int i) =>
       new CompilationUnitElementInBuildUnit(
-          this, unlinkedUnit, _linkedLibrary.units[i]);
+          this, unlinkedUnit, _linkedLibrary.units[i], i);
 }
 
 /**
@@ -1252,10 +1861,29 @@
       : super(linker, absoluteUri);
 
   @override
+  LibraryCycleForLink get libraryCycleForLink => null;
+
+  @override
   CompilationUnitElementInDependency _makeUnitElement(
           UnlinkedUnit unlinkedUnit, int i) =>
       new CompilationUnitElementInDependency(
-          this, unlinkedUnit, _linkedLibrary.units[i]);
+          this, unlinkedUnit, _linkedLibrary.units[i], i);
+}
+
+/**
+ * Element representing a method resynthesized from a summary during linking.
+ */
+class MethodElementForLink extends ExecutableElementForLink
+    implements MethodElementImpl {
+  MethodElementForLink(ClassElementForLink_Class enclosingElement,
+      UnlinkedExecutable unlinkedExecutable)
+      : super(enclosingElement, unlinkedExecutable);
+
+  @override
+  ElementKind get kind => ElementKind.METHOD;
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 /**
@@ -1318,6 +1946,18 @@
   ConstVariableNode get asConstVariable => _constNode;
 
   @override
+  DartType get asStaticType {
+    // TODO(paulberry): implement.
+    throw new UnimplementedError();
+  }
+
+  @override
+  TypeInferenceNode get asTypeInferenceNode {
+    // TODO(paulberry): implement.
+    throw new UnimplementedError();
+  }
+
+  @override
   DartType buildType(DartType getTypeArgument(int i),
           List<int> implicitFunctionTypeIndices) =>
       DynamicTypeImpl.instance;
@@ -1330,13 +1970,18 @@
  * Element representing a function or method parameter resynthesized
  * from a summary during linking.
  */
-class ParameterElementForLink implements ParameterElement {
+class ParameterElementForLink implements ParameterElementImpl {
   /**
    * The unlinked representation of the parameter in the summary.
    */
   final UnlinkedParam _unlinkedParam;
 
   /**
+   * The context in which type parameters should be interpreted.
+   */
+  final TypeParameterizedElementForLink _typeParameterContext;
+
+  /**
    * If this parameter has a default value and the enclosing library
    * is part of the build unit being linked, the parameter's node in
    * the constant evaluation dependency graph.  Otherwise `null`.
@@ -1348,13 +1993,111 @@
    */
   final CompilationUnitElementForLink compilationUnit;
 
-  ParameterElementForLink(this._unlinkedParam, this.compilationUnit) {
+  /**
+   * The index of this parameter within [enclosingElement]'s parameter list.
+   */
+  final int _parameterIndex;
+
+  @override
+  final ExecutableElementForLink enclosingElement;
+
+  DartType _inferredType;
+  DartType _declaredType;
+
+  ParameterElementForLink(this.enclosingElement, this._unlinkedParam,
+      this._typeParameterContext, this.compilationUnit, this._parameterIndex) {
     if (_unlinkedParam.defaultValue != null) {
       _constNode = new ConstParameterNode(this);
     }
   }
 
   @override
+  bool get hasImplicitType =>
+      !_unlinkedParam.isFunctionTyped && _unlinkedParam.type == null;
+
+  @override
+  String get name => _unlinkedParam.name;
+
+  @override
+  ParameterKind get parameterKind {
+    switch (_unlinkedParam.kind) {
+      case UnlinkedParamKind.required:
+        return ParameterKind.REQUIRED;
+      case UnlinkedParamKind.positional:
+        return ParameterKind.POSITIONAL;
+      case UnlinkedParamKind.named:
+        return ParameterKind.NAMED;
+    }
+  }
+
+  @override
+  DartType get type {
+    if (_inferredType != null) {
+      return _inferredType;
+    } else if (_declaredType == null) {
+      if (_unlinkedParam.isFunctionTyped) {
+        // TODO(paulberry): implement.
+        _declaredType = new FunctionTypeImpl(
+            new FunctionElementForLink_FunctionTypedParam(
+                this, enclosingElement, <int>[_parameterIndex]));
+      } else if (_unlinkedParam.type == null) {
+        _declaredType = DynamicTypeImpl.instance;
+      } else {
+        _declaredType = compilationUnit._resolveTypeRef(
+            _unlinkedParam.type, _typeParameterContext);
+      }
+    }
+    return _declaredType;
+  }
+
+  @override
+  void set type(DartType inferredType) {
+    assert(_inferredType == null);
+    _inferredType = inferredType;
+  }
+
+  /**
+   * Store the results of type inference for this parameter in
+   * [compilationUnit].
+   */
+  void link(CompilationUnitElementInBuildUnit compilationUnit) {
+    compilationUnit._storeLinkedType(
+        _unlinkedParam.inferredTypeSlot, _inferredType, _typeParameterContext);
+  }
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
+ * Element representing a getter or setter resynthesized from a summary during
+ * linking.
+ */
+class PropertyAccessorElementForLink extends ExecutableElementForLink
+    implements PropertyAccessorElementImpl {
+  @override
+  SyntheticVariableElementForLink variable;
+
+  PropertyAccessorElementForLink(ClassElementForLink_Class enclosingElement,
+      UnlinkedExecutable unlinkedExecutable, this.variable)
+      : super(enclosingElement, unlinkedExecutable);
+
+  @override
+  PropertyAccessorElementForLink get correspondingGetter => variable.getter;
+
+  @override
+  bool get isGetter =>
+      _unlinkedExecutable.kind == UnlinkedExecutableKind.getter;
+
+  @override
+  bool get isSetter =>
+      _unlinkedExecutable.kind == UnlinkedExecutableKind.setter;
+
+  @override
+  ElementKind get kind => _unlinkedExecutable.kind ==
+      UnlinkedExecutableKind.getter ? ElementKind.GETTER : ElementKind.SETTER;
+
+  @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
@@ -1378,6 +2121,18 @@
   ConstVariableNode get asConstVariable;
 
   /**
+   * Return the static type of the entity referred to by thi element.
+   */
+  DartType get asStaticType;
+
+  /**
+   * If this element can be used in a getter context as a type inference
+   * dependency, return the [TypeInferenceNode] for the inferred type.
+   * Otherwise return `null`.
+   */
+  TypeInferenceNode get asTypeInferenceNode;
+
+  /**
    * Return the type indicated by this element when it is used in a
    * type instantiation context.  If this element can't legally be
    * instantiated as a type, return the dynamic type.
@@ -1396,6 +2151,27 @@
 }
 
 /**
+ * Element representing a synthetic variable resynthesized from a summary during
+ * linking.
+ */
+class SyntheticVariableElementForLink implements PropertyInducingElementImpl {
+  PropertyAccessorElementForLink _getter;
+  PropertyAccessorElementForLink _setter;
+
+  @override
+  PropertyAccessorElementForLink get getter => _getter;
+
+  @override
+  PropertyAccessorElementForLink get setter => _setter;
+
+  @override
+  void set type(DartType inferredType) {}
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
  * Element representing a top level variable resynthesized from a
  * summary during linking.
  */
@@ -1410,14 +2186,191 @@
 }
 
 /**
- * Interface representing elements which can serve as the context within which
- * type parameter indices are interpreted.
+ * Specialization of [DependencyWalker] for performing type inferrence
+ * on static and top level variables.
  */
-abstract class TypeParameterContext {
+class TypeInferenceDependencyWalker
+    extends DependencyWalker<TypeInferenceNode> {
+  @override
+  void evaluate(TypeInferenceNode v) {
+    v.evaluate(false);
+  }
+
+  @override
+  void evaluateScc(List<TypeInferenceNode> scc) {
+    for (TypeInferenceNode v in scc) {
+      v.evaluate(true);
+    }
+  }
+}
+
+/**
+ * Specialization of [Node] used to construct the type inference dependency
+ * graph.
+ */
+class TypeInferenceNode extends Node<TypeInferenceNode> {
   /**
-   * Convert the given [index] into a type parameter type.
+   * The [FieldElement] or [TopLevelVariableElement] to which this
+   * node refers.
    */
-  TypeParameterType getTypeParameterType(int index);
+  final VariableElementForLink variableElement;
+
+  /**
+   * If a type has been inferred for this node, the inferred type (may be
+   * `dynamic`).  Otherwise `null`.
+   */
+  DartType _inferredType;
+
+  TypeInferenceNode(this.variableElement);
+
+  /**
+   * Infer a type for this node if necessary, and return it.
+   */
+  DartType get inferredType {
+    if (_inferredType == null) {
+      new TypeInferenceDependencyWalker().walk(this);
+      assert(_inferredType != null);
+    }
+    return _inferredType;
+  }
+
+  @override
+  bool get isEvaluated => _inferredType != null;
+
+  /**
+   * Collect the type inference dependencies in [unlinkedConst] (which should be
+   * interpreted relative to [compilationUnit]) and store them in
+   * [dependencies].
+   */
+  void collectDependencies(
+      List<TypeInferenceNode> dependencies,
+      UnlinkedConst unlinkedConst,
+      CompilationUnitElementForLink compilationUnit) {
+    if (unlinkedConst == null) {
+      return;
+    }
+    int refPtr = 0;
+    for (UnlinkedConstOperation operation in unlinkedConst.operations) {
+      switch (operation) {
+        case UnlinkedConstOperation.pushReference:
+          EntityRef ref = unlinkedConst.references[refPtr++];
+          // TODO(paulberry): cache these resolved references for
+          // later use by evaluate().
+          TypeInferenceNode dependency =
+              compilationUnit._resolveRef(ref.reference).asTypeInferenceNode;
+          if (dependency != null) {
+            dependencies.add(dependency);
+          }
+          break;
+        case UnlinkedConstOperation.makeTypedList:
+        case UnlinkedConstOperation.invokeConstructor:
+          refPtr++;
+          break;
+        case UnlinkedConstOperation.makeTypedMap:
+          refPtr += 2;
+          break;
+        default:
+          break;
+      }
+    }
+    assert(refPtr == unlinkedConst.references.length);
+  }
+
+  @override
+  List<TypeInferenceNode> computeDependencies() {
+    List<TypeInferenceNode> dependencies = <TypeInferenceNode>[];
+    collectDependencies(
+        dependencies,
+        variableElement.unlinkedVariable.constExpr,
+        variableElement.compilationUnit);
+    return dependencies;
+  }
+
+  @override
+  void evaluate(bool inCycle) {
+    if (inCycle) {
+      _inferredType = DynamicTypeImpl.instance;
+    } else if (!variableElement.unlinkedVariable.constExpr.isValidConst) {
+      // TODO(paulberry): delete this case and fix errors.
+      throw new UnimplementedError();
+    } else {
+      // Perform RPN evaluation of the cycle, using a stack of
+      // inferred types.
+      List<DartType> stack = <DartType>[];
+      int refPtr = 0;
+      int intPtr = 0;
+      UnlinkedConst unlinkedConst = variableElement.unlinkedVariable.constExpr;
+      TypeProvider typeProvider =
+          variableElement.compilationUnit.enclosingElement._linker.typeProvider;
+      for (UnlinkedConstOperation operation in unlinkedConst.operations) {
+        switch (operation) {
+          case UnlinkedConstOperation.pushInt:
+            intPtr++;
+            stack.add(typeProvider.intType);
+            break;
+          case UnlinkedConstOperation.pushNull:
+            stack.add(BottomTypeImpl.instance);
+            break;
+          case UnlinkedConstOperation.pushReference:
+            EntityRef ref = unlinkedConst.references[refPtr++];
+            if (ref.paramReference != 0) {
+              stack.add(typeProvider.typeType);
+            } else {
+              // Synthetic function types can't be directly referred
+              // to by expressions.
+              assert(ref.syntheticReturnType == null);
+              // Nor can implicit function types derived from
+              // function-typed parameters.
+              assert(ref.implicitFunctionTypeIndices.isEmpty);
+              ReferenceableElementForLink element =
+                  variableElement.compilationUnit._resolveRef(ref.reference);
+              TypeInferenceNode typeInferenceNode = element.asTypeInferenceNode;
+              if (typeInferenceNode != null) {
+                assert(typeInferenceNode.isEvaluated);
+                stack.add(typeInferenceNode._inferredType);
+              } else {
+                stack.add(element.asStaticType);
+              }
+            }
+            break;
+          case UnlinkedConstOperation.makeTypedList:
+            refPtr++;
+            stack.length -= unlinkedConst.ints[intPtr++];
+            // TODO(paulberry): implement.
+            stack.add(DynamicTypeImpl.instance);
+            break;
+          case UnlinkedConstOperation.makeTypedMap:
+            refPtr += 2;
+            // TODO(paulberry): implement.
+            throw new UnimplementedError('$operation');
+          case UnlinkedConstOperation.invokeConstructor:
+            // TODO(paulberry): don't just pop the args; use their types
+            // to infer the type of type arguments.
+            stack.length -=
+                unlinkedConst.ints[intPtr++] + unlinkedConst.ints[intPtr++];
+            EntityRef ref = unlinkedConst.references[refPtr++];
+            ConstructorElementForLink element = variableElement.compilationUnit
+                ._resolveRef(ref.reference)
+                .asConstructor;
+            if (ref.typeArguments.isNotEmpty) {
+              // TODO(paulberry): handle type arguments
+              throw new UnimplementedError();
+            }
+            // TODO(paulberry): do we have to follow constructor
+            // redirections?
+            stack.add(element.enclosingElement.type);
+            break;
+          default:
+            // TODO(paulberry): implement.
+            throw new UnimplementedError('$operation');
+        }
+      }
+      assert(refPtr == unlinkedConst.references.length);
+      assert(intPtr == unlinkedConst.ints.length);
+      assert(stack.length == 1);
+      _inferredType = stack[0];
+    }
+  }
 }
 
 /**
@@ -1430,16 +2383,244 @@
    */
   final UnlinkedTypeParam _unlinkedTypeParam;
 
-  TypeParameterElementForLink(this._unlinkedTypeParam);
+  /**
+   * The number of type parameters whose scope overlaps this one, and which are
+   * declared earlier in the file.
+   */
+  final int nestingLevel;
+
+  TypeParameterTypeImpl _type;
+
+  TypeParameterElementForLink(this._unlinkedTypeParam, this.nestingLevel);
 
   @override
   String get name => _unlinkedTypeParam.name;
 
   @override
+  TypeParameterTypeImpl get type => _type ??= new TypeParameterTypeImpl(this);
+
+  @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 /**
+ * Mixin representing an element which can have type parameters.
+ */
+abstract class TypeParameterizedElementForLink
+    implements TypeParameterizedElement {
+  List<TypeParameterType> _typeParameterTypes;
+  List<TypeParameterElementForLink> _typeParameters;
+  int _nestingLevel;
+
+  /**
+   * Get the type parameter context enclosing this one, if any.
+   */
+  TypeParameterizedElementForLink get enclosingTypeParameterContext;
+
+  /**
+   * Find out how many type parameters are in scope in this context.
+   */
+  int get typeParameterNestingLevel =>
+      _nestingLevel ??= _unlinkedTypeParams.length +
+          (enclosingTypeParameterContext?.typeParameterNestingLevel ?? 0);
+
+  List<TypeParameterElementForLink> get typeParameters {
+    if (_typeParameters == null) {
+      int enclosingNestingLevel =
+          enclosingTypeParameterContext?.typeParameterNestingLevel ?? 0;
+      int numTypeParameters = _unlinkedTypeParams.length;
+      _typeParameters =
+          new List<TypeParameterElementForLink>(numTypeParameters);
+      for (int i = 0; i < numTypeParameters; i++) {
+        _typeParameters[i] = new TypeParameterElementForLink(
+            _unlinkedTypeParams[i], enclosingNestingLevel + i);
+      }
+    }
+    return _typeParameters;
+  }
+
+  /**
+   * Get a list of [TypeParameterType] objects corresponding to the
+   * element's type parameters.
+   */
+  List<TypeParameterType> get typeParameterTypes {
+    if (_typeParameterTypes == null) {
+      _typeParameterTypes = typeParameters
+          .map((TypeParameterElementForLink e) => e.type)
+          .toList();
+    }
+    return _typeParameterTypes;
+  }
+
+  /**
+   * Get the [UnlinkedTypeParam]s representing the type parameters declared by
+   * this element.
+   */
+  List<UnlinkedTypeParam> get _unlinkedTypeParams;
+
+  /**
+   * Convert the given [index] into a type parameter type.
+   */
+  TypeParameterType getTypeParameterType(int index) {
+    List<TypeParameterType> types = typeParameterTypes;
+    if (index <= types.length) {
+      return types[types.length - index];
+    } else if (enclosingTypeParameterContext != null) {
+      return enclosingTypeParameterContext
+          .getTypeParameterType(index - types.length);
+    } else {
+      // If we get here, it means that a summary contained a type parameter index
+      // that was out of range.
+      throw new RangeError('Invalid type parameter index');
+    }
+  }
+}
+
+class TypeProviderForLink implements TypeProvider {
+  final _Linker _linker;
+
+  InterfaceType _boolType;
+  InterfaceType _deprecatedType;
+  InterfaceType _doubleType;
+  InterfaceType _functionType;
+  InterfaceType _futureDynamicType;
+  InterfaceType _futureNullType;
+  InterfaceType _futureType;
+  InterfaceType _intType;
+  InterfaceType _iterableDynamicType;
+  InterfaceType _iterableType;
+  InterfaceType _listType;
+  InterfaceType _mapType;
+  InterfaceType _nullType;
+  InterfaceType _numType;
+  InterfaceType _objectType;
+  InterfaceType _stackTraceType;
+  InterfaceType _streamDynamicType;
+  InterfaceType _streamType;
+  InterfaceType _stringType;
+  InterfaceType _symbolType;
+  InterfaceType _typeType;
+
+  TypeProviderForLink(this._linker);
+
+  @override
+  InterfaceType get boolType =>
+      _boolType ??= _buildInterfaceType(_linker.coreLibrary, 'bool');
+
+  @override
+  DartType get bottomType => BottomTypeImpl.instance;
+
+  @override
+  InterfaceType get deprecatedType => _deprecatedType ??=
+      _buildInterfaceType(_linker.coreLibrary, 'Deprecated');
+
+  @override
+  InterfaceType get doubleType =>
+      _doubleType ??= _buildInterfaceType(_linker.coreLibrary, 'double');
+
+  @override
+  DartType get dynamicType => DynamicTypeImpl.instance;
+
+  @override
+  InterfaceType get functionType =>
+      _functionType ??= _buildInterfaceType(_linker.coreLibrary, 'Function');
+
+  @override
+  InterfaceType get futureDynamicType =>
+      _futureDynamicType ??= futureType.instantiate(<DartType>[dynamicType]);
+
+  @override
+  InterfaceType get futureNullType =>
+      _futureNullType ??= futureType.instantiate(<DartType>[nullType]);
+
+  @override
+  InterfaceType get futureType =>
+      _futureType ??= _buildInterfaceType(_linker.asyncLibrary, 'Future');
+
+  @override
+  InterfaceType get intType =>
+      _intType ??= _buildInterfaceType(_linker.coreLibrary, 'int');
+
+  @override
+  InterfaceType get iterableDynamicType => _iterableDynamicType ??=
+      iterableType.instantiate(<DartType>[dynamicType]);
+
+  @override
+  InterfaceType get iterableType =>
+      _iterableType ??= _buildInterfaceType(_linker.coreLibrary, 'Iterable');
+
+  @override
+  InterfaceType get listType =>
+      _listType ??= _buildInterfaceType(_linker.coreLibrary, 'List');
+
+  @override
+  InterfaceType get mapType =>
+      _mapType ??= _buildInterfaceType(_linker.coreLibrary, 'Map');
+
+  @override
+  List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[
+        nullType,
+        numType,
+        intType,
+        doubleType,
+        boolType,
+        stringType
+      ];
+
+  @override
+  DartObjectImpl get nullObject {
+    // TODO(paulberry): implement if needed
+    throw new UnimplementedError();
+  }
+
+  @override
+  InterfaceType get nullType =>
+      _nullType ??= _buildInterfaceType(_linker.coreLibrary, 'Null');
+
+  @override
+  InterfaceType get numType =>
+      _numType ??= _buildInterfaceType(_linker.coreLibrary, 'num');
+
+  @override
+  InterfaceType get objectType =>
+      _objectType ??= _buildInterfaceType(_linker.coreLibrary, 'Object');
+
+  @override
+  InterfaceType get stackTraceType => _stackTraceType ??=
+      _buildInterfaceType(_linker.coreLibrary, 'StackTrace');
+
+  @override
+  InterfaceType get streamDynamicType =>
+      _streamDynamicType ??= streamType.instantiate(<DartType>[dynamicType]);
+
+  @override
+  InterfaceType get streamType =>
+      _streamType ??= _buildInterfaceType(_linker.asyncLibrary, 'Stream');
+
+  @override
+  InterfaceType get stringType =>
+      _stringType ??= _buildInterfaceType(_linker.coreLibrary, 'String');
+
+  @override
+  InterfaceType get symbolType =>
+      _symbolType ??= _buildInterfaceType(_linker.coreLibrary, 'Symbol');
+
+  @override
+  InterfaceType get typeType =>
+      _typeType ??= _buildInterfaceType(_linker.coreLibrary, 'Type');
+
+  @override
+  DartType get undefinedType => UndefinedTypeImpl.instance;
+
+  InterfaceType _buildInterfaceType(
+      LibraryElementForLink library, String name) {
+    return library
+        .getContainedName(name)
+        .buildType((int i) => DynamicTypeImpl.instance, const []);
+  }
+}
+
+/**
  * Singleton element used for unresolved references.
  */
 class UndefinedElementForLink implements ReferenceableElementForLink {
@@ -1455,6 +2636,12 @@
   ConstVariableNode get asConstVariable => null;
 
   @override
+  DartType get asStaticType => DynamicTypeImpl.instance;
+
+  @override
+  TypeInferenceNode get asTypeInferenceNode => null;
+
+  @override
   DartType buildType(DartType getTypeArgument(int i),
           List<int> implicitFunctionTypeIndices) =>
       DynamicTypeImpl.instance;
@@ -1468,7 +2655,7 @@
  * summary during linking.
  */
 class VariableElementForLink
-    implements VariableElement, ReferenceableElementForLink {
+    implements VariableElementImpl, ReferenceableElementForLink {
   /**
    * The unlinked representation of the variable in the summary.
    */
@@ -1482,6 +2669,15 @@
   ConstNode _constNode;
 
   /**
+   * If this variable has an initializer and an implicit type, and the enclosing
+   * library is part of the build unit being linked, the variable's node in the
+   * type inference dependency graph.  Otherwise `null`.
+   */
+  TypeInferenceNode _typeInferenceNode;
+
+  FunctionElementForLink_Initializer _initializer;
+
+  /**
    * The compilation unit in which this variable appears.
    */
   final CompilationUnitElementForLink compilationUnit;
@@ -1489,6 +2685,9 @@
   VariableElementForLink(this.unlinkedVariable, this.compilationUnit) {
     if (compilationUnit.isInBuildUnit && unlinkedVariable.constExpr != null) {
       _constNode = new ConstVariableNode(this);
+      if (unlinkedVariable.type == null) {
+        _typeInferenceNode = new TypeInferenceNode(this);
+      }
     }
   }
 
@@ -1499,6 +2698,27 @@
   ConstVariableNode get asConstVariable => _constNode;
 
   @override
+  DartType get asStaticType {
+    // TODO(paulberry): implement.
+    throw new UnimplementedError();
+  }
+
+  @override
+  TypeInferenceNode get asTypeInferenceNode => _typeInferenceNode;
+
+  @override
+  bool get hasImplicitType => unlinkedVariable.type == null;
+
+  @override
+  FunctionElementForLink_Initializer get initializer {
+    if (unlinkedVariable.constExpr == null) {
+      return null;
+    } else {
+      return _initializer ??= new FunctionElementForLink_Initializer(this);
+    }
+  }
+
+  @override
   bool get isConst => unlinkedVariable.isConst;
 
   @override
@@ -1508,9 +2728,17 @@
   bool get isStatic;
 
   @override
+  bool get isSynthetic => false;
+
+  @override
   String get name => unlinkedVariable.name;
 
   @override
+  void set type(DartType newType) {
+    // TODO(paulberry): store inferred type.
+  }
+
+  @override
   DartType buildType(DartType getTypeArgument(int i),
           List<int> implicitFunctionTypeIndices) =>
       DynamicTypeImpl.instance;
@@ -1554,11 +2782,17 @@
   final List<LibraryElementInBuildUnit> _librariesInBuildUnit =
       <LibraryElementInBuildUnit>[];
 
-  InterfaceType _objectType;
+  /**
+   * Indicates whether type inference should use strong mode rules.
+   */
+  final bool strongMode;
+
   LibraryElementForLink _coreLibrary;
+  LibraryElementForLink _asyncLibrary;
+  TypeProviderForLink _typeProvider;
 
   _Linker(Map<String, LinkedLibraryBuilder> linkedLibraries, this.getDependency,
-      this.getUnit) {
+      this.getUnit, this.strongMode) {
     // Create elements for the libraries to be linked.  The rest of
     // the element model will be created on demand.
     linkedLibraries
@@ -1570,17 +2804,22 @@
   }
 
   /**
+   * Get the library element for `dart:async`.
+   */
+  LibraryElementForLink get asyncLibrary =>
+      _asyncLibrary ??= getLibrary(Uri.parse('dart:async'));
+
+  /**
    * Get the library element for `dart:core`.
    */
   LibraryElementForLink get coreLibrary =>
       _coreLibrary ??= getLibrary(Uri.parse('dart:core'));
 
   /**
-   * Get the `InterfaceType` for the type `Object`.
+   * Get an instance of [TypeProvider] for use during linking.
    */
-  InterfaceType get objectType => _objectType ??= coreLibrary
-      .getContainedName('Object')
-      .buildType((int i) => DynamicTypeImpl.instance, const []);
+  TypeProviderForLink get typeProvider =>
+      _typeProvider ??= new TypeProviderForLink(this);
 
   /**
    * Get the library element for the library having the given [uri].
@@ -1595,6 +2834,7 @@
    * in the build unit being linked.
    */
   void link() {
+    // TODO(paulberry): link library cycles in appropriate dependency order.
     for (LibraryElementInBuildUnit library in _librariesInBuildUnit) {
       library.link();
     }
@@ -1602,7 +2842,8 @@
   }
 
   /**
-   * Throw away any information produced by a previous call to [link].
+   * Throw away any information stored in the summary by a previous call to
+   * [link].
    */
   void unlink() {
     for (LibraryElementInBuildUnit library in _librariesInBuildUnit) {
diff --git a/pkg/analyzer/lib/src/summary/prelink.dart b/pkg/analyzer/lib/src/summary/prelink.dart
index 6b92f99..ede4239 100644
--- a/pkg/analyzer/lib/src/summary/prelink.dart
+++ b/pkg/analyzer/lib/src/summary/prelink.dart
@@ -421,24 +421,8 @@
         // Prefix references must always point backward.
         assert(reference.prefixReference < i);
         namespace = prefixNamespaces[reference.prefixReference];
-        // If in `a.length` the `a` prefix is a top-level variable or a field,
-        // then it must be the `String.length` property reference.
-        if (namespace == null && reference.name == 'length') {
-          ReferenceKind prefixKind = references[reference.prefixReference].kind;
-          if (prefixKind == ReferenceKind.topLevelPropertyAccessor ||
-              prefixKind == ReferenceKind.propertyAccessor) {
-            references
-                .add(new LinkedReferenceBuilder(kind: ReferenceKind.length));
-            continue;
-          }
-        }
-        // Anything prefixed with 'unresolved' is unresolved.
-        if (references[reference.prefixReference].kind ==
-            ReferenceKind.unresolved) {
-          namespace = const <String, _Meaning>{};
-        }
-        // Prefix references must always point to proper prefixes.
-        assert(namespace != null);
+        // Expressions like 'a.b.c.d' cannot be prelinked.
+        namespace ??= const <String, _Meaning>{};
       }
       _Meaning meaning = namespace[reference.name];
       if (meaning != null) {
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index de36f0a..63a7f0f 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -286,7 +286,7 @@
   Expression get expr => stack.single;
 
   Expression build() {
-    if (uc.isInvalid) {
+    if (!uc.isValidConst) {
       return AstFactory.identifier3(r'$$invalidConstExpr$$');
     }
     for (UnlinkedConstOperation operation in uc.operations) {
@@ -414,12 +414,9 @@
           _push(
               AstFactory.conditionalExpression(condition, thenExpr, elseExpr));
           break;
-        // identical
-        case UnlinkedConstOperation.identical:
-          Expression second = _pop();
-          Expression first = _pop();
-          _push(AstFactory.methodInvocation(
-              null, 'identical', <Expression>[first, second]));
+        // invokeMethodRef
+        case UnlinkedConstOperation.invokeMethodRef:
+          _pushInvokeMethodRef();
           break;
         // containers
         case UnlinkedConstOperation.makeUntypedList:
@@ -438,33 +435,14 @@
           _pushMap(AstFactory.typeArgumentList(<TypeName>[keyType, valueType]));
           break;
         case UnlinkedConstOperation.pushReference:
-          EntityRef ref = uc.references[refPtr++];
-          _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
-          if (info.enclosing != null &&
-              info.enclosing.element != null &&
-              info.enclosing.element is! ClassElement) {
-            SimpleIdentifier prefix = AstFactory.identifier3(
-                info.enclosing.name)..staticElement = info.enclosing.element;
-            SimpleIdentifier name = AstFactory.identifier3(info.name)
-              ..staticElement = info.element;
-            PrefixedIdentifier node = AstFactory.identifier(prefix, name);
-            _push(node);
-          } else {
-            SimpleIdentifier node = AstFactory.identifier3(info.name);
-            node.staticElement = info.element;
-            _push(node);
-          }
+          _pushReference();
+          break;
+        case UnlinkedConstOperation.extractProperty:
+          _pushExtractProperty();
           break;
         case UnlinkedConstOperation.invokeConstructor:
           _pushInstanceCreation();
           break;
-        case UnlinkedConstOperation.length:
-          Expression target = _pop();
-          SimpleIdentifier property = AstFactory.identifier3('length');
-          property.staticElement =
-              resynthesizer._buildStringLengthPropertyAccessorElement();
-          _push(AstFactory.propertyAccess(target, property));
-          break;
         case UnlinkedConstOperation.pushConstructorParameter:
           String name = uc.strings[stringPtr++];
           SimpleIdentifier identifier = AstFactory.identifier3(name);
@@ -474,11 +452,65 @@
                       'Unable to resolve constructor parameter: $name'));
           _push(identifier);
           break;
+        case UnlinkedConstOperation.assignToRef:
+        case UnlinkedConstOperation.assignToProperty:
+        case UnlinkedConstOperation.assignToIndex:
+        case UnlinkedConstOperation.extractIndex:
+        case UnlinkedConstOperation.invokeMethod:
+        case UnlinkedConstOperation.cascadeSectionBegin:
+        case UnlinkedConstOperation.cascadeSectionEnd:
+        case UnlinkedConstOperation.typeCast:
+        case UnlinkedConstOperation.typeCheck:
+        case UnlinkedConstOperation.throwException:
+          throw new UnimplementedError('$operation');
       }
     }
     return stack.single;
   }
 
+  List<Expression> _buildArguments() {
+    List<Expression> arguments;
+    {
+      int numNamedArgs = uc.ints[intPtr++];
+      int numPositionalArgs = uc.ints[intPtr++];
+      int numArgs = numNamedArgs + numPositionalArgs;
+      arguments = _removeTopItems(numArgs);
+      // add names to the named arguments
+      for (int i = 0; i < numNamedArgs; i++) {
+        String name = uc.strings[stringPtr++];
+        int index = numPositionalArgs + i;
+        arguments[index] = AstFactory.namedExpression2(name, arguments[index]);
+      }
+    }
+    return arguments;
+  }
+
+  /**
+   * Build the identifier sequence (a single or prefixed identifier, or a
+   * property access) corresponding to the given reference [info].
+   */
+  Expression _buildIdentifierSequence(_ReferenceInfo info) {
+    Expression enclosing;
+    if (info.enclosing != null) {
+      enclosing = _buildIdentifierSequence(info.enclosing);
+    }
+    Element element = info.element;
+    if (element == null && info.name == 'length') {
+      element = _getStringLengthElement();
+    }
+    if (enclosing == null) {
+      return AstFactory.identifier3(info.name)..staticElement = element;
+    }
+    if (enclosing is SimpleIdentifier) {
+      SimpleIdentifier identifier = AstFactory.identifier3(info.name)
+        ..staticElement = element;
+      return AstFactory.identifier(enclosing, identifier);
+    }
+    SimpleIdentifier property = AstFactory.identifier3(info.name)
+      ..staticElement = element;
+    return AstFactory.propertyAccess(enclosing, property);
+  }
+
   TypeName _buildTypeAst(DartType type) {
     List<TypeName> argumentNodes;
     if (type is ParameterizedType) {
@@ -493,6 +525,9 @@
     return node;
   }
 
+  PropertyAccessorElement _getStringLengthElement() =>
+      resynthesizer.typeProvider.stringType.getGetter('length');
+
   InterpolationElement _newInterpolationElement(Expression expr) {
     if (expr is SimpleStringLiteral) {
       return new InterpolationString(expr.literal, expr.value);
@@ -526,6 +561,17 @@
     _push(AstFactory.binaryExpression(left, operator, right));
   }
 
+  void _pushExtractProperty() {
+    Expression target = _pop();
+    String name = uc.strings[stringPtr++];
+    // TODO(scheglov) Only String.length property access is supported.
+    assert(name == 'length');
+    _push(AstFactory.propertyAccess(
+        target,
+        AstFactory.identifier3('length')
+          ..staticElement = _getStringLengthElement()));
+  }
+
   void _pushInstanceCreation() {
     EntityRef ref = uc.references[refPtr++];
     _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
@@ -576,19 +622,7 @@
       }
     }
     // prepare arguments
-    List<Expression> arguments;
-    {
-      int numNamedArgs = uc.ints[intPtr++];
-      int numPositionalArgs = uc.ints[intPtr++];
-      int numArgs = numNamedArgs + numPositionalArgs;
-      arguments = _removeTopItems(numArgs);
-      // add names to the named arguments
-      for (int i = 0; i < numNamedArgs; i++) {
-        String name = uc.strings[stringPtr++];
-        int index = numPositionalArgs + i;
-        arguments[index] = AstFactory.namedExpression2(name, arguments[index]);
-      }
-    }
+    List<Expression> arguments = _buildArguments();
     // create ConstructorName
     ConstructorName constructorNode;
     if (constructorName != null) {
@@ -605,6 +639,23 @@
     _push(instanceCreation);
   }
 
+  void _pushInvokeMethodRef() {
+    List<Expression> arguments = _buildArguments();
+    EntityRef ref = uc.references[refPtr++];
+    _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
+    Expression node = _buildIdentifierSequence(info);
+    if (node is SimpleIdentifier) {
+      _push(new MethodInvocation(
+          null,
+          TokenFactory.tokenFromType(TokenType.PERIOD),
+          node,
+          null,
+          AstFactory.argumentList(arguments)));
+    } else {
+      throw new UnimplementedError('For ${node?.runtimeType}: $node');
+    }
+  }
+
   void _pushList(TypeArgumentList typeArguments) {
     int count = uc.ints[intPtr++];
     List<Expression> elements = <Expression>[];
@@ -630,6 +681,13 @@
     _push(AstFactory.prefixExpression(operator, operand));
   }
 
+  void _pushReference() {
+    EntityRef ref = uc.references[refPtr++];
+    _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
+    Expression node = _buildIdentifierSequence(info);
+    _push(node);
+  }
+
   List<Expression> _removeTopItems(int count) {
     int start = stack.length - count;
     int end = stack.length;
@@ -723,7 +781,8 @@
       : super(null, location);
 
   @override
-  Element get actualElement => enclosingElement.getNamedConstructor(name);
+  ConstructorElement get actualElement =>
+      enclosingElement.getNamedConstructor(name);
 
   @override
   AnalysisContext get context => _definingType.element.context;
@@ -964,7 +1023,6 @@
       case ReferenceKind.function:
       case ReferenceKind.propertyAccessor:
       case ReferenceKind.method:
-      case ReferenceKind.length:
       case ReferenceKind.prefix:
       case ReferenceKind.unresolved:
       case ReferenceKind.variable:
@@ -1325,7 +1383,7 @@
         // For a type that refers to a generic executable, the type arguments are
         // not supposed to include the arguments to the executable itself.
         numTypeArguments = enclosing == null ? 0 : enclosing.numTypeParameters;
-        computer = () => this.element;
+        computer = () => this.element as FunctionTypedElement;
       }
       // TODO(paulberry): Is it a bug that we have to pass `false` for
       // isInstantiated?
@@ -2005,7 +2063,7 @@
    */
   LocalVariableElement buildLocalVariable(UnlinkedVariable serializedVariable) {
     LocalVariableElementImpl element;
-    if (serializedVariable.constExpr != null) {
+    if (serializedVariable.constExpr != null && serializedVariable.isConst) {
       ConstLocalVariableElementImpl constElement =
           new ConstLocalVariableElementImpl(
               serializedVariable.name, serializedVariable.nameOffset);
@@ -2232,7 +2290,7 @@
       [ElementHolder holder]) {
     if (holder == null) {
       TopLevelVariableElementImpl element;
-      if (serializedVariable.constExpr != null) {
+      if (serializedVariable.constExpr != null && serializedVariable.isConst) {
         ConstTopLevelVariableElementImpl constElement =
             new ConstTopLevelVariableElementImpl(
                 serializedVariable.name, serializedVariable.nameOffset);
@@ -2248,7 +2306,9 @@
       buildImplicitAccessors(element, unitHolder);
     } else {
       FieldElementImpl element;
-      if (serializedVariable.constExpr != null) {
+      if (serializedVariable.constExpr != null &&
+          (serializedVariable.isConst ||
+              serializedVariable.isFinal && !serializedVariable.isStatic)) {
         ConstFieldElementImpl constElement = new ConstFieldElementImpl(
             serializedVariable.name, serializedVariable.nameOffset);
         element = constElement;
@@ -2408,9 +2468,6 @@
             element =
                 new ConstructorElementHandle(summaryResynthesizer, location);
             break;
-          case ReferenceKind.length:
-            element = _buildStringLengthPropertyAccessorElement();
-            break;
           case ReferenceKind.method:
             assert(location.components.length == 4);
             element = new MethodElementHandle(summaryResynthesizer, location);
@@ -2538,15 +2595,6 @@
   }
 
   /**
-   * Return the new handle of the `String.length` getter element.
-   */
-  PropertyAccessorElementHandle _buildStringLengthPropertyAccessorElement() =>
-      new PropertyAccessorElementHandle(
-          summaryResynthesizer,
-          new ElementLocationImpl.con3(
-              <String>['dart:core', 'dart:core', 'String', 'length?']));
-
-  /**
    * Return the defining type for a [ConstructorElement] by applying
    * [typeArgumentRefs] to the given linked [info].
    */
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 715267b..f8d96a1 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -76,7 +76,13 @@
   EntityRefBuilder serializeIdentifier(Identifier identifier) {
     EntityRefBuilder b = new EntityRefBuilder();
     if (identifier is SimpleIdentifier) {
-      b.reference = visitor.serializeSimpleReference(identifier.name);
+      int index = visitor.serializeSimpleReference(identifier.name,
+          allowTypeParameter: true);
+      if (index < 0) {
+        b.paramReference = -index;
+      } else {
+        b.reference = index;
+      }
     } else if (identifier is PrefixedIdentifier) {
       int prefix = visitor.serializeSimpleReference(identifier.prefix.name);
       b.reference =
@@ -89,15 +95,24 @@
   }
 
   @override
-  EntityRefBuilder serializePropertyAccess(PropertyAccess access) {
-    Expression target = access.target;
-    if (target is Identifier) {
-      EntityRefBuilder targetRef = serializeIdentifier(target);
-      return new EntityRefBuilder(reference: visitor.serializeReference(
-          targetRef.reference, access.propertyName.name));
+  EntityRefBuilder serializeIdentifierSequence(Expression expr) {
+    if (expr is Identifier) {
+      AstNode parent = expr.parent;
+      if (parent is MethodInvocation &&
+          parent.methodName == expr &&
+          parent.target != null) {
+        int targetId = serializeIdentifierSequence(parent.target).reference;
+        int nameId = visitor.serializeReference(targetId, expr.name);
+        return new EntityRefBuilder(reference: nameId);
+      }
+      return serializeIdentifier(expr);
+    }
+    if (expr is PropertyAccess) {
+      int targetId = serializeIdentifierSequence(expr.target).reference;
+      int nameId = visitor.serializeReference(targetId, expr.propertyName.name);
+      return new EntityRefBuilder(reference: nameId);
     } else {
-      // TODO(scheglov) should we handle other targets in malformed constants?
-      throw new StateError('Unexpected target type: ${target.runtimeType}');
+      throw new StateError('Unexpected node type: ${expr.runtimeType}');
     }
   }
 
@@ -698,8 +713,12 @@
   /**
    * Serialize a reference to a name declared either at top level or in a
    * nested scope.
+   *
+   * If [allowTypeParameter] is `true`, then references to type
+   * parameters are allowed, and are returned as negative numbers.
    */
-  int serializeSimpleReference(String name) {
+  int serializeSimpleReference(String name, {bool allowTypeParameter: false}) {
+    int indexOffset = 0;
     for (int i = scopes.length - 1; i >= 0; i--) {
       _Scope scope = scopes[i];
       _ScopedEntity entity = scope[name];
@@ -707,6 +726,9 @@
         if (entity is _ScopedClassMember) {
           return serializeReference(
               serializeReference(null, entity.className), name);
+        } else if (allowTypeParameter && entity is _ScopedTypeParameter) {
+          int paramReference = indexOffset + entity.index;
+          return -paramReference;
         } else {
           // Invalid reference to a type parameter.  Should never happen in
           // legal Dart code.
@@ -715,6 +737,9 @@
           throw new StateError('Invalid identifier reference');
         }
       }
+      if (scope is _TypeParameterScope) {
+        indexOffset += scope.length;
+      }
     }
     return serializeReference(null, name);
   }
@@ -824,7 +849,8 @@
       b.annotations = serializeAnnotations(annotations);
       b.codeRange = serializeCodeRange(variables.parent);
       if (variable.isConst ||
-          variable.isFinal && isField && !isDeclaredStatic) {
+          variable.isFinal && isField && !isDeclaredStatic ||
+          variables.type == null) {
         Expression initializer = variable.initializer;
         if (initializer != null) {
           b.constExpr = serializeConstExpr(initializer);
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index faaa1f4..8a6a4e1 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -46,7 +46,7 @@
   /**
    * See [UnlinkedConstBuilder.isInvalid].
    */
-  bool isInvalid = false;
+  bool isValidConst = true;
 
   /**
    * See [UnlinkedConstBuilder.operations].
@@ -54,6 +54,12 @@
   final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[];
 
   /**
+   * See [UnlinkedConstBuilder.assignmentOperators].
+   */
+  final List<UnlinkedExprAssignOperator> assignmentOperators =
+      <UnlinkedExprAssignOperator>[];
+
+  /**
    * See [UnlinkedConstBuilder.ints].
    */
   final List<int> ints = <int>[];
@@ -86,7 +92,7 @@
     try {
       _serialize(expr);
     } on StateError {
-      isInvalid = true;
+      isValidConst = false;
     }
   }
 
@@ -107,34 +113,20 @@
    */
   EntityRefBuilder serializeIdentifier(Identifier identifier);
 
+  /**
+   * Return [EntityRefBuilder] that corresponds to the given [expr], which
+   * must be a sequence of identifiers.
+   */
+  EntityRefBuilder serializeIdentifierSequence(Expression expr);
+
   void serializeInstanceCreation(
       EntityRefBuilder constructor, ArgumentList argumentList) {
-    List<Expression> arguments = argumentList.arguments;
-    // Serialize the arguments.
-    List<String> argumentNames = <String>[];
-    arguments.forEach((arg) {
-      if (arg is NamedExpression) {
-        argumentNames.add(arg.name.label.name);
-        _serialize(arg.expression);
-      } else {
-        _serialize(arg);
-      }
-    });
-    // Add the op-code and numbers of named and positional arguments.
-    operations.add(UnlinkedConstOperation.invokeConstructor);
-    ints.add(argumentNames.length);
-    strings.addAll(argumentNames);
-    ints.add(arguments.length - argumentNames.length);
-    // Serialize the reference.
+    _serializeArguments(argumentList);
     references.add(constructor);
+    operations.add(UnlinkedConstOperation.invokeConstructor);
   }
 
   /**
-   * Return [EntityRefBuilder] that corresponds to the given [access].
-   */
-  EntityRefBuilder serializePropertyAccess(PropertyAccess access);
-
-  /**
    * Return [EntityRefBuilder] that corresponds to the given [type].
    */
   EntityRefBuilder serializeType(TypeName type);
@@ -144,17 +136,41 @@
    * serializer.
    */
   UnlinkedConstBuilder toBuilder() {
-    if (isInvalid) {
-      return new UnlinkedConstBuilder(isInvalid: true);
-    }
     return new UnlinkedConstBuilder(
+        isValidConst: isValidConst,
         operations: operations,
+        assignmentOperators: assignmentOperators,
         ints: ints,
         doubles: doubles,
         strings: strings,
         references: references);
   }
 
+  /**
+   * Push the operation for the given assignable [expr].
+   */
+  void _pushAssignable(Expression expr) {
+    if (_isIdentifierSequence(expr)) {
+      EntityRefBuilder ref = serializeIdentifierSequence(expr);
+      references.add(ref);
+      operations.add(UnlinkedConstOperation.assignToRef);
+    } else if (expr is PropertyAccess) {
+      if (!expr.isCascaded) {
+        _serialize(expr.target);
+      }
+      strings.add(expr.propertyName.name);
+      operations.add(UnlinkedConstOperation.assignToProperty);
+    } else if (expr is IndexExpression) {
+      if (!expr.isCascaded) {
+        _serialize(expr.target);
+      }
+      _serialize(expr.index);
+      operations.add(UnlinkedConstOperation.assignToIndex);
+    } else {
+      throw new StateError('Unsupported assignable: $expr');
+    }
+  }
+
   void _pushInt(int value) {
     assert(value >= 0);
     if (value >= (1 << 32)) {
@@ -207,6 +223,9 @@
         operations.add(UnlinkedConstOperation.pushReference);
       }
     } else if (expr is InstanceCreationExpression) {
+      if (!expr.isConst) {
+        isValidConst = false;
+      }
       serializeInstanceCreation(
           serializeConstructorName(
               expr.constructorName.type, expr.constructorName.name),
@@ -216,17 +235,7 @@
     } else if (expr is MapLiteral) {
       _serializeMapLiteral(expr);
     } else if (expr is MethodInvocation) {
-      String name = expr.methodName.name;
-      if (name != 'identical') {
-        throw new StateError('Only "identity" function invocation is allowed.');
-      }
-      if (expr.argumentList == null ||
-          expr.argumentList.arguments.length != 2) {
-        throw new StateError(
-            'The function "identity" requires exactly 2 arguments.');
-      }
-      expr.argumentList.arguments.forEach(_serialize);
-      operations.add(UnlinkedConstOperation.identical);
+      _serializeMethodInvocation(expr);
     } else if (expr is BinaryExpression) {
       _serializeBinaryExpression(expr);
     } else if (expr is ConditionalExpression) {
@@ -236,22 +245,107 @@
       operations.add(UnlinkedConstOperation.conditional);
     } else if (expr is PrefixExpression) {
       _serializePrefixExpression(expr);
+    } else if (expr is PostfixExpression) {
+      _serializePostfixExpression(expr);
     } else if (expr is PropertyAccess) {
-      if (expr.target is! PrefixedIdentifier &&
-          expr.propertyName.name == 'length') {
-        _serialize(expr.target);
-        operations.add(UnlinkedConstOperation.length);
-      } else {
-        references.add(serializePropertyAccess(expr));
-        operations.add(UnlinkedConstOperation.pushReference);
-      }
+      _serializePropertyAccess(expr);
     } else if (expr is ParenthesizedExpression) {
       _serialize(expr.expression);
+    } else if (expr is IndexExpression) {
+      isValidConst = false;
+      _serialize(expr.target);
+      _serialize(expr.index);
+      operations.add(UnlinkedConstOperation.extractIndex);
+    } else if (expr is AssignmentExpression) {
+      _serializeAssignment(expr);
+    } else if (expr is CascadeExpression) {
+      _serializeCascadeExpression(expr);
+    } else if (expr is FunctionExpression) {
+      isValidConst = false;
+      // TODO(scheglov) implement
+      operations.add(UnlinkedConstOperation.pushNull);
+    } else if (expr is FunctionExpressionInvocation) {
+      isValidConst = false;
+      // TODO(scheglov) implement
+      operations.add(UnlinkedConstOperation.pushNull);
+    } else if (expr is AsExpression) {
+      isValidConst = false;
+      _serialize(expr.expression);
+      _serialize(expr.type.name);
+      operations.add(UnlinkedConstOperation.typeCast);
+    } else if (expr is IsExpression) {
+      isValidConst = false;
+      _serialize(expr.expression);
+      _serialize(expr.type.name);
+      operations.add(UnlinkedConstOperation.typeCheck);
+    } else if (expr is ThrowExpression) {
+      isValidConst = false;
+      _serialize(expr.expression);
+      operations.add(UnlinkedConstOperation.throwException);
     } else {
       throw new StateError('Unknown expression type: $expr');
     }
   }
 
+  void _serializeArguments(ArgumentList argumentList) {
+    List<Expression> arguments = argumentList.arguments;
+    // Serialize the arguments.
+    List<String> argumentNames = <String>[];
+    arguments.forEach((arg) {
+      if (arg is NamedExpression) {
+        argumentNames.add(arg.name.label.name);
+        _serialize(arg.expression);
+      } else {
+        _serialize(arg);
+      }
+    });
+    // Add numbers of named and positional arguments, and the op-code.
+    ints.add(argumentNames.length);
+    strings.addAll(argumentNames);
+    ints.add(arguments.length - argumentNames.length);
+  }
+
+  void _serializeAssignment(AssignmentExpression expr) {
+    isValidConst = false;
+    // Push the value.
+    _serialize(expr.rightHandSide);
+    // Push the assignment operator.
+    TokenType operator = expr.operator.type;
+    UnlinkedExprAssignOperator assignmentOperator;
+    if (operator == TokenType.EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.assign;
+    } else if (operator == TokenType.QUESTION_QUESTION_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.ifNull;
+    } else if (operator == TokenType.STAR_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.multiply;
+    } else if (operator == TokenType.SLASH_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.divide;
+    } else if (operator == TokenType.TILDE_SLASH_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.floorDivide;
+    } else if (operator == TokenType.PERCENT_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.modulo;
+    } else if (operator == TokenType.PLUS_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.plus;
+    } else if (operator == TokenType.MINUS_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.minus;
+    } else if (operator == TokenType.LT_LT_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.shiftLeft;
+    } else if (operator == TokenType.GT_GT_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.shiftRight;
+    } else if (operator == TokenType.AMPERSAND_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.bitAnd;
+    } else if (operator == TokenType.CARET_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.bitXor;
+    } else if (operator == TokenType.BAR_EQ) {
+      assignmentOperator = UnlinkedExprAssignOperator.bitOr;
+    } else {
+      throw new StateError('Unknown assignment operator: $operator');
+    }
+    assignmentOperators.add(assignmentOperator);
+    // Push the assignment to the LHS.
+    _pushAssignable(expr.leftHandSide);
+  }
+
   void _serializeBinaryExpression(BinaryExpression expr) {
     _serialize(expr.leftOperand);
     _serialize(expr.rightOperand);
@@ -299,6 +393,15 @@
     }
   }
 
+  void _serializeCascadeExpression(CascadeExpression expr) {
+    _serialize(expr.target);
+    for (Expression section in expr.cascadeSections) {
+      operations.add(UnlinkedConstOperation.cascadeSectionBegin);
+      _serialize(section);
+      operations.add(UnlinkedConstOperation.cascadeSectionEnd);
+    }
+  }
+
   void _serializeListLiteral(ListLiteral expr) {
     List<Expression> elements = expr.elements;
     elements.forEach(_serialize);
@@ -328,20 +431,85 @@
     }
   }
 
-  void _serializePrefixExpression(PrefixExpression expr) {
-    _serialize(expr.operand);
+  void _serializeMethodInvocation(MethodInvocation invocation) {
+    if (invocation.target != null ||
+        invocation.methodName.name != 'identical') {
+      isValidConst = false;
+    }
+    Expression target = invocation.target;
+    SimpleIdentifier methodName = invocation.methodName;
+    ArgumentList argumentList = invocation.argumentList;
+    if (_isIdentifierSequence(methodName)) {
+      EntityRefBuilder ref = serializeIdentifierSequence(methodName);
+      references.add(ref);
+      _serializeArguments(argumentList);
+      operations.add(UnlinkedConstOperation.invokeMethodRef);
+    } else {
+      if (!invocation.isCascaded) {
+        _serialize(target);
+      }
+      _serializeArguments(argumentList);
+      strings.add(methodName.name);
+      operations.add(UnlinkedConstOperation.invokeMethod);
+    }
+  }
+
+  void _serializePostfixExpression(PostfixExpression expr) {
     TokenType operator = expr.operator.type;
-    if (operator == TokenType.BANG) {
-      operations.add(UnlinkedConstOperation.not);
-    } else if (operator == TokenType.MINUS) {
-      operations.add(UnlinkedConstOperation.negate);
-    } else if (operator == TokenType.TILDE) {
-      operations.add(UnlinkedConstOperation.complement);
+    Expression operand = expr.operand;
+    if (operator == TokenType.PLUS_PLUS) {
+      _serializePrefixPostfixIncDec(
+          operand, UnlinkedExprAssignOperator.postfixIncrement);
+    } else if (operator == TokenType.MINUS_MINUS) {
+      _serializePrefixPostfixIncDec(
+          operand, UnlinkedExprAssignOperator.postfixDecrement);
     } else {
       throw new StateError('Unknown operator: $operator');
     }
   }
 
+  void _serializePrefixExpression(PrefixExpression expr) {
+    TokenType operator = expr.operator.type;
+    Expression operand = expr.operand;
+    if (operator == TokenType.BANG) {
+      _serialize(operand);
+      operations.add(UnlinkedConstOperation.not);
+    } else if (operator == TokenType.MINUS) {
+      _serialize(operand);
+      operations.add(UnlinkedConstOperation.negate);
+    } else if (operator == TokenType.TILDE) {
+      _serialize(operand);
+      operations.add(UnlinkedConstOperation.complement);
+    } else if (operator == TokenType.PLUS_PLUS) {
+      _serializePrefixPostfixIncDec(
+          operand, UnlinkedExprAssignOperator.prefixIncrement);
+    } else if (operator == TokenType.MINUS_MINUS) {
+      _serializePrefixPostfixIncDec(
+          operand, UnlinkedExprAssignOperator.prefixDecrement);
+    } else {
+      throw new StateError('Unknown operator: $operator');
+    }
+  }
+
+  void _serializePrefixPostfixIncDec(
+      Expression operand, UnlinkedExprAssignOperator operator) {
+    isValidConst = false;
+    assignmentOperators.add(operator);
+    _pushAssignable(operand);
+  }
+
+  void _serializePropertyAccess(PropertyAccess expr) {
+    if (_isIdentifierSequence(expr)) {
+      EntityRefBuilder ref = serializeIdentifierSequence(expr);
+      references.add(ref);
+      operations.add(UnlinkedConstOperation.pushReference);
+    } else {
+      _serialize(expr.target);
+      strings.add(expr.propertyName.name);
+      operations.add(UnlinkedConstOperation.extractProperty);
+    }
+  }
+
   void _serializeString(StringLiteral expr) {
     if (expr is AdjacentStrings) {
       if (expr.strings.every((string) => string is SimpleStringLiteral)) {
@@ -369,4 +537,29 @@
       ints.add(interpolation.elements.length);
     }
   }
+
+  /**
+   * Return `true` if the given [expr] is a sequence of identifiers.
+   */
+  static bool _isIdentifierSequence(Expression expr) {
+    while (expr != null) {
+      if (expr is SimpleIdentifier) {
+        AstNode parent = expr.parent;
+        if (parent is MethodInvocation && parent.methodName == expr) {
+          if (parent.isCascaded) {
+            return false;
+          }
+          return parent.target == null || _isIdentifierSequence(parent.target);
+        }
+        return true;
+      } else if (expr is PrefixedIdentifier) {
+        expr = (expr as PrefixedIdentifier).prefix;
+      } else if (expr is PropertyAccess) {
+        expr = (expr as PropertyAccess).target;
+      } else {
+        return false;
+      }
+    }
+    return false;
+  }
 }
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 09ea986..3315785 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -450,7 +450,7 @@
 
   /**
    * Compute the appropriate De Bruijn index to represent the given type
-   * parameter [type].
+   * parameter [type], or return `null` if the type parameter is not in scope.
    */
   int findTypeParameterIndex(TypeParameterType type, Element context) {
     Element originalContext = context;
@@ -475,8 +475,7 @@
       }
       context = context.enclosingElement;
     }
-    throw new StateError(
-        'Unbound type parameter $type (${originalContext?.location})');
+    return null;
   }
 
   /**
@@ -504,10 +503,11 @@
     if (element.metadata.isEmpty) {
       return const <UnlinkedConstBuilder>[];
     }
-    return element.metadata.map((ElementAnnotationImpl a) {
+    return element.metadata.map((ElementAnnotation a) {
       _ConstExprSerializer serializer =
           new _ConstExprSerializer(this, element, null);
-      serializer.serializeAnnotation(a.annotationAst);
+      serializer
+          .serializeAnnotation((a as ElementAnnotationImpl).annotationAst);
       return serializer.toBuilder();
     }).toList();
   }
@@ -852,12 +852,13 @@
   /**
    * Serialize the given [label], creating an [UnlinkedLabelBuilder].
    */
-  UnlinkedLabelBuilder serializeLabel(LabelElementImpl label) {
+  UnlinkedLabelBuilder serializeLabel(LabelElement label) {
+    LabelElementImpl labelImpl = label as LabelElementImpl;
     UnlinkedLabelBuilder b = new UnlinkedLabelBuilder();
-    b.name = label.name;
-    b.nameOffset = label.nameOffset;
-    b.isOnSwitchMember = label.isOnSwitchMember;
-    b.isOnSwitchStatement = label.isOnSwitchStatement;
+    b.name = labelImpl.name;
+    b.nameOffset = labelImpl.nameOffset;
+    b.isOnSwitchMember = labelImpl.isOnSwitchMember;
+    b.isOnSwitchStatement = labelImpl.isOnSwitchStatement;
     return b;
   }
 
@@ -1007,7 +1008,15 @@
     EntityRefBuilder b = new EntityRefBuilder(slot: slot);
     Element typeElement = type.element;
     if (type is TypeParameterType) {
-      b.paramReference = findTypeParameterIndex(type, context);
+      int typeParameterIndex = findTypeParameterIndex(type, context);
+      if (typeParameterIndex != null) {
+        b.paramReference = typeParameterIndex;
+      } else {
+        // Out-of-scope type parameters only occur in circumstances where they
+        // are irrelevant (i.e. when a type parameter is unused).  So we can
+        // safely convert them to `dynamic`.
+        b.reference = serializeReferenceForType(DynamicTypeImpl.instance);
+      }
     } else if (type is FunctionType &&
         typeElement is FunctionElement &&
         typeElement.enclosingElement == null) {
@@ -1069,8 +1078,8 @@
   }
 
   /**
-   * Create a new entry in the references table ([UnlinkedLibrary.references]
-   * and [LinkedLibrary.references]) representing an entity having the given
+   * Create a new entry in the references table ([UnlinkedUnit.references]
+   * and [LinkedUnit.references]) representing an entity having the given
    * [name] and [kind].  If [unit] is given, it is the index of the compilation
    * unit containing the entity being referred to.  If [prefixReference] is
    * given, it indicates the entry in the references table for the prefix.
@@ -1273,11 +1282,6 @@
       return index;
     });
   }
-
-  int _getLengthPropertyReference(int prefix) {
-    return serializeUnlinkedReference('length', ReferenceKind.length,
-        prefixReference: prefix);
-  }
 }
 
 /**
@@ -1351,70 +1355,58 @@
 
   EntityRefBuilder serializeIdentifier(Identifier identifier,
       {int prefixReference: 0}) {
-    Element element = identifier.staticElement;
-    // Unresolved identifier.
-    if (element == null) {
-      int reference;
-      if (identifier is PrefixedIdentifier) {
-        int prefix = serializeIdentifier(identifier.prefix).reference;
-        reference = serializer.serializeUnlinkedReference(
-            identifier.identifier.name, ReferenceKind.unresolved,
-            prefixReference: prefix);
+    if (identifier is SimpleIdentifier) {
+      Element element = identifier.staticElement;
+      if (element is TypeParameterElement) {
+        int typeParameterIndex =
+            serializer.findTypeParameterIndex(element.type, context);
+        return new EntityRefBuilder(paramReference: typeParameterIndex);
+      } else if (_isPrelinkResolvableElement(element)) {
+        int ref = serializer._getElementReferenceId(element);
+        return new EntityRefBuilder(reference: ref);
       } else {
-        reference = serializer.serializeUnlinkedReference(
-            identifier.name, ReferenceKind.unresolved,
-            prefixReference: prefixReference);
+        int ref = serializer.serializeUnlinkedReference(
+            identifier.name, ReferenceKind.unresolved);
+        return new EntityRefBuilder(reference: ref);
       }
-      return new EntityRefBuilder(reference: reference);
-    }
-    // The only supported instance property accessor - `length`.
-    if (identifier is PrefixedIdentifier &&
-        element is PropertyAccessorElement &&
-        !element.isStatic) {
-      if (element.name != 'length') {
-        throw new StateError('Only "length" property is allowed in constants.');
+    } else if (identifier is PrefixedIdentifier) {
+      Element element = identifier.staticElement;
+      if (_isPrelinkResolvableElement(element)) {
+        int ref = serializer._getElementReferenceId(element);
+        return new EntityRefBuilder(reference: ref);
+      } else {
+        int prefixRef = serializeIdentifier(identifier.prefix).reference;
+        int ref = serializer.serializeUnlinkedReference(
+            identifier.identifier.name, ReferenceKind.unresolved,
+            prefixReference: prefixRef);
+        return new EntityRefBuilder(reference: ref);
       }
-      Element prefixElement = identifier.prefix.staticElement;
-      int prefixRef = serializer._getElementReferenceId(prefixElement);
-      int lengthRef = serializer._getLengthPropertyReference(prefixRef);
-      return new EntityRefBuilder(reference: lengthRef);
+    } else {
+      throw new StateError(
+          'Unexpected identifier type: ${identifier.runtimeType}');
     }
-    if (element is TypeParameterElement) {
-      throw new StateError('Constants may not refer to type parameters.');
-    }
-    return new EntityRefBuilder(
-        reference: serializer._getElementReferenceId(element));
   }
 
   @override
-  EntityRefBuilder serializePropertyAccess(PropertyAccess access) {
-    Element element = access.propertyName.staticElement;
-    // Unresolved property access.
-    if (element == null) {
-      Expression target = access.target;
-      if (target is Identifier) {
-        EntityRefBuilder targetRef = serializeIdentifier(target);
-        EntityRefBuilder propertyRef = serializeIdentifier(access.propertyName,
-            prefixReference: targetRef.reference);
-        return new EntityRefBuilder(reference: propertyRef.reference);
+  EntityRefBuilder serializeIdentifierSequence(Expression expr) {
+    if (expr is Identifier) {
+      return serializeIdentifier(expr);
+    }
+    if (expr is PropertyAccess) {
+      Element element = expr.propertyName.staticElement;
+      if (_isPrelinkResolvableElement(element)) {
+        int ref = serializer._getElementReferenceId(element);
+        return new EntityRefBuilder(reference: ref);
       } else {
-        // TODO(scheglov) should we handle other targets in malformed constants?
-        throw new StateError('Unexpected target type: ${target.runtimeType}');
+        int targetRef = serializeIdentifierSequence(expr.target).reference;
+        int ref = serializer.serializeUnlinkedReference(
+            expr.propertyName.name, ReferenceKind.unresolved,
+            prefixReference: targetRef);
+        return new EntityRefBuilder(reference: ref);
       }
+    } else {
+      throw new StateError('Unexpected node type: ${expr.runtimeType}');
     }
-    // The only supported instance property accessor - `length`.
-    Expression target = access.target;
-    if (target is Identifier &&
-        element is PropertyAccessorElement &&
-        !element.isStatic) {
-      assert(element.name == 'length');
-      Element prefixElement = target.staticElement;
-      int prefixRef = serializer._getElementReferenceId(prefixElement);
-      int lengthRef = serializer._getLengthPropertyReference(prefixRef);
-      return new EntityRefBuilder(reference: lengthRef);
-    }
-    return new EntityRefBuilder(
-        reference: serializer._getElementReferenceId(element));
   }
 
   @override
@@ -1428,6 +1420,31 @@
     DartType type = typeName != null ? typeName.type : DynamicTypeImpl.instance;
     return serializer.serializeTypeRef(type, context);
   }
+
+  /**
+   * Return `true` if the given [element] can be resolved at prelink step.
+   */
+  static bool _isPrelinkResolvableElement(Element element) {
+    if (element == null) {
+      return false;
+    }
+    if (element == DynamicTypeImpl.instance.element) {
+      return true;
+    }
+    if (element is PrefixElement) {
+      return true;
+    }
+    Element enclosingElement = element.enclosingElement;
+    if (enclosingElement is CompilationUnitElement) {
+      return true;
+    }
+    if (enclosingElement is ClassElement) {
+      return element is ConstructorElement ||
+          element is ClassMemberElement && element.isStatic ||
+          element is PropertyAccessorElement && element.isStatic;
+    }
+    return false;
+  }
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 6ebb3f4..3faab08 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -101,7 +101,8 @@
           result == CREATED_RESOLVED_UNIT6 ||
           result == CREATED_RESOLVED_UNIT7 ||
           result == CREATED_RESOLVED_UNIT8 ||
-          result == CREATED_RESOLVED_UNIT9) {
+          result == CREATED_RESOLVED_UNIT9 ||
+          result == CREATED_RESOLVED_UNIT10) {
         entry.setValue(result, true, TargetedResult.EMPTY_LIST);
         return true;
       }
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 8705dd8..88c44fe 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -45,22 +45,47 @@
 /**
  * The [ResultCachingPolicy] for ASTs.
  */
-const ResultCachingPolicy AST_CACHING_POLICY =
+const ResultCachingPolicy<CompilationUnit> AST_CACHING_POLICY =
     const SimpleResultCachingPolicy(16384, 16384);
 
 /**
+ * The [ResultCachingPolicy] for lists of [ConstantEvaluationTarget]s.
+ */
+const ResultCachingPolicy<List<ConstantEvaluationTarget>>
+    CONSTANT_EVALUATION_TARGET_LIST_POLICY =
+    const SimpleResultCachingPolicy(-1, -1);
+
+/**
+ * The [ResultCachingPolicy] for [ConstantEvaluationTarget]s.
+ */
+const ResultCachingPolicy<ConstantEvaluationTarget>
+    CONSTANT_EVALUATION_TARGET_POLICY = const SimpleResultCachingPolicy(-1, -1);
+
+/**
  * The [ResultCachingPolicy] for [Element]s.
  */
-const ResultCachingPolicy ELEMENT_CACHING_POLICY =
+const ResultCachingPolicy<Element> ELEMENT_CACHING_POLICY =
     const SimpleResultCachingPolicy(-1, -1);
 
 /**
  * The [ResultCachingPolicy] for [TOKEN_STREAM].
  */
-const ResultCachingPolicy TOKEN_STREAM_CACHING_POLICY =
+const ResultCachingPolicy<Token> TOKEN_STREAM_CACHING_POLICY =
     const SimpleResultCachingPolicy(1, 1);
 
 /**
+ * The [ResultCachingPolicy] for [UsedImportedElements]s.
+ */
+const ResultCachingPolicy<UsedImportedElements> USED_IMPORTED_ELEMENTS_POLICY =
+    const SimpleResultCachingPolicy(-1, -1);
+
+/**
+ * The [ResultCachingPolicy] for [UsedLocalElements]s.
+ */
+const ResultCachingPolicy<UsedLocalElements> USED_LOCAL_ELEMENTS_POLICY =
+    const SimpleResultCachingPolicy(-1, -1);
+
+/**
  * The errors produced while resolving a library directives.
  *
  * The list will be empty if there were no errors, but will not be `null`.
@@ -94,7 +119,7 @@
     COMPILATION_UNIT_CONSTANTS =
     new ListResultDescriptor<ConstantEvaluationTarget>(
         'COMPILATION_UNIT_CONSTANTS', null,
-        cachingPolicy: ELEMENT_CACHING_POLICY);
+        cachingPolicy: CONSTANT_EVALUATION_TARGET_LIST_POLICY);
 
 /**
  * The element model associated with a single compilation unit.
@@ -151,7 +176,7 @@
  */
 final ResultDescriptor<ConstantEvaluationTarget> CONSTANT_VALUE =
     new ResultDescriptor<ConstantEvaluationTarget>('CONSTANT_VALUE', null,
-        cachingPolicy: ELEMENT_CACHING_POLICY);
+        cachingPolicy: CONSTANT_EVALUATION_TARGET_POLICY);
 
 /**
  * The sources representing the libraries that include a given source as a part.
@@ -198,6 +223,15 @@
     new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT11', false);
 
 /**
+ * The flag specifying that [RESOLVED_UNIT12] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT12 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT12', false);
+
+/**
  * The flag specifying that [RESOLVED_UNIT2] has been been computed for this
  * compilation unit (without requiring that the AST for it still be in cache).
  *
@@ -617,8 +651,9 @@
         cachingPolicy: AST_CACHING_POLICY);
 
 /**
- * The resolved [CompilationUnit] associated with a compilation unit, with
- * constants not yet resolved.
+ * The resolved [CompilationUnit] associated with a compilation unit in which
+ * the types of class members have been inferred in addition to everything that
+ * is true of a [RESOLVED_UNIT9].
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -628,7 +663,7 @@
 
 /**
  * The resolved [CompilationUnit] associated with a compilation unit, with
- * constants resolved.
+ * constants not yet resolved.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -637,6 +672,28 @@
         cachingPolicy: AST_CACHING_POLICY);
 
 /**
+ * The resolved [CompilationUnit] associated with a compilation unit, with
+ * constants resolved.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT12 =
+    new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT12', null,
+        cachingPolicy: AST_CACHING_POLICY);
+
+/**
+ * The partially resolved [CompilationUnit] associated with a compilation unit.
+ *
+ * In addition to what is true of a [RESOLVED_UNIT1], tasks that use this value
+ * as an input can assume that its directives have been resolved.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT2 =
+    new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT2', null,
+        cachingPolicy: AST_CACHING_POLICY);
+
+/**
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * Tasks that use this value as an input can assume that the [SimpleIdentifier]s
@@ -645,20 +702,6 @@
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
-final ResultDescriptor<CompilationUnit> RESOLVED_UNIT2 =
-    new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT2', null,
-        cachingPolicy: AST_CACHING_POLICY);
-
-/**
- * The partially resolved [CompilationUnit] associated with a compilation unit.
- *
- * In addition to what is true of a [RESOLVED_UNIT2], tasks that use this value
- * as an input can assume that the types associated with declarations have been
- * resolved. This includes the types of superclasses, mixins, interfaces,
- * fields, return types, parameters, and local variables.
- *
- * The result is only available for [LibrarySpecificUnit]s.
- */
 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT3 =
     new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT3', null,
         cachingPolicy: AST_CACHING_POLICY);
@@ -667,8 +710,9 @@
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * In addition to what is true of a [RESOLVED_UNIT3], tasks that use this value
- * as an input can assume that references to local variables and formal
- * parameters have been resolved.
+ * as an input can assume that the types associated with declarations have been
+ * resolved. This includes the types of superclasses, mixins, interfaces,
+ * fields, return types, parameters, and local variables.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -680,9 +724,8 @@
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * In addition to what is true of a [RESOLVED_UNIT4], tasks that use this value
- * as an input can assume that elements and types associated with expressions
- * outside of method bodies (essentially initializers) have been initially
- * resolved.
+ * as an input can assume that references to local variables and formal
+ * parameters have been resolved.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -694,8 +737,9 @@
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * In addition to what is true of a [RESOLVED_UNIT5], tasks that use this value
- * as an input can assume that the types of final variables have been
- * propagated.
+ * as an input can assume that elements and types associated with expressions
+ * outside of method bodies (essentially initializers) have been initially
+ * resolved.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -707,7 +751,8 @@
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * In addition to what is true of a [RESOLVED_UNIT6], tasks that use this value
- * as an input can assume that the types of static variables have been inferred.
+ * as an input can assume that the types of final variables have been
+ * propagated.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -719,8 +764,7 @@
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * In addition to what is true of a [RESOLVED_UNIT7], tasks that use this value
- * as an input can assume that the initializers of instance variables have been
- * re-resolved.
+ * as an input can assume that the types of static variables have been inferred.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -729,9 +773,11 @@
         cachingPolicy: AST_CACHING_POLICY);
 
 /**
- * The resolved [CompilationUnit] associated with a compilation unit in which
- * the types of class members have been inferred in addition to everything that
- * is true of a [RESOLVED_UNIT8].
+ * The partially resolved [CompilationUnit] associated with a compilation unit.
+ *
+ * In addition to what is true of a [RESOLVED_UNIT8], tasks that use this value
+ * as an input can assume that the initializers of instance variables have been
+ * re-resolved.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -775,14 +821,14 @@
  */
 final ResultDescriptor<UsedImportedElements> USED_IMPORTED_ELEMENTS =
     new ResultDescriptor<UsedImportedElements>('USED_IMPORTED_ELEMENTS', null,
-        cachingPolicy: ELEMENT_CACHING_POLICY);
+        cachingPolicy: USED_IMPORTED_ELEMENTS_POLICY);
 
 /**
  * The [UsedLocalElements] of a [LibrarySpecificUnit].
  */
 final ResultDescriptor<UsedLocalElements> USED_LOCAL_ELEMENTS =
     new ResultDescriptor<UsedLocalElements>('USED_LOCAL_ELEMENTS', null,
-        cachingPolicy: ELEMENT_CACHING_POLICY);
+        cachingPolicy: USED_LOCAL_ELEMENTS_POLICY);
 
 /**
  * The errors produced while resolving variable references in a compilation unit.
@@ -1100,7 +1146,7 @@
       'BuildEnumMemberElementsTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT2, RESOLVED_UNIT2]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT3, RESOLVED_UNIT3]);
 
   BuildEnumMemberElementsTask(
       InternalAnalysisContext context, AnalysisTarget target)
@@ -1135,8 +1181,8 @@
     //
     // Record outputs.
     //
-    outputs[CREATED_RESOLVED_UNIT2] = true;
-    outputs[RESOLVED_UNIT2] = unit;
+    outputs[CREATED_RESOLVED_UNIT3] = true;
+    outputs[RESOLVED_UNIT3] = unit;
   }
 
   /**
@@ -1148,7 +1194,7 @@
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      UNIT_INPUT: RESOLVED_UNIT1.of(unit)
+      UNIT_INPUT: RESOLVED_UNIT2.of(unit)
     };
   }
 
@@ -1853,7 +1899,7 @@
 class ComputeInferableStaticVariableDependenciesTask
     extends InferStaticVariableTask {
   /**
-   * The name of the [RESOLVED_UNIT5] input.
+   * The name of the [RESOLVED_UNIT6] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -1907,7 +1953,7 @@
       CompilationUnitElementImpl unit = target
           .getAncestor((Element element) => element is CompilationUnitElement);
       return <String, TaskInput>{
-        UNIT_INPUT: RESOLVED_UNIT5
+        UNIT_INPUT: RESOLVED_UNIT6
             .of(new LibrarySpecificUnit(unit.librarySource, unit.source))
       };
     }
@@ -1986,7 +2032,7 @@
       List<LibraryElement> component = library.libraryCycle;
       Set<LibraryElement> filter = new Set<LibraryElement>.from(component);
       Set<CompilationUnitElement> deps = new Set<CompilationUnitElement>();
-      void addLibrary(l) {
+      void addLibrary(LibraryElement l) {
         if (!filter.contains(l)) {
           deps.addAll(l.units);
         }
@@ -2037,7 +2083,7 @@
 class ComputePropagableVariableDependenciesTask
     extends InferStaticVariableTask {
   /**
-   * The name of the [RESOLVED_UNIT5] input.
+   * The name of the [RESOLVED_UNIT6] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -2092,7 +2138,7 @@
       CompilationUnitElementImpl unit = target
           .getAncestor((Element element) => element is CompilationUnitElement);
       return <String, TaskInput>{
-        UNIT_INPUT: RESOLVED_UNIT5
+        UNIT_INPUT: RESOLVED_UNIT6
             .of(new LibrarySpecificUnit(unit.librarySource, unit.source))
       };
     }
@@ -2458,11 +2504,11 @@
 }
 
 /**
- * A task that builds [RESOLVED_UNIT11] for a unit.
+ * A task that builds [RESOLVED_UNIT12] for a unit.
  */
 class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT10] input.
+   * The name of the [RESOLVED_UNIT11] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -2478,7 +2524,7 @@
       'EvaluateUnitConstantsTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT11, RESOLVED_UNIT11]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT12, RESOLVED_UNIT12]);
 
   EvaluateUnitConstantsTask(AnalysisContext context, LibrarySpecificUnit target)
       : super(context, target);
@@ -2491,8 +2537,8 @@
     // No actual work needs to be performed; the task manager will ensure that
     // all constants are evaluated before this method is called.
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
-    outputs[RESOLVED_UNIT11] = unit;
-    outputs[CREATED_RESOLVED_UNIT11] = true;
+    outputs[RESOLVED_UNIT12] = unit;
+    outputs[CREATED_RESOLVED_UNIT12] = true;
   }
 
   /**
@@ -2504,7 +2550,7 @@
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
       'libraryElement': LIBRARY_ELEMENT8.of(unit.library),
-      UNIT_INPUT: RESOLVED_UNIT10.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT11.of(unit),
       CONSTANT_VALUES:
           COMPILATION_UNIT_CONSTANTS.of(unit).toListOf(CONSTANT_VALUE),
       'constantExpressionsDependencies':
@@ -2527,7 +2573,7 @@
  */
 class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT10] input.
+   * The name of the [RESOLVED_UNIT11] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -2571,7 +2617,7 @@
    */
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
-    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT10.of(unit)};
+    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT11.of(unit)};
   }
 
   /**
@@ -2589,7 +2635,7 @@
  */
 class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT10] input.
+   * The name of the [RESOLVED_UNIT11] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -2633,7 +2679,7 @@
    */
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
-    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT10.of(unit)};
+    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT11.of(unit)};
   }
 
   /**
@@ -2651,7 +2697,7 @@
  */
 class GenerateHintsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT10] input.
+   * The name of the [RESOLVED_UNIT11] input.
    */
   static const String RESOLVED_UNIT_INPUT = 'RESOLVED_UNIT';
 
@@ -2870,7 +2916,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the input whose value is the [RESOLVED_UNIT7] for the
+   * The name of the input whose value is the [RESOLVED_UNIT8] for the
    * compilation unit.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2882,7 +2928,7 @@
       'InferInstanceMembersInUnitTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT9, RESOLVED_UNIT9]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT10, RESOLVED_UNIT10]);
 
   /**
    * Initialize a newly created task to build a library element for the given
@@ -2906,15 +2952,16 @@
     // Infer instance members.
     //
     if (context.analysisOptions.strongMode) {
-      InstanceMemberInferrer inferrer = new InstanceMemberInferrer(typeProvider,
+      InstanceMemberInferrer inferrer = new InstanceMemberInferrer(
+          typeProvider, new InheritanceManager(unit.element.library),
           typeSystem: context.typeSystem);
       inferrer.inferCompilationUnit(unit.element);
     }
     //
     // Record outputs.
     //
-    outputs[RESOLVED_UNIT9] = unit;
-    outputs[CREATED_RESOLVED_UNIT9] = true;
+    outputs[RESOLVED_UNIT10] = unit;
+    outputs[CREATED_RESOLVED_UNIT10] = true;
   }
 
   /**
@@ -2925,7 +2972,7 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      UNIT_INPUT: RESOLVED_UNIT8.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT9.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
       // In strong mode, add additional dependencies to enforce inference
       // ordering.
@@ -2933,13 +2980,17 @@
       // Require that field re-resolution be complete for all units in the
       // current library cycle.
       'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
-          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT8
-              .of(new LibrarySpecificUnit(unit.librarySource, unit.source))),
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT9.of(
+              new LibrarySpecificUnit(
+                  (unit as CompilationUnitElementImpl).librarySource,
+                  unit.source))),
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
-          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT9
-              .of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+              new LibrarySpecificUnit(
+                  (unit as CompilationUnitElementImpl).librarySource,
+                  unit.source)))
     };
   }
 
@@ -3007,7 +3058,7 @@
  */
 class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the input whose value is the [RESOLVED_UNIT6] for the
+   * The name of the input whose value is the [RESOLVED_UNIT7] for the
    * compilation unit.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3025,7 +3076,7 @@
       'InferStaticVariableTypesInUnitTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT7, RESOLVED_UNIT7]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT8, RESOLVED_UNIT8]);
 
   /**
    * Initialize a newly created task to build a library element for the given
@@ -3049,8 +3100,8 @@
     // because the work has implicitly been done by virtue of the task model
     // preparing all of the inputs.
     //
-    outputs[RESOLVED_UNIT7] = unit;
-    outputs[CREATED_RESOLVED_UNIT7] = true;
+    outputs[RESOLVED_UNIT8] = unit;
+    outputs[CREATED_RESOLVED_UNIT8] = true;
   }
 
   /**
@@ -3064,7 +3115,7 @@
       INFERRED_VARIABLES_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT
           .of(unit)
           .toListOf(INFERRED_STATIC_VARIABLE),
-      UNIT_INPUT: RESOLVED_UNIT6.of(unit)
+      UNIT_INPUT: RESOLVED_UNIT7.of(unit)
     };
   }
 
@@ -3095,7 +3146,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the [RESOLVED_UNIT6] input.
+   * The name of the [RESOLVED_UNIT7] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -3186,15 +3237,17 @@
           .of(variable)
           .toListOf(INFERRED_STATIC_VARIABLE),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      UNIT_INPUT: RESOLVED_UNIT6.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT7.of(unit),
       // In strong mode, add additional dependencies to enforce inference
       // ordering.
 
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
-          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT9
-              .of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+              new LibrarySpecificUnit(
+                  (unit as CompilationUnitElementImpl).librarySource,
+                  unit.source)))
     };
   }
 
@@ -3591,7 +3644,7 @@
 }
 
 /**
- * A task that builds [RESOLVED_UNIT5] for a unit.
+ * A task that builds [RESOLVED_UNIT6] for a unit.
  */
 class PartiallyResolveUnitReferencesTask extends SourceBasedAnalysisTask {
   /**
@@ -3600,7 +3653,7 @@
   static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
 
   /**
-   * The name of the [RESOLVED_UNIT4] input.
+   * The name of the [RESOLVED_UNIT5] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -3618,8 +3671,8 @@
       buildInputs, <ResultDescriptor>[
     INFERABLE_STATIC_VARIABLES_IN_UNIT,
     PROPAGABLE_VARIABLES_IN_UNIT,
-    CREATED_RESOLVED_UNIT5,
-    RESOLVED_UNIT5
+    CREATED_RESOLVED_UNIT6,
+    RESOLVED_UNIT6
   ]);
 
   PartiallyResolveUnitReferencesTask(
@@ -3653,8 +3706,8 @@
       outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = VariableElement.EMPTY_LIST;
     }
     outputs[PROPAGABLE_VARIABLES_IN_UNIT] = visitor.propagableVariables;
-    outputs[RESOLVED_UNIT5] = unit;
-    outputs[CREATED_RESOLVED_UNIT5] = true;
+    outputs[RESOLVED_UNIT6] = unit;
+    outputs[CREATED_RESOLVED_UNIT6] = true;
   }
 
   /**
@@ -3667,7 +3720,7 @@
     return <String, TaskInput>{
       'fullyBuiltLibraryElements': READY_LIBRARY_ELEMENT5.of(unit.library),
       LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library),
-      UNIT_INPUT: RESOLVED_UNIT4.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT5.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
       // In strong mode, add additional dependencies to enforce inference
       // ordering.
@@ -3675,8 +3728,10 @@
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
-          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT9
-              .of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+              new LibrarySpecificUnit(
+                  (unit as CompilationUnitElementImpl).librarySource,
+                  unit.source)))
     };
   }
 
@@ -3787,7 +3842,7 @@
     Source source = target;
     return <String, TaskInput>{
       'propagatedVariableTypesInUnits':
-          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT6),
+          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT7),
       LIBRARY_INPUT: LIBRARY_ELEMENT5.of(source),
     };
   }
@@ -3808,7 +3863,7 @@
  */
 class PropagateVariableTypesInUnitTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the input whose value is the [RESOLVED_UNIT5] for the
+   * The name of the input whose value is the [RESOLVED_UNIT6] for the
    * compilation unit.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3820,7 +3875,7 @@
       'PropagateVariableTypesInUnitTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT6, RESOLVED_UNIT6]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT7, RESOLVED_UNIT7]);
 
   PropagateVariableTypesInUnitTask(
       InternalAnalysisContext context, LibrarySpecificUnit unit)
@@ -3840,8 +3895,8 @@
     // because the work has implicitly been done by virtue of the task model
     // preparing all of the inputs.
     //
-    outputs[RESOLVED_UNIT6] = unit;
-    outputs[CREATED_RESOLVED_UNIT6] = true;
+    outputs[RESOLVED_UNIT7] = unit;
+    outputs[CREATED_RESOLVED_UNIT7] = true;
   }
 
   /**
@@ -3854,7 +3909,7 @@
     return <String, TaskInput>{
       'variables':
           PROPAGABLE_VARIABLES_IN_UNIT.of(unit).toListOf(PROPAGATED_VARIABLE),
-      UNIT_INPUT: RESOLVED_UNIT5.of(unit)
+      UNIT_INPUT: RESOLVED_UNIT6.of(unit)
     };
   }
 
@@ -3879,7 +3934,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the [RESOLVED_UNIT5] input.
+   * The name of the [RESOLVED_UNIT6] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -3965,7 +4020,7 @@
           .of(variable)
           .toListOf(PROPAGATED_VARIABLE),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      UNIT_INPUT: RESOLVED_UNIT5.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT6.of(unit),
     };
   }
 
@@ -4289,7 +4344,7 @@
           'Cannot build inputs for a ${target.runtimeType}');
     }
     return <String, TaskInput>{
-      'createdResolvedUnit': CREATED_RESOLVED_UNIT10
+      'createdResolvedUnit': CREATED_RESOLVED_UNIT11
           .of(new LibrarySpecificUnit(librarySource, target.source))
     };
   }
@@ -4305,6 +4360,80 @@
 }
 
 /**
+ * A task that resolves imports and export directives to already built elements.
+ */
+class ResolveDirectiveElementsTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the input whose value is the defining [LIBRARY_ELEMENT2].
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The name of the input for [RESOLVED_UNIT1] of a unit.
+   */
+  static const String UNIT_INPUT = 'UNIT_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'ResolveDirectiveElementsTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT2, RESOLVED_UNIT2]);
+
+  ResolveDirectiveElementsTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibrarySpecificUnit targetUnit = target;
+    //
+    // Prepare inputs.
+    //
+    CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+    //
+    // Resolve directive AST nodes to elements.
+    //
+    if (targetUnit.unit == targetUnit.library) {
+      DirectiveResolver resolver = new DirectiveResolver();
+      unit.accept(resolver);
+    }
+    //
+    // Record outputs.
+    //
+    outputs[CREATED_RESOLVED_UNIT2] = true;
+    outputs[RESOLVED_UNIT2] = unit;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    LibrarySpecificUnit unit = target;
+    return <String, TaskInput>{
+      LIBRARY_INPUT: LIBRARY_ELEMENT2.of(unit.library),
+      UNIT_INPUT: RESOLVED_UNIT1.of(unit)
+    };
+  }
+
+  /**
+   * Create a [ResolveDirectiveElementsTask] based on the given [target] in
+   * the given [context].
+   */
+  static ResolveDirectiveElementsTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new ResolveDirectiveElementsTask(context, target);
+  }
+}
+
+/**
  * A task that ensures that all of the inferable instance members in a
  * compilation unit have had their right hand sides re-resolved
  */
@@ -4320,7 +4449,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the input whose value is the [RESOLVED_UNIT7] for the
+   * The name of the input whose value is the [RESOLVED_UNIT8] for the
    * compilation unit.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -4332,7 +4461,7 @@
       'ResolveInstanceFieldsInUnitTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT8, RESOLVED_UNIT8]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT9, RESOLVED_UNIT9]);
 
   /**
    * Initialize a newly created task to build a library element for the given
@@ -4377,8 +4506,8 @@
     //
     // Record outputs.
     //
-    outputs[RESOLVED_UNIT8] = unit;
-    outputs[CREATED_RESOLVED_UNIT8] = true;
+    outputs[RESOLVED_UNIT9] = unit;
+    outputs[CREATED_RESOLVED_UNIT9] = true;
   }
 
   /**
@@ -4389,7 +4518,7 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      UNIT_INPUT: RESOLVED_UNIT7.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT8.of(unit),
       LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
       // In strong mode, add additional dependencies to enforce inference
@@ -4398,13 +4527,17 @@
       // Require that static variable inference  be complete for all units in
       // the current library cycle.
       'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
-          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT7
-              .of(new LibrarySpecificUnit(unit.librarySource, unit.source))),
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT8.of(
+              new LibrarySpecificUnit(
+                  (unit as CompilationUnitElementImpl).librarySource,
+                  unit.source))),
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
-          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT9
-              .of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+              new LibrarySpecificUnit(
+                  (unit as CompilationUnitElementImpl).librarySource,
+                  unit.source)))
     };
   }
 
@@ -4419,7 +4552,7 @@
 }
 
 /**
- * A task that finishes resolution by requesting [RESOLVED_UNIT10] for every
+ * A task that finishes resolution by requesting [RESOLVED_UNIT11] for every
  * unit in the libraries closure and produces [LIBRARY_ELEMENT8].
  */
 class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask {
@@ -4429,7 +4562,7 @@
   static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
 
   /**
-   * The name of the list of [RESOLVED_UNIT10] input.
+   * The name of the list of [RESOLVED_UNIT11] input.
    */
   static const String UNITS_INPUT = 'UNITS_INPUT';
 
@@ -4477,7 +4610,7 @@
     Source source = target;
     return <String, TaskInput>{
       LIBRARY_INPUT: LIBRARY_ELEMENT7.of(source),
-      UNITS_INPUT: LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT10),
+      UNITS_INPUT: LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT11),
     };
   }
 
@@ -4492,7 +4625,7 @@
 }
 
 /**
- * A task that finishes resolution by requesting [RESOLVED_UNIT11] for every
+ * A task that finishes resolution by requesting [RESOLVED_UNIT12] for every
  * unit in the libraries closure and produces [LIBRARY_ELEMENT].
  */
 class ResolveLibraryTask extends SourceBasedAnalysisTask {
@@ -4502,7 +4635,7 @@
   static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
 
   /**
-   * The name of the list of [RESOLVED_UNIT11] input.
+   * The name of the list of [RESOLVED_UNIT12] input.
    */
   static const String UNITS_INPUT = 'UNITS_INPUT';
 
@@ -4613,7 +4746,7 @@
     Source source = target;
     return <String, TaskInput>{
       'resolvedUnit':
-          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT3),
+          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT4),
       LIBRARY_INPUT: LIBRARY_ELEMENT4.of(source),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
     };
@@ -4645,7 +4778,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the [RESOLVED_UNIT9] input.
+   * The name of the [RESOLVED_UNIT10] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -4653,8 +4786,8 @@
       'ResolveUnitTask', createTask, buildInputs, <ResultDescriptor>[
     CONSTANT_EXPRESSIONS_DEPENDENCIES,
     RESOLVE_UNIT_ERRORS,
-    CREATED_RESOLVED_UNIT10,
-    RESOLVED_UNIT10
+    CREATED_RESOLVED_UNIT11,
+    RESOLVED_UNIT11
   ]);
 
   ResolveUnitTask(
@@ -4700,8 +4833,8 @@
     //
     outputs[CONSTANT_EXPRESSIONS_DEPENDENCIES] = constExprDependencies;
     outputs[RESOLVE_UNIT_ERRORS] = getTargetSourceErrors(errorListener, target);
-    outputs[RESOLVED_UNIT10] = unit;
-    outputs[CREATED_RESOLVED_UNIT10] = true;
+    outputs[RESOLVED_UNIT11] = unit;
+    outputs[CREATED_RESOLVED_UNIT11] = true;
   }
 
   /**
@@ -4714,15 +4847,17 @@
     return <String, TaskInput>{
       LIBRARY_INPUT: LIBRARY_ELEMENT7.of(unit.library),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      UNIT_INPUT: RESOLVED_UNIT9.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT10.of(unit),
       // In strong mode, add additional dependencies to enforce inference
       // ordering.
 
       // Require that inference be complete for all units in the
       // current library cycle.
       'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
-          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT9
-              .of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+              new LibrarySpecificUnit(
+                  (unit as CompilationUnitElementImpl).librarySource,
+                  unit.source)))
     };
   }
 
@@ -4737,7 +4872,7 @@
 }
 
 /**
- * A task that builds [RESOLVED_UNIT3] for a unit.
+ * A task that builds [RESOLVED_UNIT4] for a unit.
  */
 class ResolveUnitTypeNamesTask extends SourceBasedAnalysisTask {
   /**
@@ -4746,7 +4881,7 @@
   static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
 
   /**
-   * The name of the [RESOLVED_UNIT2] input.
+   * The name of the [RESOLVED_UNIT3] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -4761,8 +4896,8 @@
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
       'ResolveUnitTypeNamesTask', createTask, buildInputs, <ResultDescriptor>[
     RESOLVE_TYPE_NAMES_ERRORS,
-    CREATED_RESOLVED_UNIT3,
-    RESOLVED_UNIT3
+    CREATED_RESOLVED_UNIT4,
+    RESOLVED_UNIT4
   ]);
 
   ResolveUnitTypeNamesTask(
@@ -4793,8 +4928,8 @@
     //
     outputs[RESOLVE_TYPE_NAMES_ERRORS] =
         getTargetSourceErrors(errorListener, target);
-    outputs[RESOLVED_UNIT3] = unit;
-    outputs[CREATED_RESOLVED_UNIT3] = true;
+    outputs[RESOLVED_UNIT4] = unit;
+    outputs[CREATED_RESOLVED_UNIT4] = true;
   }
 
   /**
@@ -4811,7 +4946,7 @@
       'importsExportNamespace':
           IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4),
       LIBRARY_INPUT: LIBRARY_ELEMENT4.of(unit.library),
-      UNIT_INPUT: RESOLVED_UNIT2.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT3.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
     };
   }
@@ -4827,7 +4962,7 @@
 }
 
 /**
- * A task that builds [RESOLVED_UNIT4] for a unit.
+ * A task that builds [RESOLVED_UNIT5] for a unit.
  */
 class ResolveVariableReferencesTask extends SourceBasedAnalysisTask {
   /**
@@ -4836,7 +4971,7 @@
   static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
 
   /**
-   * The name of the [RESOLVED_UNIT3] input.
+   * The name of the [RESOLVED_UNIT4] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -4852,8 +4987,8 @@
       'ResolveVariableReferencesTask',
       createTask,
       buildInputs, <ResultDescriptor>[
-    CREATED_RESOLVED_UNIT4,
-    RESOLVED_UNIT4,
+    CREATED_RESOLVED_UNIT5,
+    RESOLVED_UNIT5,
     VARIABLE_REFERENCE_ERRORS
   ]);
 
@@ -4885,8 +5020,8 @@
     //
     // Record outputs.
     //
-    outputs[RESOLVED_UNIT4] = unit;
-    outputs[CREATED_RESOLVED_UNIT4] = true;
+    outputs[RESOLVED_UNIT5] = unit;
+    outputs[CREATED_RESOLVED_UNIT5] = true;
     outputs[VARIABLE_REFERENCE_ERRORS] =
         getTargetSourceErrors(errorListener, target);
   }
@@ -4900,7 +5035,7 @@
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
       LIBRARY_INPUT: LIBRARY_ELEMENT1.of(unit.library),
-      UNIT_INPUT: RESOLVED_UNIT3.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT4.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
     };
   }
@@ -5052,7 +5187,7 @@
  */
 class StrongModeVerifyUnitTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT11] input.
+   * The name of the [RESOLVED_UNIT12] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -5108,7 +5243,7 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      UNIT_INPUT: RESOLVED_UNIT11.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT12.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
     };
   }
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index a586b3b..0122c88 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -30,7 +30,8 @@
   /**
    * The list of errors that are reported for raw Dart [Source]s.
    */
-  static final List<ResultDescriptor> _SOURCE_ERRORS = <ResultDescriptor>[
+  static final List<ResultDescriptor<List<AnalysisError>>> _SOURCE_ERRORS =
+      <ResultDescriptor<List<AnalysisError>>>[
     BUILD_DIRECTIVES_ERRORS,
     BUILD_LIBRARY_ERRORS,
     PARSE_ERRORS,
@@ -40,7 +41,8 @@
   /**
    * The list of errors that are reported for raw Dart [LibrarySpecificUnit]s.
    */
-  static final List<ResultDescriptor> _UNIT_ERRORS = <ResultDescriptor>[
+  static final List<ResultDescriptor<List<AnalysisError>>> _UNIT_ERRORS =
+      <ResultDescriptor<List<AnalysisError>>>[
     HINTS,
     LINTS,
     LIBRARY_UNIT_ERRORS,
@@ -178,12 +180,12 @@
     }
     // If analysis is in progress, combine all known partial results.
     List<AnalysisError> errors = <AnalysisError>[];
-    for (ResultDescriptor descriptor in _SOURCE_ERRORS) {
+    for (ResultDescriptor<List<AnalysisError>> descriptor in _SOURCE_ERRORS) {
       errors.addAll(analysisCache.getValue(source, descriptor));
     }
     for (Source library in context.getLibrariesContaining(source)) {
       LibrarySpecificUnit unit = new LibrarySpecificUnit(library, source);
-      for (ResultDescriptor descriptor in _UNIT_ERRORS) {
+      for (ResultDescriptor<List<AnalysisError>> descriptor in _UNIT_ERRORS) {
         errors.addAll(analysisCache.getValue(unit, descriptor));
       }
     }
@@ -304,7 +306,7 @@
     // Update parts in libraries.
     if (isDartLibrarySource) {
       Source library = target;
-      List<Source> includedParts = outputs[INCLUDED_PARTS];
+      List<Source> includedParts = outputs[INCLUDED_PARTS] as List<Source>;
       if (includedParts != null) {
         libraryPartsMap[library] = includedParts;
         for (Source part in includedParts) {
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index 7ff8287..c41c41a 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -597,7 +597,7 @@
    * or `null` if all of the inputs have been collected and the task can be
    * created.
    */
-  TaskInputBuilder builder;
+  TopLevelTaskInputBuilder builder;
 
   /**
    * The [TargetedResult]s outputs of this task depends on.
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index ae1fb0d..2575677 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -166,7 +166,7 @@
    * input descriptors describing those inputs for a task with the
    * given [target].
    */
-  static Map<String, TaskInput> buildInputs(Source target) {
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     return <String, TaskInput>{DOCUMENT_INPUT: HTML_DOCUMENT.of(target)};
   }
 
@@ -237,7 +237,7 @@
    * input descriptors describing those inputs for a task with the
    * given [target].
    */
-  static Map<String, TaskInput> buildInputs(Source target) {
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin;
     Map<String, TaskInput> inputs = <String, TaskInput>{
       DART_ERRORS_INPUT: DART_SCRIPTS.of(target).toListOf(DART_ERRORS)
@@ -342,7 +342,7 @@
    * input descriptors describing those inputs for a task with the given
    * [source].
    */
-  static Map<String, TaskInput> buildInputs(Source source) {
+  static Map<String, TaskInput> buildInputs(AnalysisTarget source) {
     return <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)};
   }
 
diff --git a/pkg/analyzer/lib/src/task/inputs.dart b/pkg/analyzer/lib/src/task/inputs.dart
index 7553e15..cb497b6 100644
--- a/pkg/analyzer/lib/src/task/inputs.dart
+++ b/pkg/analyzer/lib/src/task/inputs.dart
@@ -39,7 +39,7 @@
  * A [TaskInputBuilder] used to build an input based on a [ConstantTaskInput].
  */
 class ConstantTaskInputBuilder<V> implements TaskInputBuilder<V> {
-  final ConstantTaskInput input;
+  final ConstantTaskInput<V> input;
 
   ConstantTaskInputBuilder(this.input);
 
@@ -159,7 +159,7 @@
 
   @override
   void _addResultElement(B baseElement, E resultElement) {
-    _resultValue.addAll(resultElement as Iterable);
+    _resultValue.addAll(resultElement as Iterable<E>);
   }
 
   @override
@@ -418,6 +418,8 @@
 class ObjectToListTaskInput<E> extends TaskInputImpl<List<E>>
     with ListTaskInputMixin<E>
     implements ListTaskInput<E> {
+  // TODO(brianwilkerson) Add another type parameter to this class that can be
+  // used as the type of the keys of [mapper].
   /**
    * The input used to compute the value to be mapped.
    */
diff --git a/pkg/analyzer/lib/src/task/model.dart b/pkg/analyzer/lib/src/task/model.dart
index 56e2827..47de4b3 100644
--- a/pkg/analyzer/lib/src/task/model.dart
+++ b/pkg/analyzer/lib/src/task/model.dart
@@ -11,7 +11,7 @@
 /**
  * The default [ResultCachingPolicy], results are never flushed.
  */
-const ResultCachingPolicy DEFAULT_CACHING_POLICY =
+const ResultCachingPolicy<Object> DEFAULT_CACHING_POLICY =
     const SimpleResultCachingPolicy(-1, -1);
 
 /**
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 8c6980b..d3cc82f 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -168,36 +168,36 @@
   @override
   void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
     var analyzer = options[AnalyzerOptions.analyzer];
-    if (analyzer is! YamlMap) {
-      return;
-    }
-
-    var filters = analyzer[AnalyzerOptions.errors];
-    if (filters is YamlMap) {
-      String value;
-      filters.nodes.forEach((k, v) {
-        if (k is YamlScalar) {
-          value = toUpperCase(k.value);
-          if (!errorCodes.contains(value)) {
-            reporter.reportErrorForSpan(
-                AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
-                k.span,
-                [k.value?.toString()]);
+    if (analyzer is YamlMap) {
+      var filters = analyzer[AnalyzerOptions.errors];
+      if (filters is YamlMap) {
+        String value;
+        filters.nodes.forEach((k, v) {
+          if (k is YamlScalar) {
+            value = toUpperCase(k.value);
+            if (!errorCodes.contains(value)) {
+              reporter.reportErrorForSpan(
+                  AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
+                  k.span,
+                  [k.value?.toString()]);
+            }
           }
-        }
-        if (v is YamlScalar) {
-          value = toLowerCase(v.value);
-          if (!legalValues.contains(value)) {
-            reporter.reportErrorForSpan(
-                AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES,
-                v.span, [
-              AnalyzerOptions.errors,
-              v.value?.toString(),
-              legalValueString
-            ]);
+          if (v is YamlScalar) {
+            value = toLowerCase(v.value);
+            if (!legalValues.contains(value)) {
+              reporter.reportErrorForSpan(
+                  AnalysisOptionsWarningCode
+                      .UNSUPPORTED_OPTION_WITH_LEGAL_VALUES,
+                  v.span,
+                  [
+                    AnalyzerOptions.errors,
+                    v.value?.toString(),
+                    legalValueString
+                  ]);
+            }
           }
-        }
-      });
+        });
+      }
     }
   }
 }
@@ -255,7 +255,7 @@
   /// Return a map from the names of the inputs of this kind of task to the
   /// task input descriptors describing those inputs for a task with the
   /// given [target].
-  static Map<String, TaskInput> buildInputs(Source source) =>
+  static Map<String, TaskInput> buildInputs(AnalysisTarget source) =>
       <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)};
 
   /// Compute [LineInfo] for the given [content].
@@ -289,31 +289,29 @@
   @override
   void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
     var analyzer = options[AnalyzerOptions.analyzer];
-    if (analyzer is! YamlMap) {
-      return;
-    }
-
-    var language = analyzer[AnalyzerOptions.language];
-    if (language is YamlMap) {
-      language.nodes.forEach((k, v) {
-        String key, value;
-        bool validKey = false;
-        if (k is YamlScalar) {
-          key = k.value?.toString();
-          if (!AnalyzerOptions.languageOptions.contains(key)) {
-            builder.reportError(reporter, AnalyzerOptions.language, k);
-          } else {
-            // If we have a valid key, go on and check the value.
-            validKey = true;
+    if (analyzer is YamlMap) {
+      var language = analyzer[AnalyzerOptions.language];
+      if (language is YamlMap) {
+        language.nodes.forEach((k, v) {
+          String key, value;
+          bool validKey = false;
+          if (k is YamlScalar) {
+            key = k.value?.toString();
+            if (!AnalyzerOptions.languageOptions.contains(key)) {
+              builder.reportError(reporter, AnalyzerOptions.language, k);
+            } else {
+              // If we have a valid key, go on and check the value.
+              validKey = true;
+            }
           }
-        }
-        if (validKey && v is YamlScalar) {
-          value = toLowerCase(v.value);
-          if (!AnalyzerOptions.trueOrFalse.contains(value)) {
-            trueOrFalseBuilder.reportError(reporter, key, v);
+          if (validKey && v is YamlScalar) {
+            value = toLowerCase(v.value);
+            if (!AnalyzerOptions.trueOrFalse.contains(value)) {
+              trueOrFalseBuilder.reportError(reporter, key, v);
+            }
           }
-        }
-      });
+        });
+      }
     }
   }
 }
@@ -352,16 +350,14 @@
   @override
   void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
     var analyzer = options[AnalyzerOptions.analyzer];
-    if (analyzer is! YamlMap) {
-      return;
-    }
-
-    var v = analyzer.nodes[AnalyzerOptions.strong_mode];
-    if (v is YamlScalar) {
-      var value = toLowerCase(v.value);
-      if (!AnalyzerOptions.trueOrFalse.contains(value)) {
-        trueOrFalseBuilder.reportError(
-            reporter, AnalyzerOptions.strong_mode, v);
+    if (analyzer is YamlMap) {
+      var v = analyzer.nodes[AnalyzerOptions.strong_mode];
+      if (v is YamlScalar) {
+        var value = toLowerCase(v.value);
+        if (!AnalyzerOptions.trueOrFalse.contains(value)) {
+          trueOrFalseBuilder.reportError(
+              reporter, AnalyzerOptions.strong_mode, v);
+        }
       }
     }
   }
@@ -431,17 +427,16 @@
       return;
     }
     var analyzer = optionMap[AnalyzerOptions.analyzer];
-    if (analyzer is! Map) {
-      return;
+    if (analyzer is Map) {
+      // Process strong mode option.
+      var strongMode = analyzer[AnalyzerOptions.strong_mode];
+      if (strongMode is bool) {
+        options.strongMode = strongMode;
+      }
+      // Process language options.
+      var language = analyzer[AnalyzerOptions.language];
+      _applyLanguageOptions(options, language);
     }
-    // Process strong mode option.
-    var strongMode = analyzer[AnalyzerOptions.strong_mode];
-    if (strongMode is bool) {
-      options.strongMode = strongMode;
-    }
-    // Process language options.
-    var language = analyzer[AnalyzerOptions.language];
-    _applyLanguageOptions(options, language);
   }
 
   /// Configure [context] based on the given [options] (which can be `null`
@@ -452,21 +447,19 @@
     }
 
     var analyzer = options[AnalyzerOptions.analyzer];
-    if (analyzer is! Map) {
-      return;
+    if (analyzer is Map) {
+      // Set strong mode (default is false).
+      var strongMode = analyzer[AnalyzerOptions.strong_mode];
+      setStrongMode(context, strongMode);
+
+      // Set filters.
+      var filters = analyzer[AnalyzerOptions.errors];
+      setProcessors(context, filters);
+
+      // Process language options.
+      var language = analyzer[AnalyzerOptions.language];
+      setLanguageOptions(context, language);
     }
-
-    // Set strong mode (default is false).
-    var strongMode = analyzer[AnalyzerOptions.strong_mode];
-    setStrongMode(context, strongMode);
-
-    // Set filters.
-    var filters = analyzer[AnalyzerOptions.errors];
-    setProcessors(context, filters);
-
-    // Process language options.
-    var language = analyzer[AnalyzerOptions.language];
-    setLanguageOptions(context, language);
   }
 
   void setLanguageOption(
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index 0ab8a8b..233e5c4 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -29,7 +29,10 @@
   if (field is PropertyInducingElementImpl) {
     (field.getter as ExecutableElementImpl).returnType = newType;
     if (!field.isFinal && !field.isConst) {
-      (field.setter.parameters[0] as ParameterElementImpl).type = newType;
+      List<ParameterElement> setterParameters = field.setter.parameters;
+      if (setterParameters.isNotEmpty) {
+        (setterParameters[0] as ParameterElementImpl).type = newType;
+      }
     }
   }
 }
@@ -72,7 +75,7 @@
   /**
    * The inheritance manager used to find overridden method.
    */
-  InheritanceManager inheritanceManager;
+  final InheritanceManager inheritanceManager;
 
   /**
    * The classes that have been visited while attempting to infer the types of
@@ -84,7 +87,8 @@
   /**
    * Initialize a newly create inferrer.
    */
-  InstanceMemberInferrer(this.typeProvider, {TypeSystem typeSystem})
+  InstanceMemberInferrer(this.typeProvider, this.inheritanceManager,
+      {TypeSystem typeSystem})
       : typeSystem = (typeSystem != null) ? typeSystem : new TypeSystemImpl();
 
   /**
@@ -92,7 +96,6 @@
    * compilation [unit].
    */
   void inferCompilationUnit(CompilationUnitElement unit) {
-    inheritanceManager = new InheritanceManager(unit.library);
     unit.types.forEach((ClassElement classElement) {
       try {
         _inferClass(classElement);
diff --git a/pkg/analyzer/lib/src/task/yaml.dart b/pkg/analyzer/lib/src/task/yaml.dart
index 1e1951c..e83fa8c 100644
--- a/pkg/analyzer/lib/src/task/yaml.dart
+++ b/pkg/analyzer/lib/src/task/yaml.dart
@@ -100,7 +100,7 @@
    * input descriptors describing those inputs for a task with the given
    * [source].
    */
-  static Map<String, TaskInput> buildInputs(Source source) {
+  static Map<String, TaskInput> buildInputs(AnalysisTarget source) {
     return <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)};
   }
 
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/task/model.dart
index b80cca2..be60b78 100644
--- a/pkg/analyzer/lib/task/model.dart
+++ b/pkg/analyzer/lib/task/model.dart
@@ -465,7 +465,7 @@
    * never evicted from the cache, and removed only when they are invalidated.
    */
   factory ResultDescriptor(String name, V defaultValue,
-      {ResultCachingPolicy<V> cachingPolicy}) = ResultDescriptorImpl;
+      {ResultCachingPolicy<V> cachingPolicy}) = ResultDescriptorImpl<V>;
 
   /**
    * Return the caching policy for results described by this descriptor.
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 7c34d93..4b0b2ad 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.27.3-alpha.6
+version: 0.27.3-alpha.7
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 52e3030..f922d25 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/source/embedder.dart';
+import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/context/source.dart';
@@ -417,14 +418,15 @@
   }
 
   @override
-  Future<CompilationUnit> computeResolvedCompilationUnitAsync(
+  CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync(
       Source source, Source librarySource) {
     fail("Unexpected invocation of getResolvedCompilationUnitFuture");
     return null;
   }
 
   @override
-  Object computeResult(AnalysisTarget target, ResultDescriptor result) {
+  Object/*=V*/ computeResult/*<V>*/(
+      AnalysisTarget target, ResultDescriptor/*<V>*/ result) {
     fail("Unexpected invocation of computeResult");
     return null;
   }
@@ -460,7 +462,7 @@
   }
 
   @override
-  Object getConfigurationData(ResultDescriptor key) {
+  Object/*=V*/ getConfigurationData/*<V>*/(ResultDescriptor/*<V>*/ key) {
     fail("Unexpected invocation of getConfigurationData");
     return null;
   }
@@ -564,7 +566,8 @@
   }
 
   @override
-  Object getResult(AnalysisTarget target, ResultDescriptor result) {
+  Object/*=V*/ getResult/*<V>*/(
+      AnalysisTarget target, ResultDescriptor/*<V>*/ result) {
     fail("Unexpected invocation of getResult");
     return null;
   }
@@ -605,6 +608,7 @@
     return null;
   }
 
+  @deprecated
   @override
   Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) {
     fail("Unexpected invocation of onResultComputed");
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 536553b..fa3da21 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -107,7 +107,11 @@
 const _MustCallSuper mustCallSuper = const _MustCallSuper();
 const _Override override = const _Override();
 const _Protected protected = const _Protected();
-const _Required required = const _Required();
+const Required required = const Required();
+class Required {
+  final String reason;
+  const Required([this.reason]);
+}
 
 class _Factory {
   const _Factory();
@@ -1523,6 +1527,104 @@
     verify([source]);
   }
 
+  void test_required_constructor_param() {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class C {
+  C({@Required('must specify an `a`') int a}) {}
+}
+
+main() {
+  new C();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
+    verify([source]);
+  }
+
+  void test_required_constructor_param_no_reason() {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class C {
+  C({@required int a}) {}
+}
+
+main() {
+  new C();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
+    verify([source]);
+  }
+
+  void test_required_constructor_param_null_reason() {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class C {
+  C({@Required(null) int a}) {}
+}
+
+main() {
+  new C();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
+    verify([source]);
+  }
+
+  void test_required_constructor_param_OK() {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class C {
+  C({@required int a}) {}
+}
+
+main() {
+  new C(a: 2);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_required_function_param() {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+void f({@Required('must specify an `a`') int a}) {}
+
+main() {
+  f();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
+    verify([source]);
+  }
+
+  void test_required_method_param() {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+  void m({@Required('must specify an `a`') int a}) {}
+}
+f() {
+  new A().m();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
+    verify([source]);
+  }
+
   void test_typeCheck_type_is_Null() {
     Source source = addSource(r'''
 m(i) {
@@ -2709,6 +2811,15 @@
     verify([source, source2]);
   }
 
+  void test_unusedImport_inComment_libraryDirective() {
+    Source source = addSource(r'''
+/// Use [Future] class.
+library L;
+import 'dart:async';
+''');
+    assertNoErrors(source);
+  }
+
   void test_unusedImport_show() {
     Source source = addSource(r'''
 library L;
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index afd10bf..80c41e1 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -4905,8 +4905,9 @@
     _assertCacheUnitResult(RESOLVED_UNIT8);
     _assertCacheUnitResult(RESOLVED_UNIT9);
     _assertCacheUnitResult(RESOLVED_UNIT10);
+    _assertCacheUnitResult(RESOLVED_UNIT11);
     if (expectCachePostConstantsValid) {
-      _assertCacheUnitResult(RESOLVED_UNIT11);
+      _assertCacheUnitResult(RESOLVED_UNIT12);
       _assertCacheUnitResult(RESOLVED_UNIT);
     }
   }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 9fc01e2..1e6878d 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2033,6 +2033,24 @@
         "static var x;", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
   }
 
+  void test_string_unterminated_interpolation_block() {
+    ParserTestCase.parseCompilationUnit(
+        r'''
+m() {
+ {
+ '${${
+''',
+        [
+          ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN,
+        ]);
+  }
+
   void test_switchHasCaseAfterDefaultCase() {
     parse4(
         "parseSwitchStatement",
@@ -3500,7 +3518,7 @@
 
   void test_expressionList_multiple_end() {
     List<Expression> result = parse4("parseExpressionList", ", 2, 3, 4",
-        [ParserErrorCode.MISSING_IDENTIFIER]);
+        [ParserErrorCode.MISSING_IDENTIFIER]) as List<Expression>;
     expect(result, hasLength(4));
     Expression syntheticExpression = result[0];
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
@@ -3510,7 +3528,7 @@
 
   void test_expressionList_multiple_middle() {
     List<Expression> result = parse4("parseExpressionList", "1, 2, , 4",
-        [ParserErrorCode.MISSING_IDENTIFIER]);
+        [ParserErrorCode.MISSING_IDENTIFIER]) as List<Expression>;
     expect(result, hasLength(4));
     Expression syntheticExpression = result[2];
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
@@ -3520,7 +3538,7 @@
 
   void test_expressionList_multiple_start() {
     List<Expression> result = parse4("parseExpressionList", "1, 2, 3,",
-        [ParserErrorCode.MISSING_IDENTIFIER]);
+        [ParserErrorCode.MISSING_IDENTIFIER]) as List<Expression>;
     expect(result, hasLength(4));
     Expression syntheticExpression = result[3];
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
@@ -6067,7 +6085,8 @@
   }
 
   void test_parseCombinators_h() {
-    List<Combinator> combinators = parse4("parseCombinators", "hide a;");
+    List<Combinator> combinators =
+        parse4("parseCombinators", "hide a;") as List<Combinator>;
     expect(combinators, hasLength(1));
     HideCombinator combinator = combinators[0] as HideCombinator;
     expect(combinator, isNotNull);
@@ -6076,7 +6095,8 @@
   }
 
   void test_parseCombinators_hs() {
-    List<Combinator> combinators = parse4("parseCombinators", "hide a show b;");
+    List<Combinator> combinators =
+        parse4("parseCombinators", "hide a show b;") as List<Combinator>;
     expect(combinators, hasLength(2));
     HideCombinator hideCombinator = combinators[0] as HideCombinator;
     expect(hideCombinator, isNotNull);
@@ -6090,12 +6110,14 @@
 
   void test_parseCombinators_hshs() {
     List<Combinator> combinators =
-        parse4("parseCombinators", "hide a show b hide c show d;");
+        parse4("parseCombinators", "hide a show b hide c show d;")
+        as List<Combinator>;
     expect(combinators, hasLength(4));
   }
 
   void test_parseCombinators_s() {
-    List<Combinator> combinators = parse4("parseCombinators", "show a;");
+    List<Combinator> combinators =
+        parse4("parseCombinators", "show a;") as List<Combinator>;
     expect(combinators, hasLength(1));
     ShowCombinator combinator = combinators[0] as ShowCombinator;
     expect(combinator, isNotNull);
@@ -6256,7 +6278,8 @@
         TokenType.MULTI_LINE_COMMENT, "/** xxx [a] yyy [bb] zzz */", 3);
     List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[token];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     List<Token> tokenReferences = token.references;
     expect(references, hasLength(2));
     expect(tokenReferences, hasLength(2));
@@ -6288,7 +6311,8 @@
           TokenType.MULTI_LINE_COMMENT, "/** [ some text", 5)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6303,7 +6327,8 @@
           TokenType.MULTI_LINE_COMMENT, "/** [namePrefix some text", 5)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6320,7 +6345,8 @@
           TokenType.SINGLE_LINE_COMMENT, "/// x [c]", 28)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, hasLength(3));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6342,7 +6368,8 @@
           "/**\n *     a[i]\n * non-code line\n */", 3)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, isEmpty);
   }
 
@@ -6354,7 +6381,8 @@
           TokenType.SINGLE_LINE_COMMENT, "///     a[i] == b[i]", 0)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, isEmpty);
   }
 
@@ -6364,7 +6392,8 @@
           TokenType.MULTI_LINE_COMMENT, "/** [:xxx [a] yyy:] [b] zzz */", 3)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6378,7 +6407,8 @@
           TokenType.MULTI_LINE_COMMENT, "/** `a[i]` and [b] */", 0)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6392,7 +6422,8 @@
           TokenType.MULTI_LINE_COMMENT, "/** `a[i] and [b] */", 0)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, hasLength(2));
   }
 
@@ -6402,7 +6433,8 @@
           "/**\n *     a[i]\n * xxx [i] zzz\n */", 3)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6416,7 +6448,8 @@
           "/** [a]: http://www.google.com (Google) [b] zzz */", 3)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6430,7 +6463,8 @@
           "/** [a](http://www.google.com) [b] zzz */", 3)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6444,7 +6478,8 @@
           TokenType.MULTI_LINE_COMMENT, "/** [a][c] [b] zzz */", 3)
     ];
     List<CommentReference> references =
-        parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "")
+        as List<CommentReference>;
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -7405,12 +7440,14 @@
   }
 
   void test_parseExpressionList_multiple() {
-    List<Expression> result = parse4("parseExpressionList", "1, 2, 3");
+    List<Expression> result =
+        parse4("parseExpressionList", "1, 2, 3") as List<Expression>;
     expect(result, hasLength(3));
   }
 
   void test_parseExpressionList_single() {
-    List<Expression> result = parse4("parseExpressionList", "1");
+    List<Expression> result =
+        parse4("parseExpressionList", "1") as List<Expression>;
     expect(result, hasLength(1));
   }
 
@@ -8365,12 +8402,14 @@
   }
 
   void test_parseIdentifierList_multiple() {
-    List<SimpleIdentifier> list = parse4("parseIdentifierList", "a, b, c");
+    List<SimpleIdentifier> list =
+        parse4("parseIdentifierList", "a, b, c") as List<SimpleIdentifier>;
     expect(list, hasLength(3));
   }
 
   void test_parseIdentifierList_single() {
-    List<SimpleIdentifier> list = parse4("parseIdentifierList", "a");
+    List<SimpleIdentifier> list =
+        parse4("parseIdentifierList", "a") as List<SimpleIdentifier>;
     expect(list, hasLength(1));
   }
 
diff --git a/pkg/analyzer/test/source/error_processor_test.dart b/pkg/analyzer/test/source/error_processor_test.dart
index d7aaeee..ca088967 100644
--- a/pkg/analyzer/test/source/error_processor_test.dart
+++ b/pkg/analyzer/test/source/error_processor_test.dart
@@ -95,7 +95,8 @@
     group('processing', () {
       test('yaml map', () {
         var options = optionsProvider.getOptionsFromString(config);
-        var errorConfig = new ErrorConfig(options['analyzer']['errors']);
+        var errorConfig =
+            new ErrorConfig((options['analyzer'] as YamlMap)['errors']);
         expect(errorConfig.processors, hasLength(2));
 
         // ignore
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index 0017961..7453505 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -21,7 +21,8 @@
 
 @reflectiveTest
 class _PackageMapUriResolverTest {
-  static const Map EMPTY_MAP = const <String, List<Folder>>{};
+  static const Map<String, List<Folder>> EMPTY_MAP =
+      const <String, List<Folder>>{};
   MemoryResourceProvider provider = new MemoryResourceProvider();
 
   void test_isPackageUri() {
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index b2e1f04..e19a173 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -1931,14 +1931,14 @@
     LibrarySpecificUnit unitA = new LibrarySpecificUnit(sourceA, sourceA);
     for (int i = 0; i < 10000; i++) {
       context.performAnalysisTask();
-      if (context.getResult(unitA, RESOLVED_UNIT2) != null) {
+      if (context.getResult(unitA, RESOLVED_UNIT3) != null) {
         break;
       }
     }
     // Update the source.
     // This should invalidate all the results and also reset the driver.
     context.setContents(sourceA, "library semicolonWasAdded;");
-    expect(context.getResult(unitA, RESOLVED_UNIT2), isNull);
+    expect(context.getResult(unitA, RESOLVED_UNIT3), isNull);
     expect(analysisDriver.currentWorkOrder, isNull);
     // Continue analysis.
     _analyzeAll_assertFinished();
@@ -2130,6 +2130,7 @@
     entry.setState(RESOLVED_UNIT9, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
 
     context.resolveCompilationUnit2(source, source);
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 77a68eb..ce4b499 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -420,7 +420,7 @@
   }
 
   void _assertLocate(CompilationUnit unit, int start, int end,
-      Predicate<AstNode> predicate, Type expectedClass) {
+      Predicate<Object> predicate, Type expectedClass) {
     NodeLocator locator = new NodeLocator(start, end);
     AstNode node = locator.searchWithin(unit);
     expect(node, isNotNull);
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index cb64c4c..0904904 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -601,7 +601,7 @@
   }
 
   void test_hasKnownValue_list_invalidElement() {
-    expect(_listValue([_dynamicValue]).hasKnownValue, isTrue);
+    expect(_listValue([_dynamicValue()]).hasKnownValue, isTrue);
   }
 
   void test_hasKnownValue_list_valid() {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index c0077e2..13c09c1 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -90,6 +90,11 @@
     // TODO(scheglov) fix me
   }
 
+  @override
+  void test_unused_type_parameter() {
+    // TODO(paulberry): fix.
+  }
+
   TestSummaryResynthesizer _encodeLibrary(Source source) {
     addLibrary('dart:core');
     _serializeLibrary(source);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index dc8fd6d..aa938d7 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -480,6 +480,17 @@
           fail('Prefix of type ${o.prefix.staticElement.runtimeType} should not'
               ' have been elided');
         }
+      } else if (o is SimpleIdentifier && r is PrefixedIdentifier) {
+        // In 'class C {static const a = 0; static const b = a;}' the reference
+        // to 'a' in 'b' is serialized as a fully qualified 'C.a' reference.
+        if (r.prefix.staticElement is ClassElement) {
+          compareElements(
+              r.prefix.staticElement, o.staticElement?.enclosingElement, desc);
+          compareConstAsts(r.identifier, o, desc);
+        } else {
+          fail('Prefix of type ${r.prefix.staticElement.runtimeType} should not'
+              ' have been elided');
+        }
       } else if (o is PropertyAccess &&
           o.target is PrefixedIdentifier &&
           r is PrefixedIdentifier) {
@@ -558,6 +569,13 @@
         compareConstAstLists(
             r.typeArguments?.arguments, o.typeArguments?.arguments, desc);
         compareConstAstLists(r.entries, o.entries, desc);
+      } else if (o is MethodInvocation && r is MethodInvocation) {
+        compareConstAsts(r.target, o.target, desc);
+        compareConstAsts(r.methodName, o.methodName, desc);
+        compareConstAstLists(
+            r.typeArguments?.arguments, o.typeArguments?.arguments, desc);
+        compareConstAstLists(
+            r.argumentList?.arguments, o.argumentList?.arguments, desc);
       } else if (o is InstanceCreationExpression &&
           r is InstanceCreationExpression) {
         compareElements(r.staticElement, o.staticElement, desc);
@@ -1076,8 +1094,20 @@
       expect(resynthesized.typeArguments.length, original.typeArguments.length,
           reason: desc);
       for (int i = 0; i < resynthesized.typeArguments.length; i++) {
-        compareTypes(resynthesized.typeArguments[i], original.typeArguments[i],
-            '$desc type argument ${original.typeArguments[i].name}');
+        if (resynthesized.typeArguments[i].isDynamic &&
+            original.typeArguments[i] is TypeParameterType) {
+          // It's ok for type arguments to get converted to `dynamic` if they
+          // are not used.
+          expect(
+              isTypeParameterUsed(
+                  original.typeArguments[i], original.element.type),
+              isFalse);
+        } else {
+          compareTypes(
+              resynthesized.typeArguments[i],
+              original.typeArguments[i],
+              '$desc type argument ${original.typeArguments[i].name}');
+        }
       }
       if (original.typeParameters == null) {
         expect(resynthesized.typeParameters, isNull, reason: desc);
@@ -1245,6 +1275,25 @@
     }
   }
 
+  /**
+   * Determine if [type] makes use of the given [typeParameter].
+   */
+  bool isTypeParameterUsed(TypeParameterType typeParameter, DartType type) {
+    if (type is FunctionType) {
+      return isTypeParameterUsed(typeParameter, type.returnType) ||
+          type.parameters.any((ParameterElement e) =>
+              isTypeParameterUsed(typeParameter, e.type));
+    } else if (type is InterfaceType) {
+      return type.typeArguments
+          .any((DartType t) => isTypeParameterUsed(typeParameter, t));
+    } else if (type is TypeParameterType) {
+      return type == typeParameter;
+    } else {
+      expect(type.isDynamic || type.isVoid, isTrue);
+      return false;
+    }
+  }
+
   @override
   void setUp() {
     super.setUp();
@@ -2844,6 +2893,14 @@
 }''');
   }
 
+  test_field_static_final_untyped() {
+    checkLibrary('class C { static final x = 0; }');
+  }
+
+  test_field_untyped() {
+    checkLibrary('class C { var x = 0; }');
+  }
+
   test_function_documented() {
     checkLibrary('''
 // Extra comment so doc comment offset != 0
@@ -4088,6 +4145,16 @@
     checkLibrary('f() {} g() {}');
   }
 
+  test_unused_type_parameter() {
+    checkLibrary('''
+class C<T> {
+  void f() {}
+}
+C<int> c;
+var v = c.f;
+''');
+  }
+
   test_variable_const() {
     checkLibrary('const int i = 0;');
   }
@@ -4105,6 +4172,10 @@
     checkLibrary('final int x = 0;');
   }
 
+  test_variable_final_top_level_untyped() {
+    checkLibrary('final v = 0;');
+  }
+
   test_variable_getterInLib_setterInPart() {
     addSource('/a.dart', 'part of my.lib; void set x(int _) {}');
     checkLibrary('library my.lib; part "a.dart"; int get x => 42;');
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
index 7784cae..1858f8f 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -43,31 +43,6 @@
   }
 
   @override
-  test_field_formal_param_inferred_type_explicit() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_field_formal_param_inferred_type_implicit() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_field_inferred_type_nonstatic_implicit_initialized() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_field_inferred_type_nonstatic_implicit_uninitialized() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_field_inferred_type_static_implicit_initialized() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
   test_field_propagated_type_final_immediate() {
     // TODO(paulberry): fix.
   }
@@ -78,41 +53,11 @@
   }
 
   @override
-  test_getter_inferred_type_nonstatic_implicit_return() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
   test_implicit_dependencies_follow_other_dependencies() {
     // TODO(paulberry): fix.
   }
 
   @override
-  test_inferred_type_refers_to_bound_type_param() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_inferred_type_refers_to_function_typed_parameter_type_generic_class() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_inferred_type_refers_to_function_typed_parameter_type_other_lib() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_inferred_type_refers_to_method_function_typed_parameter_type() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_inferred_type_refers_to_setter_function_typed_parameter_type() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
   test_initializer_executable_with_bottom_return_type() {
     // TODO(paulberry): fix.
   }
@@ -153,26 +98,6 @@
   }
 
   @override
-  test_method_inferred_type_nonstatic_implicit_param() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_method_inferred_type_nonstatic_implicit_return() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_setter_inferred_type_nonstatic_implicit_param() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
-  test_setter_inferred_type_nonstatic_implicit_return() {
-    // TODO(paulberry): fix.
-  }
-
-  @override
   test_syntheticFunctionType_genericClosure() {
     // TODO(paulberry): fix.
   }
@@ -203,6 +128,11 @@
   }
 
   @override
+  test_unused_type_parameter() {
+    // TODO(paulberry): fix.
+  }
+
+  @override
   test_variable_inferred_type_implicit_initialized() {
     // TODO(paulberry): fix.
   }
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
index 60ec0cb..a1690c5 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
@@ -130,6 +130,11 @@
   }
 
   @override
+  test_unused_type_parameter() {
+    // TODO(paulberry): fix.
+  }
+
+  @override
   test_variable_propagated_type_final_immediate() {
     // TODO(paulberry): fix.
   }
@@ -173,6 +178,9 @@
   bool get skipFullyLinkedData => false;
 
   @override
+  bool get skipNonConstInitializers => false;
+
+  @override
   addNamedSource(String filePath, String contents) {
     CompilationUnit unit = _parseText(contents);
     UnlinkedUnit unlinkedUnit =
@@ -205,7 +213,7 @@
       }
       return unit;
     }
-    linked = link(uriToUnit.keys.toSet(), getDependency, getUnit)[
+    linked = link(uriToUnit.keys.toSet(), getDependency, getUnit, strongMode)[
         testDartUri.toString()];
     expect(linked, isNotNull);
     validateLinkedLibrary(linked);
diff --git a/pkg/analyzer/test/src/summary/summarize_elements_test.dart b/pkg/analyzer/test/src/summary/summarize_elements_test.dart
index 539bbaf..da2a2bb 100644
--- a/pkg/analyzer/test/src/summary/summarize_elements_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_elements_test.dart
@@ -64,6 +64,9 @@
   bool get skipFullyLinkedData => false;
 
   @override
+  bool get skipNonConstInitializers => true;
+
+  @override
   bool get strongMode => false;
 
   @override
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index c690ab8..a34f921 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -172,6 +172,11 @@
   bool get skipFullyLinkedData;
 
   /**
+   * `true` if non-const variable initializers are not serialized.
+   */
+  bool get skipNonConstInitializers;
+
+  /**
    * `true` if the linked portion of the summary contains the result of strong
    * mode analysis.
    */
@@ -231,14 +236,18 @@
    * a file reachable via the given [absoluteUri] and [relativeUri].
    */
   void checkDependency(int dependency, String absoluteUri, String relativeUri) {
+    expect(dependency, new isInstanceOf<int>());
     if (expectAbsoluteUrisInDependencies) {
       // The element model doesn't (yet) store enough information to recover
       // relative URIs, so we have to use the absolute URI.
       // TODO(paulberry): fix this.
-      relativeUri = absoluteUri;
+      expect(linked.dependencies[dependency].uri, absoluteUri);
+    } else if (dependency >= linked.numPrelinkedDependencies) {
+      // Fully-linked dependencies are always absolute URIs.
+      expect(linked.dependencies[dependency].uri, absoluteUri);
+    } else {
+      expect(linked.dependencies[dependency].uri, relativeUri);
     }
-    expect(dependency, new isInstanceOf<int>());
-    expect(linked.dependencies[dependency].uri, relativeUri);
   }
 
   /**
@@ -507,7 +516,8 @@
       UnlinkedUnit unlinkedSourceUnit,
       int numTypeParameters: 0,
       bool checkAstDerivedDataOverride: false,
-      int localIndex: 0}) {
+      int localIndex: 0,
+      bool unresolvedHasName: false}) {
     linkedSourceUnit ??= definingUnit;
     unlinkedSourceUnit ??= unlinkedUnits[0];
     LinkedReference referenceResolution =
@@ -542,7 +552,7 @@
         !checkAstDerivedDataOverride) {
       // summarize_elements.dart isn't yet able to record the name of
       // unresolved references.  TODO(paulberry): fix this.
-      expect(name, '*unresolved*');
+      expect(name, unresolvedHasName ? expectedName : '*unresolved*');
     } else {
       if (expectedName == null) {
         expect(name, isEmpty);
@@ -584,7 +594,8 @@
       LinkedUnit linkedSourceUnit,
       UnlinkedUnit unlinkedSourceUnit,
       int numTypeParameters: 0,
-      bool checkAstDerivedDataOverride: false}) {
+      bool checkAstDerivedDataOverride: false,
+      bool unresolvedHasName: false}) {
     linkedSourceUnit ??= definingUnit;
     expect(typeRef, new isInstanceOf<EntityRef>());
     expect(typeRef.paramReference, 0);
@@ -599,12 +610,14 @@
         linkedSourceUnit: linkedSourceUnit,
         unlinkedSourceUnit: unlinkedSourceUnit,
         numTypeParameters: numTypeParameters,
-        checkAstDerivedDataOverride: checkAstDerivedDataOverride);
+        checkAstDerivedDataOverride: checkAstDerivedDataOverride,
+        unresolvedHasName: unresolvedHasName);
     expect(reference, isNotNull,
         reason: 'Unlinked type refs must refer to an explicit reference');
     if (expectedKind == ReferenceKind.unresolved &&
         !checkAstDerivedData &&
-        !checkAstDerivedDataOverride) {
+        !checkAstDerivedDataOverride &&
+        !unresolvedHasName) {
       // summarize_elements.dart isn't yet able to record the prefix of
       // unresolved references.  TODO(paulberry): fix this.
       expect(reference.prefixReference, 0);
@@ -1728,18 +1741,6 @@
         strings: ['T']);
   }
 
-  test_constExpr_identical() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = identical(42, null);');
-    _assertUnlinkedConst(variable.constExpr, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushNull,
-      UnlinkedConstOperation.identical
-    ], ints: [
-      42
-    ]);
-  }
-
   test_constExpr_invokeConstructor_generic_named() {
     UnlinkedVariable variable = serializeVariableText('''
 class C<K, V> {
@@ -2202,6 +2203,25 @@
     ]);
   }
 
+  test_constExpr_invokeMethodRef_identical() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = identical(42, null);');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushNull,
+      UnlinkedConstOperation.invokeMethodRef
+    ], ints: [
+      42,
+      0,
+      2
+    ], referenceValidators: [
+      (EntityRef r) {
+        checkTypeRef(r, 'dart:core', 'dart:core', 'identical',
+            expectedKind: ReferenceKind.topLevelFunction);
+      }
+    ]);
+  }
+
   test_constExpr_length_classConstField() {
     UnlinkedVariable variable = serializeVariableText('''
 class C {
@@ -2254,7 +2274,8 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
-              expectedKind: ReferenceKind.length,
+              expectedKind: ReferenceKind.unresolved,
+              unresolvedHasName: true,
               prefixExpectations: [
                 new _PrefixExpectation(
                     ReferenceKind.topLevelPropertyAccessor, 'a')
@@ -2273,7 +2294,8 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
-              expectedKind: ReferenceKind.length,
+              expectedKind: ReferenceKind.unresolved,
+              unresolvedHasName: true,
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.propertyAccessor, 'F'),
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C'),
@@ -2295,7 +2317,8 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
-              expectedKind: ReferenceKind.length,
+              expectedKind: ReferenceKind.unresolved,
+              unresolvedHasName: true,
               prefixExpectations: [
                 new _PrefixExpectation(
                     ReferenceKind.topLevelPropertyAccessor, 'a',
@@ -2318,7 +2341,8 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
-              expectedKind: ReferenceKind.length,
+              expectedKind: ReferenceKind.unresolved,
+              unresolvedHasName: true,
               prefixExpectations: [
                 new _PrefixExpectation(
                     ReferenceKind.topLevelPropertyAccessor, 'a',
@@ -2335,10 +2359,11 @@
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.add,
-      UnlinkedConstOperation.length
+      UnlinkedConstOperation.extractProperty
     ], strings: [
       'abc',
-      'edf'
+      'edf',
+      'length'
     ]);
   }
 
@@ -2347,9 +2372,10 @@
         serializeVariableText('const v = ("abc").length;');
     _assertUnlinkedConst(variable.constExpr, operators: [
       UnlinkedConstOperation.pushString,
-      UnlinkedConstOperation.length
+      UnlinkedConstOperation.extractProperty
     ], strings: [
-      'abc'
+      'abc',
+      'length'
     ]);
   }
 
@@ -2358,9 +2384,10 @@
         serializeVariableText('const v = "abc".length;');
     _assertUnlinkedConst(variable.constExpr, operators: [
       UnlinkedConstOperation.pushString,
-      UnlinkedConstOperation.length
+      UnlinkedConstOperation.extractProperty
     ], strings: [
-      'abc'
+      'abc',
+      'length'
     ]);
   }
 
@@ -2980,7 +3007,13 @@
 ''';
     UnlinkedVariable variable =
         serializeClassText(text, allowErrors: true).fields[0];
-    _assertUnlinkedConst(variable.constExpr, isInvalid: true);
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) {
+        return checkParamTypeRef(r, 1);
+      }
+    ]);
   }
 
   test_constExpr_pushReference_unresolved_prefix0() {
@@ -5842,6 +5875,834 @@
         ReferenceKind.topLevelPropertyAccessor);
   }
 
+  test_expr_assignOperator_assign() {
+    _assertAssignmentOperator(
+        '(a = 1 + 2) + 3', UnlinkedExprAssignOperator.assign);
+  }
+
+  test_expr_assignOperator_bitAnd() {
+    _assertAssignmentOperator(
+        '(a &= 1 + 2) + 3', UnlinkedExprAssignOperator.bitAnd);
+  }
+
+  test_expr_assignOperator_bitOr() {
+    _assertAssignmentOperator(
+        '(a |= 1 + 2) + 3', UnlinkedExprAssignOperator.bitOr);
+  }
+
+  test_expr_assignOperator_bitXor() {
+    _assertAssignmentOperator(
+        '(a ^= 1 + 2) + 3', UnlinkedExprAssignOperator.bitXor);
+  }
+
+  test_expr_assignOperator_divide() {
+    _assertAssignmentOperator(
+        '(a /= 1 + 2) + 3', UnlinkedExprAssignOperator.divide);
+  }
+
+  test_expr_assignOperator_floorDivide() {
+    _assertAssignmentOperator(
+        '(a ~/= 1 + 2) + 3', UnlinkedExprAssignOperator.floorDivide);
+  }
+
+  test_expr_assignOperator_ifNull() {
+    _assertAssignmentOperator(
+        '(a ??= 1 + 2) + 3', UnlinkedExprAssignOperator.ifNull);
+  }
+
+  test_expr_assignOperator_minus() {
+    _assertAssignmentOperator(
+        '(a -= 1 + 2) + 3', UnlinkedExprAssignOperator.minus);
+  }
+
+  test_expr_assignOperator_modulo() {
+    _assertAssignmentOperator(
+        '(a %= 1 + 2) + 3', UnlinkedExprAssignOperator.modulo);
+  }
+
+  test_expr_assignOperator_multiply() {
+    _assertAssignmentOperator(
+        '(a *= 1 + 2) + 3', UnlinkedExprAssignOperator.multiply);
+  }
+
+  test_expr_assignOperator_plus() {
+    _assertAssignmentOperator(
+        '(a += 1 + 2) + 3', UnlinkedExprAssignOperator.plus);
+  }
+
+  test_expr_assignOperator_shiftLeft() {
+    _assertAssignmentOperator(
+        '(a <<= 1 + 2) + 3', UnlinkedExprAssignOperator.shiftLeft);
+  }
+
+  test_expr_assignOperator_shiftRight() {
+    _assertAssignmentOperator(
+        '(a >>= 1 + 2) + 3', UnlinkedExprAssignOperator.shiftRight);
+  }
+
+  test_expr_assignToIndex_ofFieldSequence() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class A {
+  B b;
+}
+class B {
+  C c;
+}
+class C {
+  List<int> f = <int>[0, 1, 2];
+}
+A a = new A();
+final v = (a.b.c.f[1] = 5);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushReference,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToIndex,
+    ], assignmentOperators: [
+      (UnlinkedExprAssignOperator.assign)
+    ], ints: [
+      5,
+      1
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'f',
+              expectedKind: ReferenceKind.unresolved,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
+                new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
+                new _PrefixExpectation(
+                    ReferenceKind.topLevelPropertyAccessor, 'a')
+              ])
+    ]);
+  }
+
+  test_expr_assignToIndex_ofIndexExpression() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class A {
+ List<B> b;
+}
+class B {
+  List<C> c;
+}
+class C {
+  List<int> f = <int>[0, 1, 2];
+}
+A a = new A();
+final v = (a.b[1].c[2].f[3] = 5);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      // 5
+      UnlinkedConstOperation.pushInt,
+      // a.b[1]
+      UnlinkedConstOperation.pushReference,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.extractIndex,
+      // c[2]
+      UnlinkedConstOperation.extractProperty,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.extractIndex,
+      // f[3] = 5
+      UnlinkedConstOperation.extractProperty,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToIndex,
+    ], assignmentOperators: [
+      (UnlinkedExprAssignOperator.assign)
+    ], ints: [
+      5,
+      1,
+      2,
+      3,
+    ], strings: [
+      'c',
+      'f'
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null,
+              'b', expectedKind: ReferenceKind.unresolved, prefixExpectations: [
+            new _PrefixExpectation(ReferenceKind.topLevelPropertyAccessor, 'a')
+          ])
+    ]);
+  }
+
+  test_expr_assignToIndex_ofTopLevelVariable() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+List<int> a = <int>[0, 1, 2];
+final v = (a[1] = 5);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushReference,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToIndex,
+    ], assignmentOperators: [
+      (UnlinkedExprAssignOperator.assign)
+    ], ints: [
+      5,
+      1,
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'a',
+          expectedKind: ReferenceKind.topLevelPropertyAccessor)
+    ]);
+  }
+
+  test_expr_assignToProperty_ofInstanceCreation() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  int f;
+}
+final v = (new C().f = 5);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.invokeConstructor,
+      UnlinkedConstOperation.assignToProperty,
+    ], assignmentOperators: [
+      (UnlinkedExprAssignOperator.assign)
+    ], ints: [
+      5,
+      0,
+      0,
+    ], strings: [
+      'f'
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'C',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_expr_assignToRef_classStaticField() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  static int f;
+}
+final v = (C.f = 1);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToRef,
+    ], assignmentOperators: [
+      (UnlinkedExprAssignOperator.assign)
+    ], ints: [
+      1,
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'f',
+              expectedKind: ReferenceKind.unresolved,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+              ])
+    ]);
+  }
+
+  test_expr_assignToRef_fieldSequence() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class A {
+  B b;
+}
+class B {
+  C c;
+}
+class C {
+  int f;
+}
+A a = new A();
+final v = (a.b.c.f = 1);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToRef,
+    ], assignmentOperators: [
+      (UnlinkedExprAssignOperator.assign)
+    ], ints: [
+      1,
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'f',
+              expectedKind: ReferenceKind.unresolved,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
+                new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
+                new _PrefixExpectation(
+                    ReferenceKind.topLevelPropertyAccessor, 'a')
+              ])
+    ]);
+  }
+
+  test_expr_assignToRef_postfixDecrement() {
+    _assertRefPrefixPostfixIncrementDecrement(
+        'a-- + 2', UnlinkedExprAssignOperator.postfixDecrement);
+  }
+
+  test_expr_assignToRef_postfixIncrement() {
+    _assertRefPrefixPostfixIncrementDecrement(
+        'a++ + 2', UnlinkedExprAssignOperator.postfixIncrement);
+  }
+
+  test_expr_assignToRef_prefixDecrement() {
+    _assertRefPrefixPostfixIncrementDecrement(
+        '--a + 2', UnlinkedExprAssignOperator.prefixDecrement);
+  }
+
+  test_expr_assignToRef_prefixIncrement() {
+    _assertRefPrefixPostfixIncrementDecrement(
+        '++a + 2', UnlinkedExprAssignOperator.prefixIncrement);
+  }
+
+  test_expr_assignToRef_topLevelVariable() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+int a = 0;
+final v = (a = 1);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToRef,
+    ], assignmentOperators: [
+      (UnlinkedExprAssignOperator.assign)
+    ], ints: [
+      1,
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'a',
+          expectedKind: ReferenceKind.topLevelPropertyAccessor)
+    ]);
+  }
+
+  test_expr_assignToRef_topLevelVariable_imported() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    addNamedSource(
+        '/a.dart',
+        '''
+int a = 0;
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+final v = (a = 1);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToRef,
+    ], assignmentOperators: [
+      (UnlinkedExprAssignOperator.assign)
+    ], ints: [
+      1,
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
+          expectedKind: ReferenceKind.topLevelPropertyAccessor)
+    ]);
+  }
+
+  test_expr_assignToRef_topLevelVariable_imported_withPrefix() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    addNamedSource(
+        '/a.dart',
+        '''
+int a = 0;
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+final v = (p.a = 1);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToRef,
+    ], assignmentOperators: [
+      (UnlinkedExprAssignOperator.assign)
+    ], ints: [
+      1,
+    ], strings: [], referenceValidators: [
+      (EntityRef r) {
+        return checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
+            expectedKind: ReferenceKind.topLevelPropertyAccessor,
+            expectedPrefix: 'p');
+      }
+    ]);
+  }
+
+  test_expr_cascadeSection_assignToIndex() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  List<int> items;
+}
+final C c = new C();
+final v = c.items..[1] = 2;
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushReference,
+      //   ..[1] = 2
+      UnlinkedConstOperation.cascadeSectionBegin,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToIndex,
+      // c
+      UnlinkedConstOperation.cascadeSectionEnd,
+    ], assignmentOperators: [
+      UnlinkedExprAssignOperator.assign,
+    ], ints: [
+      2,
+      1
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'items',
+              expectedKind: ReferenceKind.unresolved,
+              prefixExpectations: [
+                new _PrefixExpectation(
+                    ReferenceKind.topLevelPropertyAccessor, 'c'),
+              ])
+    ]);
+  }
+
+  test_expr_cascadeSection_assignToProperty() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  int f1 = 0;
+  int f2 = 0;
+}
+final v = new C()..f1 = 1..f2 += 2;
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      // new C()
+      UnlinkedConstOperation.invokeConstructor,
+      //   ..f1 = 1
+      UnlinkedConstOperation.cascadeSectionBegin,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToProperty,
+      // C
+      UnlinkedConstOperation.cascadeSectionEnd,
+      //   ..f2 += 2
+      UnlinkedConstOperation.cascadeSectionBegin,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToProperty,
+      // C
+      UnlinkedConstOperation.cascadeSectionEnd,
+    ], assignmentOperators: [
+      UnlinkedExprAssignOperator.assign,
+      UnlinkedExprAssignOperator.plus,
+    ], ints: [
+      0, 0, // new C()
+      1, // f1 = 1
+      2, // f2 += 2
+    ], strings: [
+      'f1',
+      'f2',
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'C',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_expr_cascadeSection_embedded() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class A {
+  int fa1;
+  B b;
+  int fa2;
+}
+class B {
+  int fb;
+}
+final v = new A()
+  ..fa1 = 1
+  ..b = (new B()..fb = 2)
+  ..fa2 = 3;
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      // new A()
+      UnlinkedConstOperation.invokeConstructor,
+      // ..fa1 = 1
+      UnlinkedConstOperation.cascadeSectionBegin,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToProperty,
+      UnlinkedConstOperation.cascadeSectionEnd,
+      // ..b
+      UnlinkedConstOperation.cascadeSectionBegin,
+      //   new B()
+      UnlinkedConstOperation.invokeConstructor,
+      //   ..fb = 2
+      UnlinkedConstOperation.cascadeSectionBegin,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToProperty,
+      UnlinkedConstOperation.cascadeSectionEnd,
+      // ..b = <pop value>
+      UnlinkedConstOperation.assignToProperty,
+      UnlinkedConstOperation.cascadeSectionEnd,
+      // ..fa2 = 3
+      UnlinkedConstOperation.cascadeSectionBegin,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.assignToProperty,
+      UnlinkedConstOperation.cascadeSectionEnd,
+    ], assignmentOperators: [
+      UnlinkedExprAssignOperator.assign,
+      UnlinkedExprAssignOperator.assign,
+      UnlinkedExprAssignOperator.assign,
+      UnlinkedExprAssignOperator.assign,
+    ], ints: [
+      0,
+      0,
+      1,
+      0,
+      0,
+      2,
+      3,
+    ], strings: [
+      'fa1',
+      'fb',
+      'b',
+      'fa2',
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'A',
+          expectedKind: ReferenceKind.classOrEnum),
+      (EntityRef r) => checkTypeRef(r, null, null, 'B',
+          expectedKind: ReferenceKind.classOrEnum),
+    ]);
+  }
+
+  test_expr_cascadeSection_invokeMethod() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class A {
+  int m(int _) => 0;
+}
+final A a = new A();
+final v = a..m(5).abs()..m(6);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      // a
+      UnlinkedConstOperation.pushReference,
+      //   ..m(5)
+      UnlinkedConstOperation.cascadeSectionBegin,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.invokeMethod,
+      //   ..abs()
+      UnlinkedConstOperation.invokeMethod,
+      // a
+      UnlinkedConstOperation.cascadeSectionEnd,
+      //   ..m(6)
+      UnlinkedConstOperation.cascadeSectionBegin,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.invokeMethod,
+      // a
+      UnlinkedConstOperation.cascadeSectionEnd,
+    ], ints: [
+      5, 0, 1, // m(5)
+      0, 0, // abs()
+      6, 0, 1, // m(5)
+    ], strings: [
+      'm',
+      'abs',
+      'm',
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'a',
+          expectedKind: ReferenceKind.topLevelPropertyAccessor),
+    ]);
+  }
+
+  test_expr_extractIndex_ofClassField() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  List<int> get items => null;
+}
+final v = new C().items[5];
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+      UnlinkedConstOperation.extractProperty,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.extractIndex,
+    ], ints: [
+      0,
+      0,
+      5
+    ], strings: [
+      'items'
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'C',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_expr_extractProperty_ofInvokeConstructor() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  int f = 0;
+}
+final v = new C().f;
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+      UnlinkedConstOperation.extractProperty,
+    ], ints: [
+      0,
+      0
+    ], strings: [
+      'f'
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'C',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_expr_functionExpression_asArgument() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+final v = foo(5, () => 42);
+foo(a, b) {}
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushNull,
+      UnlinkedConstOperation.invokeMethodRef
+    ], ints: [
+      5,
+      0,
+      2
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+          expectedKind: ReferenceKind.topLevelFunction)
+    ]);
+  }
+
+  test_expr_functionExpression_withBlockBody() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+final v = () { return 42; };
+''');
+    _assertUnlinkedConst(variable.constExpr,
+        isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+  }
+
+  test_expr_functionExpression_withExpressionBody() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+final v = () => 42;
+''');
+    _assertUnlinkedConst(variable.constExpr,
+        isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+  }
+
+  test_expr_functionExpressionInvocation_withBlockBody() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+final v = ((a, b) {return 42;})(1, 2);
+''');
+    _assertUnlinkedConst(variable.constExpr,
+        isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+  }
+
+  test_expr_functionExpressionInvocation_withExpressionBody() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+final v = ((a, b) => 42)(1, 2);
+''');
+    _assertUnlinkedConst(variable.constExpr,
+        isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+  }
+
+  test_expr_invokeMethod_instance() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  int m(a, {b, c}) => 42;
+}
+final v = new C().m(1, b: 2, c: 3);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.invokeMethod,
+    ], ints: [
+      0,
+      0,
+      1,
+      2,
+      3,
+      2,
+      1
+    ], strings: [
+      'b',
+      'c',
+      'm'
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'C',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_expr_invokeMethodRef_instance() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+class A {
+  B b;
+}
+class B {
+  C c;
+}
+class C {
+  int m(int a, int b) => a + b;
+}
+A a = new A();
+final v = a.b.c.m(10, 20);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.invokeMethodRef,
+    ], ints: [
+      10,
+      20,
+      0,
+      2
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'm',
+              expectedKind: ReferenceKind.unresolved,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
+                new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
+                new _PrefixExpectation(
+                    ReferenceKind.topLevelPropertyAccessor, 'a')
+              ])
+    ]);
+  }
+
+  test_expr_invokeMethodRef_static_importedWithPrefix() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    addNamedSource(
+        '/a.dart',
+        '''
+class C {
+  static int m() => 42;
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+final v = p.C.m();
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.invokeMethodRef,
+    ], ints: [
+      0,
+      0
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'm',
+              expectedKind: ReferenceKind.method,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
+                    absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
+                new _PrefixExpectation(ReferenceKind.prefix, 'p')
+              ])
+    ]);
+  }
+
+  test_expr_throwException() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+final v = throw 1 + 2;
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.add,
+      UnlinkedConstOperation.throwException,
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_expr_typeCast() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+final v = 42 as num;
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushReference,
+      UnlinkedConstOperation.typeCast,
+    ], ints: [
+      42
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'num',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_expr_typeCheck() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+final v = 42 is num;
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushReference,
+      UnlinkedConstOperation.typeCheck,
+    ], ints: [
+      42
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'num',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
   test_field() {
     UnlinkedClass cls = serializeClassText('class C { int i; }');
     UnlinkedVariable variable = findVariable('i', variables: cls.fields);
@@ -5883,14 +6744,28 @@
         operators: [UnlinkedConstOperation.pushInt], ints: [0]);
   }
 
-  test_field_final_invalidConstExpr() {
+  test_field_final_notConstExpr() {
     UnlinkedVariable variable = serializeClassText(r'''
 class C {
   final int f = 1 + m();
   static int m() => 42;
 }''').fields[0];
     expect(variable.isFinal, isTrue);
-    _assertUnlinkedConst(variable.constExpr, isInvalid: true);
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.invokeMethodRef,
+      UnlinkedConstOperation.add,
+    ], ints: [
+      1,
+      0,
+      0
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'm',
+              expectedKind: ReferenceKind.method,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+              ])
+    ]);
   }
 
   test_field_final_typeParameter() {
@@ -5998,6 +6873,28 @@
     expect(variable.constExpr, isNull);
   }
 
+  test_field_static_final_untyped() {
+    if (!checkAstDerivedData) {
+      // The element model doesn't contain the initializer expressions needed
+      // for type inference.  TODO(paulberry): fix.
+      return;
+    }
+    UnlinkedVariable variable =
+        serializeClassText('class C { static final x = 0; }').fields[0];
+    expect(variable.constExpr, isNotNull);
+  }
+
+  test_field_untyped() {
+    if (!checkAstDerivedData) {
+      // The element model doesn't contain the initializer expressions needed
+      // for type inference.  TODO(paulberry): fix.
+      return;
+    }
+    UnlinkedVariable variable =
+        serializeClassText('class C { var x = 0; }').fields[0];
+    expect(variable.constExpr, isNotNull);
+  }
+
   test_fully_linked_references_follow_other_references() {
     if (skipFullyLinkedData) {
       return;
@@ -7949,6 +8846,24 @@
     expect(xType.reference, yType.reference);
   }
 
+  test_unused_type_parameter() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    // Unused type parameters get converted to `dynamic`.
+    UnlinkedVariable variable = serializeVariableText('''
+class C<T> {
+  void f() {}
+}
+C<int> c;
+var v = c.f;
+''');
+    EntityRef type =
+        getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot);
+    expect(type.typeArguments, hasLength(1));
+    checkLinkedTypeRef(type.typeArguments[0], null, null, 'dynamic');
+  }
+
   test_variable() {
     String text = 'int i;';
     UnlinkedVariable v = serializeVariableText(text, variableName: 'i');
@@ -8003,6 +8918,16 @@
     expect(variable.constExpr, isNull);
   }
 
+  test_variable_final_top_level_untyped() {
+    if (!checkAstDerivedData) {
+      // The element model doesn't contain the initializer expressions needed
+      // for type inference.  TODO(paulberry): fix.
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('final v = 0;');
+    expect(variable.constExpr, isNotNull);
+  }
+
   test_variable_implicit_dynamic() {
     UnlinkedVariable variable = serializeVariableText('var v;');
     expect(variable.type, isNull);
@@ -8222,6 +9147,38 @@
     }
   }
 
+  /**
+   * Assert that serializing the given [expr] of form `(a op= 1 + 2) + 3`
+   * uses the given [expectedAssignOperator].
+   */
+  void _assertAssignmentOperator(
+      String expr, UnlinkedExprAssignOperator expectedAssignOperator) {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+int a = 0;
+final v = $expr;
+    ''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.add,
+      UnlinkedConstOperation.assignToRef,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.add,
+    ], assignmentOperators: [
+      expectedAssignOperator
+    ], ints: [
+      1,
+      2,
+      3
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'a',
+          expectedKind: ReferenceKind.topLevelPropertyAccessor)
+    ]);
+  }
+
   void _assertCodeRange(CodeRange codeRange, int offset, int length) {
     expect(codeRange, isNotNull);
     expect(codeRange.offset, offset);
@@ -8251,20 +9208,53 @@
     expect(p.visibleLength, isZero);
   }
 
+  /**
+   * Assert that the [expr] of the form `++a + 2` is serialized with the
+   * [expectedAssignmentOperator].
+   */
+  void _assertRefPrefixPostfixIncrementDecrement(
+      String expr, UnlinkedExprAssignOperator expectedAssignmentOperator) {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+int a = 0;
+final v = $expr;
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.assignToRef,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.add,
+    ], assignmentOperators: [
+      expectedAssignmentOperator
+    ], ints: [
+      2
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'a',
+          expectedKind: ReferenceKind.topLevelPropertyAccessor)
+    ]);
+  }
+
+  /**
+   * TODO(scheglov) rename "Const" to "Expr" everywhere
+   */
   void _assertUnlinkedConst(UnlinkedConst constExpr,
-      {bool isInvalid: false,
+      {bool isValidConst: true,
       List<UnlinkedConstOperation> operators: const <UnlinkedConstOperation>[],
+      List<UnlinkedExprAssignOperator> assignmentOperators:
+          const <UnlinkedExprAssignOperator>[],
       List<int> ints: const <int>[],
       List<double> doubles: const <double>[],
       List<String> strings: const <String>[],
       List<_EntityRefValidator> referenceValidators:
           const <_EntityRefValidator>[]}) {
     expect(constExpr, isNotNull);
-    expect(constExpr.isInvalid, isInvalid);
+    expect(constExpr.isValidConst, isValidConst);
     expect(constExpr.operations, operators);
     expect(constExpr.ints, ints);
     expect(constExpr.doubles, doubles);
     expect(constExpr.strings, strings);
+    expect(constExpr.assignmentOperators, assignmentOperators);
     expect(constExpr.references, hasLength(referenceValidators.length));
     for (int i = 0; i < referenceValidators.length; i++) {
       referenceValidators[i](constExpr.references[i]);
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index c07689b..9b058bc 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -66,6 +66,7 @@
   runReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
   runReflectiveTests(PropagateVariableTypesInUnitTaskTest);
   runReflectiveTests(PropagateVariableTypeTaskTest);
+  runReflectiveTests(ResolveDirectiveElementsTaskTest);
   runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
   runReflectiveTests(ResolveLibraryTaskTest);
   runReflectiveTests(ResolveLibraryTypeNamesTaskTest);
@@ -130,6 +131,8 @@
     new isInstanceOf<PropagateVariableTypesInUnitTask>();
 isInstanceOf isPropagateVariableTypeTask =
     new isInstanceOf<PropagateVariableTypeTask>();
+isInstanceOf isResolveDirectiveElementsTask =
+    new isInstanceOf<ResolveDirectiveElementsTask>();
 isInstanceOf isResolveLibraryTask = new isInstanceOf<ResolveLibraryTask>();
 isInstanceOf isResolveLibraryTypeNamesTask =
     new isInstanceOf<ResolveLibraryTypeNamesTask>();
@@ -562,9 +565,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT2);
-    expect(outputs[RESOLVED_UNIT2], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT2], isTrue);
+    computeResult(target, RESOLVED_UNIT3);
+    expect(outputs[RESOLVED_UNIT3], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT3], isTrue);
   }
 
   test_perform() {
@@ -575,9 +578,9 @@
   A, B
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT2,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT3,
         matcher: isBuildEnumMemberElementsTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT2];
+    CompilationUnit unit = outputs[RESOLVED_UNIT3];
     // validate Element
     ClassElement enumElement = unit.element.getEnum('MyEnum');
     List<FieldElement> fields = enumElement.fields;
@@ -981,7 +984,8 @@
     libraryUnitElement = libraryUnit.element;
     librarySource = libraryUnitElement.source;
     libraryElement = outputs[LIBRARY_ELEMENT1];
-    partUnits = task.inputs[BuildLibraryElementTask.PARTS_UNIT_INPUT];
+    partUnits = task.inputs[BuildLibraryElementTask.PARTS_UNIT_INPUT]
+        as List<CompilationUnit>;
   }
 }
 
@@ -1012,6 +1016,10 @@
 
 @reflectiveTest
 class BuildSourceExportClosureTaskTest extends _AbstractDartTaskTest {
+  List<Source> getExportSourceClosure(Map<ResultDescriptor, dynamic> outputs) {
+    return outputs[EXPORT_SOURCE_CLOSURE] as List<Source>;
+  }
+
   test_perform_exportClosure() {
     Source sourceA = newSource(
         '/a.dart',
@@ -1040,21 +1048,21 @@
     {
       computeResult(sourceA, EXPORT_SOURCE_CLOSURE,
           matcher: isBuildSourceExportClosureTask);
-      List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
+      List<Source> closure = getExportSourceClosure(outputs);
       expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
     }
     // c.dart
     {
       computeResult(sourceC, EXPORT_SOURCE_CLOSURE,
           matcher: isBuildSourceExportClosureTask);
-      List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
+      List<Source> closure = getExportSourceClosure(outputs);
       expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
     }
     // d.dart
     {
       computeResult(sourceD, EXPORT_SOURCE_CLOSURE,
           matcher: isBuildSourceExportClosureTask);
-      List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
+      List<Source> closure = getExportSourceClosure(outputs);
       expect(closure, unorderedEquals([sourceD]));
     }
   }
@@ -1204,8 +1212,8 @@
     // First compute the resolved unit for the source.
     LibrarySpecificUnit librarySpecificUnit =
         new LibrarySpecificUnit(source, source);
-    computeResult(librarySpecificUnit, RESOLVED_UNIT2);
-    CompilationUnit unit = outputs[RESOLVED_UNIT2];
+    computeResult(librarySpecificUnit, RESOLVED_UNIT3);
+    CompilationUnit unit = outputs[RESOLVED_UNIT3];
     // Find the element for 'A'
     EnumDeclaration enumDeclaration = unit.declarations[0];
     EnumConstantDeclaration constantDeclaration = enumDeclaration.constants[0];
@@ -1491,9 +1499,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5);
-    expect(outputs[RESOLVED_UNIT5], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT5], isTrue);
+    computeResult(target, RESOLVED_UNIT6);
+    expect(outputs[RESOLVED_UNIT6], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT6], isTrue);
   }
 
   test_perform() {
@@ -1504,22 +1512,36 @@
 const b = 0;
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(target, RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     TopLevelVariableElement elementA = unit.element.topLevelVariables[0];
     TopLevelVariableElement elementB = unit.element.topLevelVariables[1];
 
     computeResult(elementA, INFERABLE_STATIC_VARIABLE_DEPENDENCIES,
         matcher: isComputeInferableStaticVariableDependenciesTask);
     expect(outputs, hasLength(1));
-    List<VariableElement> dependencies =
-        outputs[INFERABLE_STATIC_VARIABLE_DEPENDENCIES];
+    List<VariableElement> dependencies = outputs[
+        INFERABLE_STATIC_VARIABLE_DEPENDENCIES] as List<VariableElement>;
     expect(dependencies, unorderedEquals([elementB]));
   }
 }
 
 @reflectiveTest
 class ComputeLibraryCycleTaskTest extends _AbstractDartTaskTest {
+  List<LibraryElement> getLibraryCycle(Map<ResultDescriptor, dynamic> outputs) {
+    return outputs[LIBRARY_CYCLE] as List<LibraryElement>;
+  }
+
+  List<CompilationUnitElement> getLibraryCycleDependencies(
+      Map<ResultDescriptor, dynamic> outputs) {
+    return outputs[LIBRARY_CYCLE_DEPENDENCIES] as List<CompilationUnitElement>;
+  }
+
+  List<CompilationUnitElement> getLibraryCycleUnits(
+      Map<ResultDescriptor, dynamic> outputs) {
+    return outputs[LIBRARY_CYCLE_UNITS] as List<CompilationUnitElement>;
+  }
+
   @override
   void setUp() {
     super.setUp();
@@ -1639,18 +1661,18 @@
     });
     List<Map<ResultDescriptor, dynamic>> results =
         computeLibraryResultsMap(sources, LIBRARY_CYCLE);
-    List<LibraryElement> component0 = results[0][LIBRARY_CYCLE];
-    List<LibraryElement> component1 = results[1][LIBRARY_CYCLE];
+    List<LibraryElement> component0 = getLibraryCycle(results[0]);
+    List<LibraryElement> component1 = getLibraryCycle(results[1]);
     expect(component0, hasLength(1));
     expect(component1, hasLength(1));
 
-    List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS];
+    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results[0]);
+    List<CompilationUnitElement> units1 = getLibraryCycleUnits(results[1]);
     expect(units0, hasLength(1));
     expect(units1, hasLength(1));
 
-    List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES];
+    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results[0]);
+    List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results[1]);
     expect(dep0, hasLength(1)); // dart:core
     expect(dep1, hasLength(2)); // dart:core, a.dart
   }
@@ -1669,24 +1691,24 @@
     });
     List<Map<ResultDescriptor, dynamic>> results =
         computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
-    List<LibraryElement> component0 = results[0][LIBRARY_CYCLE];
-    List<LibraryElement> component1 = results[1][LIBRARY_CYCLE];
-    List<LibraryElement> component2 = results[2][LIBRARY_CYCLE];
+    List<LibraryElement> component0 = getLibraryCycle(results[0]);
+    List<LibraryElement> component1 = getLibraryCycle(results[1]);
+    List<LibraryElement> component2 = getLibraryCycle(results[2]);
 
     expect(component0, hasLength(3));
     expect(component1, hasLength(3));
     expect(component2, hasLength(3));
 
-    List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS];
+    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results[0]);
+    List<CompilationUnitElement> units1 = getLibraryCycleUnits(results[1]);
+    List<CompilationUnitElement> units2 = getLibraryCycleUnits(results[2]);
     expect(units0, hasLength(3));
     expect(units1, hasLength(3));
     expect(units2, hasLength(3));
 
-    List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES];
+    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results[0]);
+    List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results[1]);
+    List<CompilationUnitElement> dep2 = getLibraryCycleDependencies(results[2]);
     expect(dep0, hasLength(1)); // dart:core
     expect(dep1, hasLength(1)); // dart:core
     expect(dep2, hasLength(1)); // dart:core
@@ -1756,13 +1778,13 @@
     });
     List<Map<ResultDescriptor, dynamic>> results =
         computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
-    List<LibraryElement> component0 = results[0][LIBRARY_CYCLE];
+    List<LibraryElement> component0 = getLibraryCycle(results[0]);
     expect(component0, hasLength(1));
 
-    List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS];
+    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results[0]);
     expect(units0, hasLength(1));
 
-    List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES];
+    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results[0]);
     expect(dep0, hasLength(1)); // dart:core
   }
 
@@ -1773,9 +1795,9 @@
 import 'dart:core';
 ''');
     computeResult(new LibrarySpecificUnit(source, source), LIBRARY_CYCLE);
-    List<LibraryElement> component = outputs[LIBRARY_CYCLE];
-    List<CompilationUnitElement> units = outputs[LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> deps = outputs[LIBRARY_CYCLE_DEPENDENCIES];
+    List<LibraryElement> component = getLibraryCycle(outputs);
+    List<CompilationUnitElement> units = getLibraryCycleUnits(outputs);
+    List<CompilationUnitElement> deps = getLibraryCycleDependencies(outputs);
     expect(component, hasLength(1));
     expect(units, hasLength(1));
     expect(deps, hasLength(1));
@@ -1794,23 +1816,23 @@
     });
     List<Map<ResultDescriptor, dynamic>> results =
         computeLibraryResultsMap(sources, LIBRARY_CYCLE);
-    List<LibraryElement> component0 = results[0][LIBRARY_CYCLE];
-    List<LibraryElement> component1 = results[1][LIBRARY_CYCLE];
-    List<LibraryElement> component2 = results[2][LIBRARY_CYCLE];
+    List<LibraryElement> component0 = getLibraryCycle(results[0]);
+    List<LibraryElement> component1 = getLibraryCycle(results[1]);
+    List<LibraryElement> component2 = getLibraryCycle(results[2]);
     expect(component0, hasLength(1));
     expect(component1, hasLength(1));
     expect(component2, hasLength(1));
 
-    List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS];
+    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results[0]);
+    List<CompilationUnitElement> units1 = getLibraryCycleUnits(results[1]);
+    List<CompilationUnitElement> units2 = getLibraryCycleUnits(results[2]);
     expect(units0, hasLength(1));
     expect(units1, hasLength(1));
     expect(units2, hasLength(1));
 
-    List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES];
+    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results[0]);
+    List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results[1]);
+    List<CompilationUnitElement> dep2 = getLibraryCycleDependencies(results[2]);
     expect(dep0, hasLength(1)); // dart:core
     expect(dep1, hasLength(1)); // dart:core,
     expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart
@@ -1837,29 +1859,29 @@
     });
     List<Map<ResultDescriptor, dynamic>> results =
         computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
-    List<LibraryElement> component0 = results[0][LIBRARY_CYCLE];
-    List<LibraryElement> component1 = results[1][LIBRARY_CYCLE];
-    List<LibraryElement> component2 = results[2][LIBRARY_CYCLE];
-    List<LibraryElement> component3 = results[3][LIBRARY_CYCLE];
+    List<LibraryElement> component0 = getLibraryCycle(results[0]);
+    List<LibraryElement> component1 = getLibraryCycle(results[1]);
+    List<LibraryElement> component2 = getLibraryCycle(results[2]);
+    List<LibraryElement> component3 = getLibraryCycle(results[3]);
 
     expect(component0, hasLength(2));
     expect(component1, hasLength(2));
     expect(component2, hasLength(2));
     expect(component3, hasLength(2));
 
-    List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units3 = results[3][LIBRARY_CYCLE_UNITS];
+    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results[0]);
+    List<CompilationUnitElement> units1 = getLibraryCycleUnits(results[1]);
+    List<CompilationUnitElement> units2 = getLibraryCycleUnits(results[2]);
+    List<CompilationUnitElement> units3 = getLibraryCycleUnits(results[3]);
     expect(units0, hasLength(2));
     expect(units1, hasLength(2));
     expect(units2, hasLength(2));
     expect(units3, hasLength(2));
 
-    List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep3 = results[3][LIBRARY_CYCLE_DEPENDENCIES];
+    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results[0]);
+    List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results[1]);
+    List<CompilationUnitElement> dep2 = getLibraryCycleDependencies(results[2]);
+    List<CompilationUnitElement> dep3 = getLibraryCycleDependencies(results[3]);
     expect(dep0, hasLength(1)); // dart:core
     expect(dep1, hasLength(1)); // dart:core
     expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart
@@ -1922,14 +1944,14 @@
         new LibrarySpecificUnit(sources[5], sources[7]), LIBRARY_CYCLE);
     Map<ResultDescriptor, dynamic> results7 = outputs;
 
-    List<LibraryElement> component0 = results0[LIBRARY_CYCLE];
-    List<LibraryElement> component1 = results1[LIBRARY_CYCLE];
-    List<LibraryElement> component2 = results2[LIBRARY_CYCLE];
-    List<LibraryElement> component3 = results3[LIBRARY_CYCLE];
-    List<LibraryElement> component4 = results4[LIBRARY_CYCLE];
-    List<LibraryElement> component5 = results5[LIBRARY_CYCLE];
-    List<LibraryElement> component6 = results6[LIBRARY_CYCLE];
-    List<LibraryElement> component7 = results7[LIBRARY_CYCLE];
+    List<LibraryElement> component0 = getLibraryCycle(results0);
+    List<LibraryElement> component1 = getLibraryCycle(results1);
+    List<LibraryElement> component2 = getLibraryCycle(results2);
+    List<LibraryElement> component3 = getLibraryCycle(results3);
+    List<LibraryElement> component4 = getLibraryCycle(results4);
+    List<LibraryElement> component5 = getLibraryCycle(results5);
+    List<LibraryElement> component6 = getLibraryCycle(results6);
+    List<LibraryElement> component7 = getLibraryCycle(results7);
 
     expect(component0, hasLength(2));
     expect(component1, hasLength(2));
@@ -1940,14 +1962,14 @@
     expect(component6, hasLength(2));
     expect(component7, hasLength(2));
 
-    List<CompilationUnitElement> units0 = results0[LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units1 = results1[LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units2 = results2[LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units3 = results3[LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units4 = results4[LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units5 = results5[LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units6 = results6[LIBRARY_CYCLE_UNITS];
-    List<CompilationUnitElement> units7 = results7[LIBRARY_CYCLE_UNITS];
+    List<CompilationUnitElement> units0 = getLibraryCycleUnits(results0);
+    List<CompilationUnitElement> units1 = getLibraryCycleUnits(results1);
+    List<CompilationUnitElement> units2 = getLibraryCycleUnits(results2);
+    List<CompilationUnitElement> units3 = getLibraryCycleUnits(results3);
+    List<CompilationUnitElement> units4 = getLibraryCycleUnits(results4);
+    List<CompilationUnitElement> units5 = getLibraryCycleUnits(results5);
+    List<CompilationUnitElement> units6 = getLibraryCycleUnits(results6);
+    List<CompilationUnitElement> units7 = getLibraryCycleUnits(results7);
     expect(units0, hasLength(4));
     expect(units1, hasLength(4));
     expect(units2, hasLength(4));
@@ -1957,14 +1979,14 @@
     expect(units6, hasLength(4));
     expect(units7, hasLength(4));
 
-    List<CompilationUnitElement> dep0 = results0[LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep1 = results1[LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep2 = results2[LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep3 = results3[LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep4 = results4[LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep5 = results5[LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep6 = results6[LIBRARY_CYCLE_DEPENDENCIES];
-    List<CompilationUnitElement> dep7 = results7[LIBRARY_CYCLE_DEPENDENCIES];
+    List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results0);
+    List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results1);
+    List<CompilationUnitElement> dep2 = getLibraryCycleDependencies(results2);
+    List<CompilationUnitElement> dep3 = getLibraryCycleDependencies(results3);
+    List<CompilationUnitElement> dep4 = getLibraryCycleDependencies(results4);
+    List<CompilationUnitElement> dep5 = getLibraryCycleDependencies(results5);
+    List<CompilationUnitElement> dep6 = getLibraryCycleDependencies(results6);
+    List<CompilationUnitElement> dep7 = getLibraryCycleDependencies(results7);
     expect(dep0, hasLength(1)); // dart:core
     expect(dep1, hasLength(1)); // dart:core
     expect(dep2, hasLength(1)); // dart:core
@@ -1979,6 +2001,11 @@
 @reflectiveTest
 class ComputePropagableVariableDependenciesTaskTest
     extends _AbstractDartTaskTest {
+  List<VariableElement> getPropagableVariableDependencies(
+      Map<ResultDescriptor, dynamic> outputs) {
+    return outputs[PROPAGABLE_VARIABLE_DEPENDENCIES] as List<VariableElement>;
+  }
+
   test_perform_instanceField() {
     AnalysisTarget source = newSource(
         '/test.dart',
@@ -1998,8 +2025,8 @@
 }
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(target, RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     FieldElement elementA = AstFinder.getFieldInClassElement(unit, 'A', 'a');
     // compute
     computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
@@ -2007,7 +2034,7 @@
     // verify
     expect(outputs, hasLength(1));
     List<VariableElement> dependencies =
-        outputs[PROPAGABLE_VARIABLE_DEPENDENCIES];
+        getPropagableVariableDependencies(outputs);
     expect(
         dependencies,
         unorderedEquals([
@@ -2029,8 +2056,8 @@
 var   d4 = 4;
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(target, RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     TopLevelVariableElement elementA =
         AstFinder.getTopLevelVariableElement(unit, 'a');
     // compute
@@ -2039,7 +2066,7 @@
     // verify
     expect(outputs, hasLength(1));
     List<VariableElement> dependencies =
-        outputs[PROPAGABLE_VARIABLE_DEPENDENCIES];
+        getPropagableVariableDependencies(outputs);
     expect(
         dependencies,
         unorderedEquals([
@@ -2060,8 +2087,8 @@
 final d = 4;
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(target, RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     TopLevelVariableElement elementA =
         AstFinder.getTopLevelVariableElement(unit, 'a');
     // compute
@@ -2070,7 +2097,7 @@
     // verify
     expect(outputs, hasLength(1));
     List<VariableElement> dependencies =
-        outputs[PROPAGABLE_VARIABLE_DEPENDENCIES];
+        getPropagableVariableDependencies(outputs);
     expect(dependencies,
         unorderedEquals([AstFinder.getTopLevelVariableElement(unit, 'd')]));
   }
@@ -2084,8 +2111,8 @@
 const c = 2;
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(target, RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     TopLevelVariableElement elementA =
         AstFinder.getTopLevelVariableElement(unit, 'a');
     // compute
@@ -2094,7 +2121,7 @@
     // verify
     expect(outputs, hasLength(1));
     List<VariableElement> dependencies =
-        outputs[PROPAGABLE_VARIABLE_DEPENDENCIES];
+        getPropagableVariableDependencies(outputs);
     expect(
         dependencies,
         unorderedEquals([
@@ -2106,13 +2133,17 @@
 
 @reflectiveTest
 class ContainingLibrariesTaskTest extends _AbstractDartTaskTest {
+  List<Source> getContainingLibraries(Map<ResultDescriptor, dynamic> outputs) {
+    return outputs[CONTAINING_LIBRARIES] as List<Source>;
+  }
+
   test_perform_definingCompilationUnit() {
     AnalysisTarget library = newSource('/test.dart', 'library test;');
     computeResult(library, INCLUDED_PARTS);
     computeResult(library, CONTAINING_LIBRARIES,
         matcher: isContainingLibrariesTask);
     expect(outputs, hasLength(1));
-    List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES];
+    List<Source> containingLibraries = getContainingLibraries(outputs);
     expect(containingLibraries, unorderedEquals([library]));
   }
 
@@ -2128,7 +2159,7 @@
     computeResult(part, CONTAINING_LIBRARIES,
         matcher: isContainingLibrariesTask);
     expect(outputs, hasLength(1));
-    List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES];
+    List<Source> containingLibraries = getContainingLibraries(outputs);
     expect(containingLibraries, unorderedEquals([library1, library2]));
   }
 
@@ -2141,20 +2172,24 @@
     computeResult(part, CONTAINING_LIBRARIES,
         matcher: isContainingLibrariesTask);
     expect(outputs, hasLength(1));
-    List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES];
+    List<Source> containingLibraries = getContainingLibraries(outputs);
     expect(containingLibraries, unorderedEquals([library]));
   }
 }
 
 @reflectiveTest
 class DartErrorsTaskTest extends _AbstractDartTaskTest {
+  List<AnalysisError> getDartErrors(Map<ResultDescriptor, dynamic> outputs) {
+    return outputs[DART_ERRORS] as List<AnalysisError>;
+  }
+
   test_perform_definingCompilationUnit() {
     AnalysisTarget library =
         newSource('/test.dart', 'library test; import "dart:math";');
     computeResult(library, INCLUDED_PARTS);
     computeResult(library, DART_ERRORS, matcher: isDartErrorsTask);
     expect(outputs, hasLength(1));
-    List<AnalysisError> errors = outputs[DART_ERRORS];
+    List<AnalysisError> errors = getDartErrors(outputs);
     expect(errors, hasLength(1));
   }
 
@@ -2167,7 +2202,7 @@
     computeResult(library, DART_ERRORS);
     computeResult(part, DART_ERRORS, matcher: isDartErrorsTask);
     expect(outputs, hasLength(1));
-    List<AnalysisError> errors = outputs[DART_ERRORS];
+    List<AnalysisError> errors = getDartErrors(outputs);
     // This should contain only the errors in the part file, not the ones in the
     // library.
     expect(errors, hasLength(1));
@@ -2184,9 +2219,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT11);
-    expect(outputs[RESOLVED_UNIT11], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
+    computeResult(target, RESOLVED_UNIT12);
+    expect(outputs[RESOLVED_UNIT12], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT12], isTrue);
   }
 
   test_perform() {
@@ -2203,9 +2238,9 @@
 const x = const C();
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT11,
+    computeResult(target, RESOLVED_UNIT12,
         matcher: isEvaluateUnitConstantsTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT11];
+    CompilationUnit unit = outputs[RESOLVED_UNIT12];
     CompilationUnitElement unitElement = unit.element;
     expect(
         (unitElement.types[0].constructors[0] as ConstructorElementImpl)
@@ -2227,7 +2262,7 @@
   UsedImportedElements usedElements;
   Set<String> usedElementNames;
 
-  test_perform() {
+  test_perform_inBody() {
     newSource(
         '/a.dart',
         r'''
@@ -2253,6 +2288,54 @@
     expect(usedElementNames, unorderedEquals(['A']));
   }
 
+  test_perform_inComment_exportDirective() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+import 'dart:async';
+/// Use [Future].
+export 'dart:math';
+''');
+    _computeUsedElements(source);
+    expect(usedElementNames, unorderedEquals(['Future']));
+  }
+
+  test_perform_inComment_importDirective() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+import 'dart:async';
+/// Use [Future].
+import 'dart:math';
+''');
+    _computeUsedElements(source);
+    expect(usedElementNames, unorderedEquals(['Future']));
+  }
+
+  test_perform_inComment_libraryDirective() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+/// Use [Future].
+library test;
+import 'dart:async';
+''');
+    _computeUsedElements(source);
+    expect(usedElementNames, unorderedEquals(['Future']));
+  }
+
+  test_perform_inComment_topLevelFunction() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+import 'dart:async';
+/// Use [Future].
+main() {}
+''');
+    _computeUsedElements(source);
+    expect(usedElementNames, unorderedEquals(['Future']));
+  }
+
   void _computeUsedElements(Source source) {
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
     computeResult(target, USED_IMPORTED_ELEMENTS,
@@ -2664,9 +2747,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT9);
-    expect(outputs[RESOLVED_UNIT9], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
+    computeResult(target, RESOLVED_UNIT10);
+    expect(outputs[RESOLVED_UNIT10], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
   }
 
   void test_perform() {
@@ -2686,9 +2769,9 @@
 class Y {}
 class Z {}
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10,
         matcher: isInferInstanceMembersInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
     VariableDeclaration field = AstFinder.getFieldInClass(unit, 'B', 'f');
     MethodDeclaration method = AstFinder.getMethodInClass(unit, 'B', 'm');
     DartType typeX = AstFinder.getClass(unit, 'X').element.type;
@@ -2720,12 +2803,12 @@
 }
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9,
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT10,
         matcher: isInferInstanceMembersInUnitTask);
-    CompilationUnit firstUnit = outputs[RESOLVED_UNIT9];
+    CompilationUnit firstUnit = outputs[RESOLVED_UNIT10];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9);
-    CompilationUnit secondUnit = outputs[RESOLVED_UNIT9];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT10);
+    CompilationUnit secondUnit = outputs[RESOLVED_UNIT10];
 
     VariableDeclaration variableA =
         AstFinder.getTopLevelVariable(firstUnit, 'a');
@@ -2752,8 +2835,8 @@
   String field = topLevel;
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
     VariableDeclaration topLevelDecl =
         AstFinder.getTopLevelVariable(unit, 'topLevel');
     VariableDeclaration fieldDecl =
@@ -2770,6 +2853,12 @@
 
 @reflectiveTest
 class InferStaticVariableTypesInUnitTaskTest extends _AbstractDartTaskTest {
+  @override
+  void setUp() {
+    super.setUp();
+    enableStrongMode();
+  }
+
   test_created_resolved_unit() {
     Source source = newSource(
         '/test.dart',
@@ -2778,9 +2867,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT7);
-    expect(outputs[RESOLVED_UNIT7], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT7], isTrue);
+    computeResult(target, RESOLVED_UNIT8);
+    expect(outputs[RESOLVED_UNIT8], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
   }
 
   void test_perform_const_field() {
@@ -2792,14 +2881,26 @@
   static const X = "";
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
         matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
+    CompilationUnit unit = outputs[RESOLVED_UNIT8];
     VariableDeclaration declaration = AstFinder.getFieldInClass(unit, 'M', 'X');
     InterfaceType stringType = context.typeProvider.stringType;
     expect(declaration.element.type, stringType);
   }
 
+  test_perform_hasParseError() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+@(i $=
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT8);
+    expect(outputs[RESOLVED_UNIT8], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
+  }
+
   void test_perform_nestedDeclarations() {
     enableStrongMode();
     AnalysisTarget source = newSource(
@@ -2811,7 +2912,7 @@
   return xSquared;
 };
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
         matcher: isInferStaticVariableTypesInUnitTask);
   }
 
@@ -2834,12 +2935,12 @@
 class M {}
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT7,
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8,
         matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit firstUnit = outputs[RESOLVED_UNIT7];
+    CompilationUnit firstUnit = outputs[RESOLVED_UNIT8];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT7);
-    CompilationUnit secondUnit = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8);
+    CompilationUnit secondUnit = outputs[RESOLVED_UNIT8];
 
     VariableDeclaration variableA =
         AstFinder.getTopLevelVariable(firstUnit, 'a');
@@ -2868,9 +2969,9 @@
   return 1 + X;
 };
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
         matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
+    CompilationUnit unit = outputs[RESOLVED_UNIT8];
     TopLevelVariableDeclaration declaration = unit.declarations[1];
     FunctionExpression function =
         declaration.variables.variables[0].initializer;
@@ -2892,8 +2993,8 @@
   var field = '';
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     VariableDeclaration declaration =
         AstFinder.getFieldInClass(unit, 'C', 'field');
     VariableElement variable = declaration.name.staticElement;
@@ -2908,8 +3009,8 @@
         '''
 var topLevel = '';
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     VariableDeclaration declaration =
         AstFinder.getTopLevelVariable(unit, 'topLevel');
     VariableElement variable = declaration.name.staticElement;
@@ -2928,8 +3029,8 @@
   var field3 = topLevel3;
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     VariableDeclaration topLevelDecl =
         AstFinder.getTopLevelVariable(unit, 'topLevel3');
     VariableDeclaration fieldDecl =
@@ -2955,8 +3056,8 @@
   var field = topLevel;
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     VariableElement topLevel =
         AstFinder.getTopLevelVariable(unit, 'topLevel').name.staticElement;
     VariableElement field =
@@ -2978,8 +3079,8 @@
 var pi = piFirst ? 3.14 : tau / 2;
 var tau = piFirst ? pi * 2 : 6.28;
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     VariableElement piFirst =
         AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
     VariableElement pi =
@@ -3001,8 +3102,8 @@
         '''
 var a = '' / null;
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     VariableElement a =
         AstFinder.getTopLevelVariable(unit, 'a').name.staticElement;
 
@@ -3018,8 +3119,8 @@
         '''
 var a = null;
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     VariableElement a =
         AstFinder.getTopLevelVariable(unit, 'a').name.staticElement;
 
@@ -3065,6 +3166,11 @@
 
 @reflectiveTest
 class LibraryUnitErrorsTaskTest extends _AbstractDartTaskTest {
+  List<AnalysisError> getLibraryUnitErrors(
+      Map<ResultDescriptor, dynamic> outputs) {
+    return outputs[LIBRARY_UNIT_ERRORS] as List<AnalysisError>;
+  }
+
   test_perform_definingCompilationUnit() {
     AnalysisTarget library =
         newSource('/test.dart', 'library test; import "dart:math";');
@@ -3072,7 +3178,7 @@
         new LibrarySpecificUnit(library, library), LIBRARY_UNIT_ERRORS,
         matcher: isLibraryUnitErrorsTask);
     expect(outputs, hasLength(1));
-    List<AnalysisError> errors = outputs[LIBRARY_UNIT_ERRORS];
+    List<AnalysisError> errors = getLibraryUnitErrors(outputs);
     expect(errors, hasLength(1));
   }
 
@@ -3083,7 +3189,7 @@
     computeResult(new LibrarySpecificUnit(library, part), LIBRARY_UNIT_ERRORS,
         matcher: isLibraryUnitErrorsTask);
     expect(outputs, hasLength(1));
-    List<AnalysisError> errors = outputs[LIBRARY_UNIT_ERRORS];
+    List<AnalysisError> errors = getLibraryUnitErrors(outputs);
     expect(errors, hasLength(0));
   }
 }
@@ -3256,7 +3362,8 @@
     computeResult(source, PARSED_UNIT, matcher: isParseDartTask);
   }
 
-  static void _assertHasCore(List<Source> sources, int lenght) {
+  static void _assertHasCore(dynamic sourceList, int lenght) {
+    List<Source> sources = sourceList as List<Source>;
     expect(sources, hasLength(lenght));
     expect(sources, contains(predicate((Source s) {
       return s.fullName.endsWith('core.dart');
@@ -3290,7 +3397,8 @@
     computeResult(target, PROPAGABLE_VARIABLES_IN_UNIT,
         matcher: isPartiallyResolveUnitReferencesTask);
     // PROPAGABLE_VARIABLES_IN_UNIT
-    List<VariableElement> variables = outputs[PROPAGABLE_VARIABLES_IN_UNIT];
+    List<VariableElement> variables =
+        outputs[PROPAGABLE_VARIABLES_IN_UNIT] as List<VariableElement>;
     expect(variables.map((v) => v.displayName),
         unorderedEquals(['t1', 't2', 'fs1', 'fs2', 'fi1', 'fi2']));
   }
@@ -3319,11 +3427,11 @@
   new A<int>().m();
 }
 ''');
-    computeResult(new LibrarySpecificUnit(sourceC, sourceC), RESOLVED_UNIT5,
+    computeResult(new LibrarySpecificUnit(sourceC, sourceC), RESOLVED_UNIT6,
         matcher: isPartiallyResolveUnitReferencesTask);
     // validate
     expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(0));
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     expect(unit, isNotNull);
 
     FunctionDeclaration mainFunction = unit.declarations[0];
@@ -3351,13 +3459,13 @@
 }
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5,
+    computeResult(target, RESOLVED_UNIT6,
         matcher: isPartiallyResolveUnitReferencesTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     // INFERABLE_STATIC_VARIABLES_IN_UNIT
     {
       List<VariableElement> variables =
-          outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT];
+          outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] as List<VariableElement>;
       expect(variables, hasLength(4));
       expect(variables.map((v) => v.displayName),
           unorderedEquals(['a', 'b', 'd', 'f']));
@@ -3394,9 +3502,9 @@
 }
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5,
+    computeResult(target, RESOLVED_UNIT6,
         matcher: isPartiallyResolveUnitReferencesTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     NodeList<CompilationUnitMember> declarations = unit.declarations;
 
     void expectReference(BlockFunctionBody body, bool isResolved) {
@@ -3445,9 +3553,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT6);
-    expect(outputs[RESOLVED_UNIT6], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT6], isTrue);
+    computeResult(target, RESOLVED_UNIT7);
+    expect(outputs[RESOLVED_UNIT7], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT7], isTrue);
   }
 
   void test_perform_cycle() {
@@ -3459,9 +3567,9 @@
 final tau = piFirst ? pi * 2 : 6.28;
 ''');
     // compute
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7,
         matcher: isPropagateVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT6];
+    CompilationUnit unit = outputs[RESOLVED_UNIT7];
     // verify
     TopLevelVariableElement piFirst =
         AstFinder.getTopLevelVariableElement(unit, 'piFirst');
@@ -3484,9 +3592,9 @@
 final c = '2';
 ''');
     // compute
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7,
         matcher: isPropagateVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT6];
+    CompilationUnit unit = outputs[RESOLVED_UNIT7];
     // verify
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -3509,8 +3617,8 @@
 final pi = piFirst ? 3.14 : tau / 2;
 final tau = piFirst ? pi * 2 : 6.28;
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     TopLevelVariableElement piFirst =
         AstFinder.getTopLevelVariableElement(unit, 'piFirst');
     TopLevelVariableElement pi =
@@ -3532,8 +3640,8 @@
         '''
 var a = null;
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     TopLevelVariableElement a = AstFinder.getTopLevelVariableElement(unit, 'a');
     // compute
     computeResult(a, PROPAGATED_VARIABLE, matcher: isPropagateVariableTypeTask);
@@ -3548,8 +3656,8 @@
 final b = 1;
 final c = '2';
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
     TopLevelVariableElement elementA =
         AstFinder.getTopLevelVariableElement(unit, 'a');
     TopLevelVariableElement elementB =
@@ -3568,6 +3676,57 @@
 }
 
 @reflectiveTest
+class ResolveDirectiveElementsTaskTest extends _AbstractDartTaskTest {
+  test_perform() {
+    List<Source> sources = newSources({
+      '/libA.dart': '''
+library libA;
+import 'libB.dart';
+export 'libC.dart';
+''',
+      '/libB.dart': '''
+library libB;
+''',
+      '/libC.dart': '''
+library libC;
+'''
+    });
+    Source sourceA = sources[0];
+    LibrarySpecificUnit targetA = new LibrarySpecificUnit(sourceA, sourceA);
+    // build directive elements
+    computeResult(sourceA, LIBRARY_ELEMENT2,
+        matcher: isBuildDirectiveElementsTask);
+    // prepare outputs
+    LibraryElement libraryElementA = outputs[LIBRARY_ELEMENT2];
+    LibraryElement libraryElementB = libraryElementA.imports[0].importedLibrary;
+    LibraryElement libraryElementC = libraryElementA.exports[0].exportedLibrary;
+    // clear elements in directive ASTs
+    {
+      CompilationUnit unitA = context.getResult(targetA, RESOLVED_UNIT1);
+      unitA.directives[1].element = null;
+      unitA.directives[2].element = null;
+    }
+    // resolve directive ASTs
+    computeResult(targetA, RESOLVED_UNIT2,
+        matcher: isResolveDirectiveElementsTask);
+    // validate that directive ASTs have elements
+    CompilationUnit unitA = context.getResult(targetA, RESOLVED_UNIT2);
+    {
+      ImportDirective importNode = unitA.directives[1];
+      ImportElement importElement = importNode.element;
+      expect(importElement, isNotNull);
+      expect(importElement.importedLibrary, libraryElementB);
+    }
+    {
+      ExportDirective exportNode = unitA.directives[2];
+      ExportElement exportElement = exportNode.element;
+      expect(exportElement, isNotNull);
+      expect(exportElement.exportedLibrary, libraryElementC);
+    }
+  }
+}
+
+@reflectiveTest
 class ResolveInstanceFieldsInUnitTaskTest extends _AbstractDartTaskTest {
   @override
   void setUp() {
@@ -3583,9 +3742,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT8);
-    expect(outputs[RESOLVED_UNIT8], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
+    computeResult(target, RESOLVED_UNIT9);
+    expect(outputs[RESOLVED_UNIT9], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
   }
 
   // Test inference of instance fields across units
@@ -3615,16 +3774,16 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT8);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT8];
+        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
 
     // B.b2 shoud be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
         AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT8);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT8];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
 
     // B.b2 should now be fully resolved and inferred.
     assertVariableDeclarationTypes(
@@ -3635,7 +3794,7 @@
         AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT8);
+        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
 
     // A.a2 should now be fully resolved and inferred.
     assertVariableDeclarationTypes(
@@ -3672,15 +3831,15 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT8);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT8];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
 
     // A.a2 should now be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
         AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT8);
+        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
 
     // A.a2 should now be fully resolved and inferred (but not re-resolved).
     assertVariableDeclarationTypes(
@@ -3718,8 +3877,8 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT8);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT8];
+        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
 
     assertVariableDeclarationTypes(
         AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
@@ -3727,8 +3886,8 @@
         AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT8);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT8];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
 
     assertVariableDeclarationTypes(
         AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
@@ -3741,7 +3900,7 @@
         AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT8);
+        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
 
     assertVariableDeclarationTypes(
         AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
@@ -3780,8 +3939,8 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT8);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT8];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
 
     // A.a2 should now be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
@@ -3792,7 +3951,7 @@
         AstFinder.getFieldInClass(unit0, "B", "b2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT8);
+        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
 
     // A.a2 should now be fully resolved and inferred (but not re-resolved).
     assertVariableDeclarationTypes(
@@ -3901,9 +4060,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT10);
-    expect(outputs[RESOLVED_UNIT10], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
+    computeResult(target, RESOLVED_UNIT11);
+    expect(outputs[RESOLVED_UNIT11], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
   }
 
   void test_perform() {
@@ -3920,9 +4079,9 @@
   }
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
         matcher: isResolveUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     FunctionDeclaration f = unit.declarations[0];
     _assertResolved(f.functionExpression.body);
@@ -3949,10 +4108,10 @@
   a.v.isEven;
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
         matcher: isResolveUnitTask);
     expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
     FunctionDeclaration main = unit.declarations[0];
     BlockFunctionBody body = main.functionExpression.body;
     ExpressionStatement statement = body.block.statements.single;
@@ -3977,9 +4136,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT3);
-    expect(outputs[RESOLVED_UNIT3], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT3], isTrue);
+    computeResult(target, RESOLVED_UNIT4);
+    expect(outputs[RESOLVED_UNIT4], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT4], isTrue);
   }
 
   test_perform() {
@@ -3991,9 +4150,9 @@
 int f(String p) => p.length;
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT3, matcher: isResolveUnitTypeNamesTask);
+    computeResult(target, RESOLVED_UNIT4, matcher: isResolveUnitTypeNamesTask);
     // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT3];
+    CompilationUnit unit = outputs[RESOLVED_UNIT4];
     {
       ClassDeclaration nodeA = unit.declarations[0];
       ClassDeclaration nodeB = unit.declarations[1];
@@ -4033,9 +4192,9 @@
 typedef String G(int p);
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT3, matcher: isResolveUnitTypeNamesTask);
+    computeResult(target, RESOLVED_UNIT4, matcher: isResolveUnitTypeNamesTask);
     // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT3];
+    CompilationUnit unit = outputs[RESOLVED_UNIT4];
     FunctionTypeAlias nodeF = unit.declarations[0];
     FunctionTypeAlias nodeG = unit.declarations[1];
     {
@@ -4089,9 +4248,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT4);
-    expect(outputs[RESOLVED_UNIT4], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT4], isTrue);
+    computeResult(target, RESOLVED_UNIT5);
+    expect(outputs[RESOLVED_UNIT5], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT5], isTrue);
   }
 
   test_perform_buildClosureLibraryElements() {
@@ -4102,7 +4261,7 @@
 }
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT4,
+    computeResult(target, RESOLVED_UNIT5,
         matcher: isResolveVariableReferencesTask);
   }
 
@@ -4124,10 +4283,10 @@
 }
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT4,
+    computeResult(target, RESOLVED_UNIT5,
         matcher: isResolveVariableReferencesTask);
     // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT4];
+    CompilationUnit unit = outputs[RESOLVED_UNIT5];
     FunctionDeclaration mainDeclaration = unit.declarations[0];
     FunctionBody body = mainDeclaration.functionExpression.body;
     FunctionElement main = mainDeclaration.element;
@@ -4151,10 +4310,10 @@
 }
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT4,
+    computeResult(target, RESOLVED_UNIT5,
         matcher: isResolveVariableReferencesTask);
     // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT4];
+    CompilationUnit unit = outputs[RESOLVED_UNIT5];
     FunctionDeclaration mainDeclaration = unit.declarations[0];
     FunctionBody body = mainDeclaration.functionExpression.body;
     FunctionElement main = mainDeclaration.element;
@@ -4233,8 +4392,8 @@
 var pi = piFirst ? 3.14 : tau / 2;
 var tau = piFirst ? pi * 2 : 6.28;
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
     VariableElement piFirst =
         AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
     VariableElement pi =
@@ -4276,11 +4435,11 @@
           }
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT10);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT10];
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT11];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT10);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT10];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
+    CompilationUnit unit2 = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
 
@@ -4327,7 +4486,7 @@
     '''
     });
     List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT10).toList();
+        computeLibraryResults(sources, RESOLVED_UNIT11).toList();
     CompilationUnit unit0 = units[0];
     CompilationUnit unit1 = units[1];
     CompilationUnit unit2 = units[2];
@@ -4374,7 +4533,7 @@
     '''
     });
     List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT10).toList();
+        computeLibraryResults(sources, RESOLVED_UNIT11).toList();
     CompilationUnit unit0 = units[0];
     CompilationUnit unit2 = units[2];
 
@@ -4415,11 +4574,11 @@
           }
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT10);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT10];
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT11];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT10);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT10];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
+    CompilationUnit unit2 = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -4469,7 +4628,7 @@
     '''
     });
     List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT10).toList();
+        computeLibraryResults(sources, RESOLVED_UNIT11).toList();
     CompilationUnit unit0 = units[0];
     CompilationUnit unit1 = units[1];
     CompilationUnit unit2 = units[2];
@@ -4505,8 +4664,8 @@
         y = "hi";
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -4544,8 +4703,8 @@
         final z = 42; // should infer `int`
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -4593,8 +4752,8 @@
       int y = 0; // field def after use
       final z = 42; // should infer `int`
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -4646,8 +4805,8 @@
         new A().y2 = /*severe:StaticTypeError*/"hi";
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -4688,8 +4847,8 @@
         x = "hi";
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -5037,7 +5196,7 @@
    * Fill [errorListener] with [result] errors in the current [task].
    */
   void _fillErrorListener(ResultDescriptor<List<AnalysisError>> result) {
-    List<AnalysisError> errors = task.outputs[result];
+    List<AnalysisError> errors = task.outputs[result] as List<AnalysisError>;
     expect(errors, isNotNull, reason: result.name);
     errorListener = new GatheringErrorListener();
     errorListener.addAll(errors);
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index bd21675..efbf9ee 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -241,8 +241,8 @@
 
   test_performAnalysisTask_infiniteLoop_handled() {
     AnalysisTarget target = new TestSource();
-    ResultDescriptor resultA = new ResultDescriptor('resultA', -1);
-    ResultDescriptor resultB = new ResultDescriptor('resultB', -2);
+    ResultDescriptor<int> resultA = new ResultDescriptor<int>('resultA', -1);
+    ResultDescriptor<int> resultB = new ResultDescriptor<int>('resultB', -2);
     // configure tasks
     TestAnalysisTask task1;
     TestAnalysisTask task2;
@@ -290,8 +290,8 @@
 
   test_performAnalysisTask_infiniteLoop_unhandled() {
     AnalysisTarget target = new TestSource();
-    ResultDescriptor resultA = new ResultDescriptor('resultA', -1);
-    ResultDescriptor resultB = new ResultDescriptor('resultB', -2);
+    ResultDescriptor<int> resultA = new ResultDescriptor<int>('resultA', -1);
+    ResultDescriptor<int> resultB = new ResultDescriptor<int>('resultB', -2);
     // configure tasks
     TestAnalysisTask task1;
     TestAnalysisTask task2;
@@ -324,8 +324,8 @@
 
   test_performAnalysisTask_inputsFirst() {
     AnalysisTarget target = new TestSource();
-    ResultDescriptor resultA = new ResultDescriptor('resultA', -1);
-    ResultDescriptor resultB = new ResultDescriptor('resultB', -2);
+    ResultDescriptor<int> resultA = new ResultDescriptor<int>('resultA', -1);
+    ResultDescriptor<int> resultB = new ResultDescriptor<int>('resultB', -2);
     // configure tasks
     TestAnalysisTask task1;
     TestAnalysisTask task2;
diff --git a/pkg/analyzer/test/src/task/inputs_test.dart b/pkg/analyzer/test/src/task/inputs_test.dart
index be97598..509c296 100644
--- a/pkg/analyzer/test/src/task/inputs_test.dart
+++ b/pkg/analyzer/test/src/task/inputs_test.dart
@@ -141,7 +141,8 @@
 
   test_toList() {
     var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
-    TaskInput<List> input2 = input.toList((target) => 'name');
+    TaskInput<List> input2 =
+        input.toList((target) => new SimpleTaskInput(target, null));
     expect(input2,
         new isInstanceOf<ListToListTaskInput<AnalysisTarget, String>>());
   }
@@ -155,7 +156,8 @@
 
   test_toMap() {
     var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
-    TaskInput<Map> input2 = input.toMap((target) => 'name');
+    TaskInput<Map> input2 =
+        input.toMap((target) => new SimpleTaskInput(target, null));
     expect(
         input2, new isInstanceOf<ListToMapTaskInput<AnalysisTarget, String>>());
   }
@@ -170,8 +172,8 @@
 @reflectiveTest
 class ListToListTaskInputBuilderTest extends EngineTestCase {
   static final AnalysisTarget target1 = new TestSource();
-  static final ResultDescriptorImpl result1 =
-      new ResultDescriptorImpl('result1', null);
+  static final ResultDescriptorImpl<List> result1 =
+      new ResultDescriptorImpl<List>('result1', null);
   static final ResultDescriptorImpl result2 =
       new ResultDescriptorImpl('result2', null);
   static final ListToListTaskInput input = new ListToListTaskInput(
@@ -342,11 +344,11 @@
 @reflectiveTest
 class ListToListTaskInputTest extends EngineTestCase {
   static final AnalysisTarget target = new TestSource();
-  static final ResultDescriptorImpl result =
-      new ResultDescriptorImpl('result', null);
+  static final ResultDescriptorImpl<List> result =
+      new ResultDescriptorImpl<List>('result', null);
 
   test_create() {
-    SimpleTaskInput baseAccessor = result.of(target);
+    SimpleTaskInput<List> baseAccessor = result.of(target);
     GenerateTaskInputs generate = (object) {};
     ListToListTaskInput input = new ListToListTaskInput(baseAccessor, generate);
     expect(input, isNotNull);
@@ -355,7 +357,7 @@
   }
 
   test_createBuilder() {
-    SimpleTaskInput baseAccessor = result.of(target);
+    SimpleTaskInput<List> baseAccessor = result.of(target);
     GenerateTaskInputs generate = (object) {};
     ListToListTaskInput input = new ListToListTaskInput(baseAccessor, generate);
     expect(input.createBuilder(), isNotNull);
@@ -365,8 +367,8 @@
 @reflectiveTest
 class ListToMapTaskInputBuilderTest extends EngineTestCase {
   static final AnalysisTarget target1 = new TestSource('target1');
-  static final ResultDescriptorImpl result1 =
-      new ResultDescriptorImpl('result1', null);
+  static final ResultDescriptorImpl<List> result1 =
+      new ResultDescriptorImpl<List>('result1', null);
   static final ResultDescriptorImpl result2 =
       new ResultDescriptorImpl('result2', null);
   static final ListToMapTaskInput input = new ListToMapTaskInput(
@@ -535,11 +537,11 @@
 @reflectiveTest
 class ListToMapTaskInputTest extends EngineTestCase {
   static final AnalysisTarget target = new TestSource();
-  static final ResultDescriptorImpl result =
-      new ResultDescriptorImpl('result', null);
+  static final ResultDescriptorImpl<List> result =
+      new ResultDescriptorImpl<List>('result', null);
 
   test_create() {
-    SimpleTaskInput baseAccessor = result.of(target);
+    SimpleTaskInput<List> baseAccessor = result.of(target);
     GenerateTaskInputs generate = (object) {};
     ListToMapTaskInput input = new ListToMapTaskInput(baseAccessor, generate);
     expect(input, isNotNull);
@@ -548,7 +550,7 @@
   }
 
   test_createBuilder() {
-    SimpleTaskInput baseAccessor = result.of(target);
+    SimpleTaskInput<List> baseAccessor = result.of(target);
     GenerateTaskInputs generate = (object) {};
     ListToMapTaskInput input = new ListToMapTaskInput(baseAccessor, generate);
     expect(input.createBuilder(), isNotNull);
@@ -561,7 +563,7 @@
   static final ResultDescriptorImpl result =
       new ResultDescriptorImpl('result', null);
   static final SimpleTaskInput baseInput = new SimpleTaskInput(target, result);
-  static final Function mapper = (x) => [x];
+  static final mapper = (Object x) => [x];
   static final ObjectToListTaskInput input =
       new ObjectToListTaskInput(baseInput, mapper);
 
@@ -689,7 +691,7 @@
 
   test_create() {
     SimpleTaskInput baseInput = new SimpleTaskInput(target, result);
-    Function mapper = (x) => [x];
+    var mapper = (Object x) => [x];
     ObjectToListTaskInput input = new ObjectToListTaskInput(baseInput, mapper);
     expect(input, isNotNull);
     expect(input.baseInput, baseInput);
@@ -698,7 +700,7 @@
 
   test_createBuilder() {
     SimpleTaskInput baseInput = new SimpleTaskInput(target, result);
-    Function mapper = (x) => [x];
+    var mapper = (Object x) => [x];
     ObjectToListTaskInput input = new ObjectToListTaskInput(baseInput, mapper);
     expect(input.createBuilder(),
         new isInstanceOf<ObjectToListTaskInputBuilder>());
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 77e2990..4288f15 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -114,7 +114,8 @@
 ''');
 
     List<ErrorProcessor> processors =
-        context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+        context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS)
+        as List<ErrorProcessor>;
     expect(processors, hasLength(2));
 
     var unused_local = new AnalysisError(
@@ -222,7 +223,8 @@
     AnalysisTarget target = newSource(optionsFilePath, code);
     computeResult(target, ANALYSIS_OPTIONS_ERRORS);
     expect(task, isGenerateOptionsErrorsTask);
-    List<AnalysisError> errors = outputs[ANALYSIS_OPTIONS_ERRORS];
+    List<AnalysisError> errors =
+        outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
     expect(errors, hasLength(1));
     expect(errors[0].errorCode, AnalysisOptionsErrorCode.PARSE_ERROR);
   }
@@ -250,7 +252,8 @@
     AnalysisTarget target = newSource(optionsFilePath, code);
     computeResult(target, ANALYSIS_OPTIONS_ERRORS);
     expect(task, isGenerateOptionsErrorsTask);
-    List<AnalysisError> errors = outputs[ANALYSIS_OPTIONS_ERRORS];
+    List<AnalysisError> errors =
+        outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
     expect(errors, hasLength(1));
     expect(errors[0].errorCode,
         AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES);
@@ -396,7 +399,7 @@
         [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
   }
 
-  void validate(String source, List<AnalysisOptionsErrorCode> expected) {
+  void validate(String source, List<ErrorCode> expected) {
     var options = optionsProvider.getOptionsFromString(source);
     var errors = validator.validate(options);
     expect(errors.map((AnalysisError e) => e.errorCode),
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index f17517d..6e5b83b 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -63,8 +63,9 @@
   var uriResolver = new _TestUriResolver(files);
   // Enable task model strong mode
   var context = AnalysisEngine.instance.createAnalysisContext();
-  context.analysisOptions.strongMode = true;
-  (context.analysisOptions as AnalysisOptionsImpl).strongModeHints = true;
+  AnalysisOptionsImpl options = context.analysisOptions as AnalysisOptionsImpl;
+  options.strongMode = true;
+  options.strongModeHints = true;
   context.sourceFactory =
       new SourceFactory([new DartUriResolver(new MockSdk()), uriResolver]);
 
diff --git a/pkg/analyzer/test/src/task/strong_mode_test.dart b/pkg/analyzer/test/src/task/strong_mode_test.dart
index 097d5d4..c4589f7 100644
--- a/pkg/analyzer/test/src/task/strong_mode_test.dart
+++ b/pkg/analyzer/test/src/task/strong_mode_test.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
 import 'package:unittest/unittest.dart';
@@ -18,14 +19,17 @@
 main() {
   initializeTestEnvironment();
   runReflectiveTests(InstanceMemberInferrerTest);
+  runReflectiveTests(SetFieldTypeTest);
   runReflectiveTests(VariableGathererTest);
 }
 
 @reflectiveTest
 class InstanceMemberInferrerTest extends AbstractContextTest {
-  InstanceMemberInferrer get createInferrer =>
-      new InstanceMemberInferrer(context.typeProvider,
-          typeSystem: context.typeSystem);
+  InstanceMemberInferrer createInferrer(LibraryElement library) {
+    return new InstanceMemberInferrer(
+        context.typeProvider, new InheritanceManager(library),
+        typeSystem: context.typeSystem);
+  }
 
   /**
    * Add a source with the given [content] and return the result of resolving
@@ -37,13 +41,12 @@
   }
 
   void test_creation() {
-    InstanceMemberInferrer inferrer = createInferrer;
+    InstanceMemberInferrer inferrer = createInferrer(null);
     expect(inferrer, isNotNull);
     expect(inferrer.typeSystem, isNotNull);
   }
 
   void test_inferCompilationUnit_field_multiple_different() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -62,14 +65,13 @@
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_field_multiple_different_generic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A<E> {
@@ -88,14 +90,13 @@
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_field_multiple_dynamic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -114,14 +115,13 @@
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_field_multiple_same() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -143,14 +143,13 @@
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldC.type, expectedType);
     expect(getterC.returnType, expectedType);
   }
 
   void test_inferCompilationUnit_field_noOverride() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -163,7 +162,7 @@
     expect(fieldA.type.isDynamic, isTrue);
     expect(getterA.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    InstanceMemberInferrer inferrer = _runInferrer(unit);
 
     DartType intType = inferrer.typeProvider.intType;
     expect(fieldA.type, intType);
@@ -171,7 +170,6 @@
   }
 
   void test_inferCompilationUnit_field_noOverride_bottom() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -184,14 +182,13 @@
     expect(fieldA.type.isDynamic, isTrue);
     expect(getterA.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldA.type.isDynamic, isTrue);
     expect(getterA.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_field_single_explicitlyDynamic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -210,14 +207,13 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(getterB.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldB.type, fieldA.type);
     expect(getterB.returnType, getterA.returnType);
   }
 
   void test_inferCompilationUnit_field_single_final() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -236,14 +232,13 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(getterB.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldB.type, fieldA.type);
     expect(getterB.returnType, getterA.returnType);
   }
 
   void test_inferCompilationUnit_field_single_final_narrowType() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -259,14 +254,13 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(getterB.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    InstanceMemberInferrer inferrer = _runInferrer(unit);
 
     expect(fieldB.type, inferrer.typeProvider.intType);
     expect(getterB.returnType, fieldB.type);
   }
 
   void test_inferCompilationUnit_field_single_generic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A<E> {
@@ -283,14 +277,13 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(getterB.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldB.type, typeBE);
     expect(getterB.returnType, typeBE);
   }
 
   void test_inferCompilationUnit_field_single_inconsistentAccessors() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -307,14 +300,13 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(getterB.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldB.type.isDynamic, isTrue);
     expect(getterB.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_field_single_noModifiers() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -333,14 +325,13 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(getterB.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldB.type, fieldA.type);
     expect(getterB.returnType, getterA.returnType);
   }
 
   void test_inferCompilationUnit_fieldFormal() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String fieldName = 'f';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -355,7 +346,7 @@
     expect(fieldA.type.isDynamic, isTrue);
     expect(paramA.type.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    InstanceMemberInferrer inferrer = _runInferrer(unit);
 
     DartType intType = inferrer.typeProvider.intType;
     expect(fieldA.type, intType);
@@ -363,7 +354,6 @@
   }
 
   void test_inferCompilationUnit_getter_multiple_different() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String getterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -382,14 +372,13 @@
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_getter_multiple_dynamic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String getterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -408,14 +397,13 @@
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_getter_multiple_same() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String getterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -437,14 +425,13 @@
     expect(fieldC.type.isDynamic, isTrue);
     expect(getterC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldC.type, expectedType);
     expect(getterC.returnType, expectedType);
   }
 
   void test_inferCompilationUnit_getter_single() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String getterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -463,14 +450,13 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(getterB.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldB.type, fieldA.type);
     expect(getterB.returnType, getterA.returnType);
   }
 
   void test_inferCompilationUnit_getter_single_generic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String getterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A<E> {
@@ -487,14 +473,13 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(getterB.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldB.type, typeBE);
     expect(getterB.returnType, typeBE);
   }
 
   void test_inferCompilationUnit_getter_single_inconsistentAccessors() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String getterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -514,7 +499,7 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(getterB.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     // Expected behavior is that the getter is inferred: getters and setters
     // are treated as independent methods.
@@ -523,17 +508,15 @@
   }
 
   void test_inferCompilationUnit_invalid_inheritanceCycle() {
-    InstanceMemberInferrer inferrer = createInferrer;
     CompilationUnitElement unit = resolve('''
 class A extends C {}
 class B extends A {}
 class C extends B {}
 ''');
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
   }
 
   void test_inferCompilationUnit_method_parameter_multiple_different() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -551,13 +534,12 @@
     ParameterElement parameterC = methodC.parameters[0];
     expect(parameterC.type.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(parameterC.type.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_method_parameter_multiple_named_different() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -575,13 +557,12 @@
     ParameterElement parameterC = methodC.parameters[0];
     expect(parameterC.type.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(parameterC.type.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_method_parameter_multiple_named_same() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -603,13 +584,12 @@
     ParameterElement parameterC = methodC.parameters[0];
     expect(parameterC.type.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(parameterC.type, expectedType);
   }
 
   void test_inferCompilationUnit_method_parameter_multiple_namedAndRequired() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -627,14 +607,13 @@
     ParameterElement parameterC = methodC.parameters[0];
     expect(parameterC.type.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(parameterC.type.isDynamic, isTrue);
   }
 
   void
       test_inferCompilationUnit_method_parameter_multiple_optionalAndRequired() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -656,13 +635,12 @@
     ParameterElement parameterC = methodC.parameters[0];
     expect(parameterC.type.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(parameterC.type, expectedType);
   }
 
   void test_inferCompilationUnit_method_parameter_single_generic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A<E> {
@@ -679,7 +657,7 @@
     expect(parameterC.type.isDynamic, isTrue);
     expect(methodC.type.typeArguments, [typeCE]);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(parameterC.type, classC.typeParameters[0].type);
     expect(methodC.type.typeArguments, [typeCE],
@@ -687,7 +665,6 @@
   }
 
   void test_inferCompilationUnit_method_return_multiple_different() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -704,13 +681,12 @@
     MethodElement methodC = classC.getMethod(methodName);
     expect(methodC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(methodC.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_method_return_multiple_different_generic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A<E> {
@@ -727,13 +703,12 @@
     MethodElement methodC = classC.getMethod(methodName);
     expect(methodC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(methodC.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_method_return_multiple_dynamic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -750,13 +725,12 @@
     MethodElement methodC = classC.getMethod(methodName);
     expect(methodC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(methodC.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_method_return_multiple_same_generic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A<E> {
@@ -773,13 +747,12 @@
     MethodElement methodC = classC.getMethod(methodName);
     expect(methodC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(methodC.returnType, classC.typeParameters[0].type);
   }
 
   void test_inferCompilationUnit_method_return_multiple_same_nonVoid() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -799,13 +772,12 @@
     MethodElement methodC = classC.getMethod(methodName);
     expect(methodC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(methodC.returnType, expectedType);
   }
 
   void test_inferCompilationUnit_method_return_multiple_same_void() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -825,13 +797,12 @@
     MethodElement methodC = classC.getMethod(methodName);
     expect(methodC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(methodC.returnType, expectedType);
   }
 
   void test_inferCompilationUnit_method_return_multiple_void() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -848,13 +819,12 @@
     MethodElement methodC = classC.getMethod(methodName);
     expect(methodC.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(methodC.returnType.isDynamic, isTrue);
   }
 
   void test_inferCompilationUnit_method_return_single() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -870,13 +840,12 @@
     MethodElement methodB = classB.getMethod(methodName);
     expect(methodB.returnType.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(methodB.returnType, methodA.returnType);
   }
 
   void test_inferCompilationUnit_method_return_single_generic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
 class A<E> {
@@ -892,7 +861,7 @@
     expect(methodB.returnType.isDynamic, isTrue);
     expect(methodB.type.typeArguments, [typeBE]);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(methodB.returnType, classB.typeParameters[0].type);
     expect(methodB.type.typeArguments, [typeBE],
@@ -900,7 +869,6 @@
   }
 
   void test_inferCompilationUnit_setter_single() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String setterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -919,14 +887,13 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(setterB.parameters[0].type.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldB.type, fieldA.type);
     expect(setterB.parameters[0].type, setterA.parameters[0].type);
   }
 
   void test_inferCompilationUnit_setter_single_generic() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String setterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A<E> {
@@ -943,14 +910,13 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(setterB.parameters[0].type.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     expect(fieldB.type, typeBE);
     expect(setterB.parameters[0].type, typeBE);
   }
 
   void test_inferCompilationUnit_setter_single_inconsistentAccessors() {
-    InstanceMemberInferrer inferrer = createInferrer;
     String getterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A {
@@ -969,7 +935,7 @@
     expect(fieldB.type.isDynamic, isTrue);
     expect(setterB.parameters[0].type.isDynamic, isTrue);
 
-    inferrer.inferCompilationUnit(unit);
+    _runInferrer(unit);
 
     // Expected behavior is that the getter is inferred: getters and setters
     // are treated as independent methods.
@@ -979,6 +945,29 @@
     // resolver would do if we explicitly typed the parameter as 'String'
     expect(fieldB.type, setterB.parameters[0].type);
   }
+
+  InstanceMemberInferrer _runInferrer(CompilationUnitElement unit) {
+    InstanceMemberInferrer inferrer = createInferrer(unit.library);
+    inferrer.inferCompilationUnit(unit);
+    return inferrer;
+  }
+}
+
+@reflectiveTest
+class SetFieldTypeTest extends AbstractContextTest {
+  void test_setter_withoutParameter() {
+    CompilationUnitElement unit = _resolve('''
+var x = 0;
+set x() {}
+''');
+    TopLevelVariableElement variable = unit.topLevelVariables.single;
+    setFieldType(variable, context.typeProvider.intType);
+  }
+
+  CompilationUnitElement _resolve(String content) {
+    Source source = addSource('/test.dart', content);
+    return context.resolveCompilationUnit2(source, source).element;
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/tool/task_dependency_graph/tasks.dot b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
index d77151b..4142a2a 100644
--- a/pkg/analyzer/tool/task_dependency_graph/tasks.dot
+++ b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
@@ -19,8 +19,8 @@
   BuildCompilationUnitElementTask -> RESOLVED_UNIT1
   BuildDirectiveElementsTask -> BUILD_DIRECTIVES_ERRORS
   BuildDirectiveElementsTask -> LIBRARY_ELEMENT2
-  BuildEnumMemberElementsTask -> CREATED_RESOLVED_UNIT2
-  BuildEnumMemberElementsTask -> RESOLVED_UNIT2
+  BuildEnumMemberElementsTask -> CREATED_RESOLVED_UNIT3
+  BuildEnumMemberElementsTask -> RESOLVED_UNIT3
   BuildExportNamespaceTask -> LIBRARY_ELEMENT4
   BuildLibraryElementTask -> BUILD_LIBRARY_ERRORS
   BuildLibraryElementTask -> IS_LAUNCHABLE
@@ -46,23 +46,24 @@
   CONTENT [shape=box]
   CREATED_RESOLVED_UNIT [shape=box]
   CREATED_RESOLVED_UNIT1 [shape=box]
-  CREATED_RESOLVED_UNIT10 -> ResolveConstantExpressionTask
+  CREATED_RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
+  CREATED_RESOLVED_UNIT10 -> InferStaticVariableTypeTask
+  CREATED_RESOLVED_UNIT10 -> PartiallyResolveUnitReferencesTask
+  CREATED_RESOLVED_UNIT10 -> ResolveInstanceFieldsInUnitTask
+  CREATED_RESOLVED_UNIT10 -> ResolveUnitTask
   CREATED_RESOLVED_UNIT10 [shape=box]
+  CREATED_RESOLVED_UNIT11 -> ResolveConstantExpressionTask
   CREATED_RESOLVED_UNIT11 [shape=box]
+  CREATED_RESOLVED_UNIT12 [shape=box]
   CREATED_RESOLVED_UNIT2 [shape=box]
   CREATED_RESOLVED_UNIT3 [shape=box]
   CREATED_RESOLVED_UNIT4 [shape=box]
   CREATED_RESOLVED_UNIT5 [shape=box]
   CREATED_RESOLVED_UNIT6 [shape=box]
-  CREATED_RESOLVED_UNIT7 -> ResolveInstanceFieldsInUnitTask
   CREATED_RESOLVED_UNIT7 [shape=box]
-  CREATED_RESOLVED_UNIT8 -> InferInstanceMembersInUnitTask
+  CREATED_RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
   CREATED_RESOLVED_UNIT8 [shape=box]
   CREATED_RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
-  CREATED_RESOLVED_UNIT9 -> InferStaticVariableTypeTask
-  CREATED_RESOLVED_UNIT9 -> PartiallyResolveUnitReferencesTask
-  CREATED_RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
-  CREATED_RESOLVED_UNIT9 -> ResolveUnitTask
   CREATED_RESOLVED_UNIT9 [shape=box]
   ComputeConstantDependenciesTask -> CONSTANT_DEPENDENCIES
   ComputeConstantValueTask -> CONSTANT_VALUE
@@ -85,8 +86,8 @@
   EXPORTED_LIBRARIES [shape=box]
   EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
   EXPORT_SOURCE_CLOSURE [shape=box]
-  EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT11
-  EvaluateUnitConstantsTask -> RESOLVED_UNIT11
+  EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT12
+  EvaluateUnitConstantsTask -> RESOLVED_UNIT12
   GatherUsedImportedElementsTask -> USED_IMPORTED_ELEMENTS
   GatherUsedLocalElementsTask -> USED_LOCAL_ELEMENTS
   GenerateHintsTask -> HINTS
@@ -109,11 +110,11 @@
   INFERRED_STATIC_VARIABLE -> InferStaticVariableTypesInUnitTask
   INFERRED_STATIC_VARIABLE [shape=box]
   IS_LAUNCHABLE [shape=box]
-  InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT9
-  InferInstanceMembersInUnitTask -> RESOLVED_UNIT9
+  InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT10
+  InferInstanceMembersInUnitTask -> RESOLVED_UNIT10
   InferStaticVariableTypeTask -> INFERRED_STATIC_VARIABLE
-  InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT7
-  InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT7
+  InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
+  InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT8
   LIBRARY_CYCLE [shape=box]
   LIBRARY_CYCLE_DEPENDENCIES -> InferInstanceMembersInUnitTask
   LIBRARY_CYCLE_DEPENDENCIES -> InferStaticVariableTypeTask
@@ -133,6 +134,7 @@
   LIBRARY_ELEMENT2 -> BuildSourceExportClosureTask
   LIBRARY_ELEMENT2 -> ComputeLibraryCycleTask
   LIBRARY_ELEMENT2 -> ReadyLibraryElement2Task
+  LIBRARY_ELEMENT2 -> ResolveDirectiveElementsTask
   LIBRARY_ELEMENT2 [shape=box]
   LIBRARY_ELEMENT3 -> BuildExportNamespaceTask
   LIBRARY_ELEMENT3 -> BuildTypeProviderTask
@@ -193,15 +195,15 @@
   ParseDartTask -> PARSE_ERRORS
   ParseDartTask -> SOURCE_KIND
   ParseDartTask -> UNITS
-  PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT5
+  PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT6
   PartiallyResolveUnitReferencesTask -> INFERABLE_STATIC_VARIABLES_IN_UNIT
   PartiallyResolveUnitReferencesTask -> PROPAGABLE_VARIABLES_IN_UNIT
-  PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT5
+  PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT6
   PropagateVariableTypeTask -> PROPAGATED_VARIABLE
   PropagateVariableTypesInLibraryClosureTask -> LIBRARY_ELEMENT7
   PropagateVariableTypesInLibraryTask -> LIBRARY_ELEMENT6
-  PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT6
-  PropagateVariableTypesInUnitTask -> RESOLVED_UNIT6
+  PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT7
+  PropagateVariableTypesInUnitTask -> RESOLVED_UNIT7
   READY_LIBRARY_ELEMENT2 -> ComputeLibraryCycleTask
   READY_LIBRARY_ELEMENT2 -> ReadyLibraryElement2Task
   READY_LIBRARY_ELEMENT2 [shape=box]
@@ -221,37 +223,39 @@
   RESOLVED_UNIT -> VerifyUnitTask
   RESOLVED_UNIT [shape=box]
   RESOLVED_UNIT1 -> BuildDirectiveElementsTask
-  RESOLVED_UNIT1 -> BuildEnumMemberElementsTask
   RESOLVED_UNIT1 -> BuildLibraryElementTask
+  RESOLVED_UNIT1 -> ResolveDirectiveElementsTask
   RESOLVED_UNIT1 [shape=box]
-  RESOLVED_UNIT10 -> EvaluateUnitConstantsTask
-  RESOLVED_UNIT10 -> GatherUsedImportedElementsTask
-  RESOLVED_UNIT10 -> GatherUsedLocalElementsTask
-  RESOLVED_UNIT10 -> ResolveLibraryReferencesTask
+  RESOLVED_UNIT10 -> ResolveUnitTask
   RESOLVED_UNIT10 [shape=box]
-  RESOLVED_UNIT11 -> StrongModeVerifyUnitTask
+  RESOLVED_UNIT11 -> EvaluateUnitConstantsTask
+  RESOLVED_UNIT11 -> GatherUsedImportedElementsTask
+  RESOLVED_UNIT11 -> GatherUsedLocalElementsTask
+  RESOLVED_UNIT11 -> ResolveLibraryReferencesTask
   RESOLVED_UNIT11 [shape=box]
-  RESOLVED_UNIT2 -> ResolveUnitTypeNamesTask
+  RESOLVED_UNIT12 -> StrongModeVerifyUnitTask
+  RESOLVED_UNIT12 [shape=box]
+  RESOLVED_UNIT2 -> BuildEnumMemberElementsTask
   RESOLVED_UNIT2 [shape=box]
-  RESOLVED_UNIT3 -> ResolveLibraryTypeNamesTask
-  RESOLVED_UNIT3 -> ResolveVariableReferencesTask
+  RESOLVED_UNIT3 -> ResolveUnitTypeNamesTask
   RESOLVED_UNIT3 [shape=box]
-  RESOLVED_UNIT4 -> PartiallyResolveUnitReferencesTask
+  RESOLVED_UNIT4 -> ResolveLibraryTypeNamesTask
+  RESOLVED_UNIT4 -> ResolveVariableReferencesTask
   RESOLVED_UNIT4 [shape=box]
-  RESOLVED_UNIT5 -> ComputeInferableStaticVariableDependenciesTask
-  RESOLVED_UNIT5 -> ComputePropagableVariableDependenciesTask
-  RESOLVED_UNIT5 -> PropagateVariableTypeTask
-  RESOLVED_UNIT5 -> PropagateVariableTypesInUnitTask
+  RESOLVED_UNIT5 -> PartiallyResolveUnitReferencesTask
   RESOLVED_UNIT5 [shape=box]
-  RESOLVED_UNIT6 -> InferStaticVariableTypeTask
-  RESOLVED_UNIT6 -> InferStaticVariableTypesInUnitTask
-  RESOLVED_UNIT6 -> PropagateVariableTypesInLibraryTask
+  RESOLVED_UNIT6 -> ComputeInferableStaticVariableDependenciesTask
+  RESOLVED_UNIT6 -> ComputePropagableVariableDependenciesTask
+  RESOLVED_UNIT6 -> PropagateVariableTypeTask
+  RESOLVED_UNIT6 -> PropagateVariableTypesInUnitTask
   RESOLVED_UNIT6 [shape=box]
-  RESOLVED_UNIT7 -> ResolveInstanceFieldsInUnitTask
+  RESOLVED_UNIT7 -> InferStaticVariableTypeTask
+  RESOLVED_UNIT7 -> InferStaticVariableTypesInUnitTask
+  RESOLVED_UNIT7 -> PropagateVariableTypesInLibraryTask
   RESOLVED_UNIT7 [shape=box]
-  RESOLVED_UNIT8 -> InferInstanceMembersInUnitTask
+  RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
   RESOLVED_UNIT8 [shape=box]
-  RESOLVED_UNIT9 -> ResolveUnitTask
+  RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
   RESOLVED_UNIT9 [shape=box]
   RESOLVE_TYPE_NAMES_ERRORS -> LibraryUnitErrorsTask
   RESOLVE_TYPE_NAMES_ERRORS [shape=box]
@@ -262,21 +266,23 @@
   ReadyLibraryElement6Task -> READY_LIBRARY_ELEMENT6
   ReadyResolvedUnitTask -> READY_RESOLVED_UNIT
   ResolveConstantExpressionTask -> CONSTANT_EXPRESSION_RESOLVED
-  ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT8
-  ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT8
+  ResolveDirectiveElementsTask -> CREATED_RESOLVED_UNIT2
+  ResolveDirectiveElementsTask -> RESOLVED_UNIT2
+  ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT9
+  ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT9
   ResolveLibraryReferencesTask -> LIBRARY_ELEMENT8
   ResolveLibraryReferencesTask -> REFERENCED_NAMES
   ResolveLibraryTask -> LIBRARY_ELEMENT
   ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT5
   ResolveUnitTask -> CONSTANT_EXPRESSIONS_DEPENDENCIES
-  ResolveUnitTask -> CREATED_RESOLVED_UNIT10
-  ResolveUnitTask -> RESOLVED_UNIT10
+  ResolveUnitTask -> CREATED_RESOLVED_UNIT11
+  ResolveUnitTask -> RESOLVED_UNIT11
   ResolveUnitTask -> RESOLVE_UNIT_ERRORS
-  ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT3
-  ResolveUnitTypeNamesTask -> RESOLVED_UNIT3
+  ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT4
+  ResolveUnitTypeNamesTask -> RESOLVED_UNIT4
   ResolveUnitTypeNamesTask -> RESOLVE_TYPE_NAMES_ERRORS
-  ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT4
-  ResolveVariableReferencesTask -> RESOLVED_UNIT4
+  ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT5
+  ResolveVariableReferencesTask -> RESOLVED_UNIT5
   ResolveVariableReferencesTask -> VARIABLE_REFERENCE_ERRORS
   SCAN_ERRORS -> dartErrorsForSource
   SCAN_ERRORS [shape=box]
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 95bed11..428869f 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -250,6 +250,7 @@
   ///   * if [options.enableTypeChecks] is false, then de-escalate checked-mode
   ///   compile time errors to a severity of [ErrorSeverity.INFO].
   ///   * if [options.hintsAreFatal] is true, escalate hints to errors.
+  ///   * if [options.lintsAreFatal] is true, escalate lints to errors.
   static ErrorSeverity computeSeverity(
       AnalysisError error, CommandLineOptions options,
       [AnalysisContext context]) {
@@ -270,6 +271,10 @@
       return ErrorSeverity.ERROR;
     }
 
+    if (options.lintsAreFatal && error.errorCode is LintCode) {
+      return ErrorSeverity.ERROR;
+    }
+
     return error.errorCode.errorSeverity;
   }
 
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 4bf126d..2c543fa 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -143,6 +143,9 @@
   /// Whether to use strong static checking.
   final bool strongMode;
 
+  /// Whether to treat lints as fatal
+  final bool lintsAreFatal;
+
   /// Initialize options from the given parsed [args].
   CommandLineOptions._fromArgs(
       ArgResults args, Map<String, String> definedVariables)
@@ -184,7 +187,8 @@
         showSdkWarnings = args['show-sdk-warnings'] || args['warnings'],
         sourceFiles = args.rest,
         warningsAreFatal = args['fatal-warnings'],
-        strongMode = args['strong'];
+        strongMode = args['strong'],
+        lintsAreFatal = args['fatal-lints'];
 
   /// Parse [args] into [CommandLineOptions] describing the specified
   /// analyzer options. In case of a format error, calls [printAndFail], which
@@ -303,6 +307,8 @@
           help: 'Treat non-type warnings as fatal.',
           defaultsTo: false,
           negatable: false)
+      ..addFlag('fatal-lints',
+          help: 'Treat lints as fatal.', defaultsTo: false, negatable: false)
       ..addFlag('package-warnings',
           help: 'Show warnings from package: imports.',
           defaultsTo: false,
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 63354da..6b546a6 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -45,6 +45,7 @@
         expect(options.sourceFiles, equals(['foo.dart']));
         expect(options.warningsAreFatal, isFalse);
         expect(options.strongMode, isFalse);
+        expect(options.lintsAreFatal, isFalse);
       });
 
       test('batch', () {
@@ -182,6 +183,12 @@
         expect(options.strongMode, isTrue);
       });
 
+      test('hintsAreFatal', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '--fatal-lints', 'foo.dart']);
+        expect(options.lintsAreFatal, isTrue);
+      });
+
       test("can't specify package and package-root", () {
         var failureMessage;
         CommandLineOptions.parse(
diff --git a/pkg/compiler/lib/compiler.dart b/pkg/compiler/lib/compiler.dart
index 445e2ca..b4c22eb 100644
--- a/pkg/compiler/lib/compiler.dart
+++ b/pkg/compiler/lib/compiler.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 import 'package:package_config/packages.dart';
 import 'compiler_new.dart' as new_api;
+import 'src/options.dart' show CompilerOptions;
 import 'src/old_to_new_api.dart';
 
 // Unless explicitly allowed, passing [:null:] for any argument to the
@@ -115,7 +116,7 @@
      Uri packageConfig,
      PackagesDiscoveryProvider packagesDiscoveryProvider]) {
 
-  new_api.CompilerOptions compilerOptions = new new_api.CompilerOptions.parse(
+  CompilerOptions compilerOptions = new CompilerOptions.parse(
       entryPoint: script,
       libraryRoot: libraryRoot,
       packageRoot: packageRoot,
diff --git a/pkg/compiler/lib/compiler_new.dart b/pkg/compiler/lib/compiler_new.dart
index fa405da..3988c2f 100644
--- a/pkg/compiler/lib/compiler_new.dart
+++ b/pkg/compiler/lib/compiler_new.dart
@@ -9,10 +9,9 @@
 
 import 'dart:async';
 import 'src/apiimpl.dart';
-import 'src/commandline_options.dart';
-import 'src/diagnostics/diagnostic_listener.dart' show DiagnosticOptions;
+import 'src/options.dart' show CompilerOptions;
 
-import 'compiler.dart' show Diagnostic, PackagesDiscoveryProvider;
+import 'compiler.dart' show Diagnostic;
 export 'compiler.dart' show Diagnostic, PackagesDiscoveryProvider;
 
 // Unless explicitly allowed, passing `null` for any argument to the
@@ -93,426 +92,6 @@
   CompilationResult(this.compiler, {this.isSuccess: true});
 }
 
-/// Object for passing options to the compiler.
-class CompilerOptions {
-  /// The entry point of the application that is being compiled.
-  final Uri entryPoint;
-
-  /// Root location where SDK libraries are found.
-  final Uri libraryRoot;
-
-  /// Package root location.
-  ///
-  /// If not null then [packageConfig] should be null.
-  final Uri packageRoot;
-
-  /// Location of the package configuration file.
-  ///
-  /// If not null then [packageRoot] should be null.
-  final Uri packageConfig;
-
-  // TODO(sigmund): Move out of here, maybe to CompilerInput. Options should not
-  // hold code, just configuration options.
-  final PackagesDiscoveryProvider packagesDiscoveryProvider;
-
-  /// Resolved constant "environment" values passed to the compiler via the `-D`
-  /// flags.
-  final Map<String, dynamic> environment;
-
-  /// Whether we allow mocking compilation of libraries such as dart:io and
-  /// dart:html for unit testing purposes.
-  final bool allowMockCompilation;
-
-  /// Whether the native extension syntax is supported by the frontend.
-  final bool allowNativeExtensions;
-
-  /// Whether to resolve all functions in the program, not just those reachable
-  /// from main. This implies [analyzeOnly] is true as well.
-  final bool analyzeAll;
-
-  /// Whether to disable tree-shaking for the main script. This marks all
-  /// functions in the main script as reachable (not just a function named
-  /// `main`).
-  // TODO(sigmund): rename. The current name seems to indicate that only the
-  // main function is retained, which is the opposite of what this does.
-  final bool analyzeMain;
-
-  /// Whether to run the compiler just for the purpose of analysis. That is, to
-  /// run resolution and type-checking alone, but otherwise do not generate any
-  /// code.
-  final bool analyzeOnly;
-
-  /// Whether to skip analysis of method bodies and field initializers. Implies
-  /// [analyzeOnly].
-  final bool analyzeSignaturesOnly;
-
-  /// ID associated with this sdk build.
-  final String buildId;
-
-  /// Whether there is a build-id available so we can use it on error messages
-  /// and in the emitted output of the compiler.
-  bool get hasBuildId => buildId != _UNDETERMINED_BUILD_ID;
-
-  /// Location where to generate a map containing details of how deferred
-  /// libraries are subdivided.
-  final Uri deferredMapUri;
-
-  /// Whether to disable inlining during the backend optimizations.
-  // TODO(sigmund): negate, so all flags are positive
-  final bool disableInlining;
-
-  /// Several options to configure diagnostic messages.
-  // TODO(sigmund): should we simply embed those options here?
-  final DiagnosticOptions diagnosticOptions;
-
-  /// Whether to disable global type inference.
-  final bool disableTypeInference;
-
-  /// Whether to emit a .json file with a summary of the information used by the
-  /// compiler during optimization. This includes resolution details,
-  /// dependencies between elements, results of type inference, and the output
-  /// code for each function.
-  final bool dumpInfo;
-
-  /// Whether we allow passing an extra argument to `assert`, containing a
-  /// reason for why an assertion fails. (experimental)
-  final bool enableAssertMessage;
-
-  /// Whether to enable the experimental conditional directives feature.
-  final bool enableConditionalDirectives;
-
-  /// Whether the user specified a flag to allow the use of dart:mirrors. This
-  /// silences a warning produced by the compiler.
-  final bool enableExperimentalMirrors;
-
-  /// Whether to enable minification
-  // TODO(sigmund): rename to minify
-  final bool enableMinification;
-
-  /// Whether to model which native classes are live based on annotations on the
-  /// core libraries. If false, all native classes will be included by default.
-  final bool enableNativeLiveTypeAnalysis;
-
-  /// Whether to generate code containing checked-mode assignability checks.
-  final bool enableTypeAssertions;
-
-  /// Whether to generate code containing user's `assert` statements.
-  final bool enableUserAssertions;
-
-  /// Whether to generate output even when there are compile-time errors.
-  final bool generateCodeWithCompileTimeErrors;
-
-  /// Whether to generate a source-map file together with the output program.
-  final bool generateSourceMap;
-
-  /// Whether some values are cached for reuse in incremental compilation.
-  /// Incremental compilation allows calling `Compiler.run` more than once
-  /// (experimental).
-  final bool hasIncrementalSupport;
-
-  /// URI of the main output if the compiler is generating source maps.
-  final Uri outputUri;
-
-  /// Location of the platform configuration file.
-  final Uri platformConfigUri;
-
-  /// Whether to emit URIs in the reflection metadata.
-  final bool preserveUris;
-
-  /// URI where the compiler should generate the output source map file.
-  final Uri sourceMapUri;
-
-  /// The compiler is run from the build bot.
-  final bool testMode;
-
-  /// Whether to trust JS-interop annotations. (experimental)
-  final bool trustJSInteropTypeAnnotations;
-
-  /// Whether to trust primitive types during inference and optimizations.
-  final bool trustPrimitives;
-
-  /// Whether to trust type annotations during inference and optimizations.
-  final bool trustTypeAnnotations;
-
-  /// Whether to generate code compliant with content security policy (CSP).
-  final bool useContentSecurityPolicy;
-
-  /// Use the experimental CPS based backend.
-  final bool useCpsIr;
-
-  /// When obfuscating for minification, whether to use the frequency of a name
-  /// as an heuristic to pick shorter names.
-  final bool useFrequencyNamer;
-
-  /// Whether to use the new source-information implementation for source-maps.
-  /// (experimental)
-  final bool useNewSourceInfo;
-
-  /// Whether the user requested to use the fast startup emitter. The full
-  /// emitter might still be used if the program uses dart:mirrors.
-  final bool useStartupEmitter;
-
-  /// Enable verbose printing during compilation. Includes progress messages
-  /// during each phase and a time-breakdown between phases at the end.
-  final bool verbose;
-
-
-  // -------------------------------------------------
-  // Options for deprecated features
-  // -------------------------------------------------
-  // TODO(sigmund): delete these as we delete the underlying features
-
-  /// Whether to preserve comments while scanning (only use for dart:mirrors).
-  final bool preserveComments;
-
-  /// Whether to emit JavaScript (false enables dart2dart).
-  final bool emitJavaScript;
-
-  /// When using dart2dart, whether to use the multi file format.
-  final bool dart2dartMultiFile;
-
-  /// Strip option used by dart2dart.
-  final List<String> strips;
-
-  /// Create an options object by parsing flags from [options].
-  factory CompilerOptions.parse(
-      {Uri entryPoint,
-      Uri libraryRoot,
-      Uri packageRoot,
-      Uri packageConfig,
-      PackagesDiscoveryProvider packagesDiscoveryProvider,
-      Map<String, dynamic> environment: const <String, dynamic>{},
-      List<String> options}) {
-    return new CompilerOptions(
-        entryPoint: entryPoint,
-        libraryRoot: libraryRoot,
-        packageRoot: packageRoot,
-        packageConfig: packageConfig,
-        packagesDiscoveryProvider: packagesDiscoveryProvider,
-        environment: environment,
-        allowMockCompilation: _hasOption(options, Flags.allowMockCompilation),
-        allowNativeExtensions: _hasOption(options, Flags.allowNativeExtensions),
-        analyzeAll: _hasOption(options, Flags.analyzeAll),
-        analyzeMain: _hasOption(options, Flags.analyzeMain),
-        analyzeOnly: _hasOption(options, Flags.analyzeOnly),
-        analyzeSignaturesOnly: _hasOption(options, Flags.analyzeSignaturesOnly),
-        buildId: _extractStringOption(
-            options, '--build-id=', _UNDETERMINED_BUILD_ID),
-        dart2dartMultiFile: _hasOption(options, '--output-type=dart-multi'),
-        deferredMapUri: _extractUriOption(options, '--deferred-map='),
-        diagnosticOptions: new DiagnosticOptions(
-            suppressWarnings: _hasOption(options, Flags.suppressWarnings),
-            fatalWarnings: _hasOption(options, Flags.fatalWarnings),
-            suppressHints: _hasOption(options, Flags.suppressHints),
-            terseDiagnostics: _hasOption(options, Flags.terse),
-            shownPackageWarnings:
-                _extractOptionalCsvOption(options, Flags.showPackageWarnings)),
-        disableInlining: _hasOption(options, Flags.disableInlining),
-        disableTypeInference: _hasOption(options, Flags.disableTypeInference),
-        dumpInfo: _hasOption(options, Flags.dumpInfo),
-        emitJavaScript: !(_hasOption(options, '--output-type=dart') ||
-            _hasOption(options, '--output-type=dart-multi')),
-        enableAssertMessage: _hasOption(options, Flags.enableAssertMessage),
-        enableConditionalDirectives:
-            _hasOption(options, Flags.conditionalDirectives),
-        enableExperimentalMirrors:
-            _hasOption(options, Flags.enableExperimentalMirrors),
-        enableMinification: _hasOption(options, Flags.minify),
-        enableNativeLiveTypeAnalysis:
-            !_hasOption(options, Flags.disableNativeLiveTypeAnalysis),
-        enableTypeAssertions: _hasOption(options, Flags.enableCheckedMode),
-        enableUserAssertions: _hasOption(options, Flags.enableCheckedMode),
-        generateCodeWithCompileTimeErrors:
-            _hasOption(options, Flags.generateCodeWithCompileTimeErrors),
-        generateSourceMap: !_hasOption(options, Flags.noSourceMaps),
-        hasIncrementalSupport: _forceIncrementalSupport ||
-            _hasOption(options, Flags.incrementalSupport),
-        outputUri: _extractUriOption(options, '--out='),
-        platformConfigUri: _resolvePlatformConfigFromOptions(
-            libraryRoot, options),
-        preserveComments: _hasOption(options, Flags.preserveComments),
-        preserveUris: _hasOption(options, Flags.preserveUris),
-        sourceMapUri: _extractUriOption(options, '--source-map='),
-        strips: _extractCsvOption(options, '--force-strip='),
-        testMode: _hasOption(options, Flags.testMode),
-        trustJSInteropTypeAnnotations:
-            _hasOption(options, Flags.trustJSInteropTypeAnnotations),
-        trustPrimitives: _hasOption(options, Flags.trustPrimitives),
-        trustTypeAnnotations: _hasOption(options, Flags.trustTypeAnnotations),
-        useContentSecurityPolicy:
-            _hasOption(options, Flags.useContentSecurityPolicy),
-        useCpsIr: _hasOption(options, Flags.useCpsIr),
-        useFrequencyNamer:
-            !_hasOption(options, Flags.noFrequencyBasedMinification),
-        useNewSourceInfo: _hasOption(options, Flags.useNewSourceInfo),
-        useStartupEmitter: _hasOption(options, Flags.fastStartup),
-        verbose: _hasOption(options, Flags.verbose));
-  }
-
-  /// Creates an option object for the compiler.
-  ///
-  /// This validates and normalizes dependent options to be consistent. For
-  /// example, if [analyzeAll] is true, the resulting options object will also
-  /// have [analyzeOnly] as true.
-  factory CompilerOptions(
-      {Uri entryPoint,
-      Uri libraryRoot,
-      Uri packageRoot,
-      Uri packageConfig,
-      PackagesDiscoveryProvider packagesDiscoveryProvider,
-      Map<String, dynamic> environment: const <String, dynamic>{},
-      bool allowMockCompilation: false,
-      bool allowNativeExtensions: false,
-      bool analyzeAll: false,
-      bool analyzeMain: false,
-      bool analyzeOnly: false,
-      bool analyzeSignaturesOnly: false,
-      String buildId: _UNDETERMINED_BUILD_ID,
-      bool dart2dartMultiFile: false,
-      Uri deferredMapUri: null,
-      DiagnosticOptions diagnosticOptions: const DiagnosticOptions(),
-      bool disableInlining: false,
-      bool disableTypeInference: false,
-      bool dumpInfo: false,
-      bool emitJavaScript: true,
-      bool enableAssertMessage: false,
-      bool enableConditionalDirectives: false,
-      bool enableExperimentalMirrors: false,
-      bool enableMinification: false,
-      bool enableNativeLiveTypeAnalysis: true,
-      bool enableTypeAssertions: false,
-      bool enableUserAssertions: false,
-      bool generateCodeWithCompileTimeErrors: false,
-      bool generateSourceMap: true,
-      bool hasIncrementalSupport: false,
-      Uri outputUri: null,
-      Uri platformConfigUri: null,
-      bool preserveComments: false,
-      bool preserveUris: false,
-      Uri sourceMapUri: null,
-      List<String> strips: const [],
-      bool testMode: false,
-      bool trustJSInteropTypeAnnotations: false,
-      bool trustPrimitives: false,
-      bool trustTypeAnnotations: false,
-      bool useContentSecurityPolicy: false,
-      bool useCpsIr: false,
-      bool useFrequencyNamer: true,
-      bool useNewSourceInfo: false,
-      bool useStartupEmitter: false,
-      bool verbose: false}) {
-    // TODO(sigmund): should entrypoint be here? should we validate it is not
-    // null? In unittests we use the same compiler to analyze or build multiple
-    // entrypoints.
-    if (libraryRoot == null) {
-      throw new ArgumentError("[libraryRoot] is null.");
-    }
-    if (!libraryRoot.path.endsWith("/")) {
-      throw new ArgumentError("[libraryRoot] must end with a /");
-    }
-    if (packageRoot != null && packageConfig != null) {
-      throw new ArgumentError("Only one of [packageRoot] or [packageConfig] "
-          "may be given.");
-    }
-    if (packageRoot != null && !packageRoot.path.endsWith("/")) {
-      throw new ArgumentError("[packageRoot] must end with a /");
-    }
-    if (!analyzeOnly) {
-      if (allowNativeExtensions) {
-        throw new ArgumentError(
-            "${Flags.allowNativeExtensions} is only supported in combination "
-            "with ${Flags.analyzeOnly}");
-      }
-    }
-    return new CompilerOptions._(entryPoint, libraryRoot, packageRoot,
-        packageConfig, packagesDiscoveryProvider, environment,
-        allowMockCompilation: allowMockCompilation,
-        allowNativeExtensions: allowNativeExtensions,
-        analyzeAll: analyzeAll,
-        analyzeMain: analyzeMain,
-        analyzeOnly: analyzeOnly || analyzeSignaturesOnly || analyzeAll,
-        analyzeSignaturesOnly: analyzeSignaturesOnly,
-        buildId: buildId,
-        dart2dartMultiFile: dart2dartMultiFile,
-        deferredMapUri: deferredMapUri,
-        diagnosticOptions: diagnosticOptions,
-        disableInlining: disableInlining || hasIncrementalSupport,
-        disableTypeInference: disableTypeInference || !emitJavaScript,
-        dumpInfo: dumpInfo,
-        emitJavaScript: emitJavaScript,
-        enableAssertMessage: enableAssertMessage,
-        enableConditionalDirectives: enableConditionalDirectives,
-        enableExperimentalMirrors: enableExperimentalMirrors,
-        enableMinification: enableMinification,
-        enableNativeLiveTypeAnalysis: enableNativeLiveTypeAnalysis,
-        enableTypeAssertions: enableTypeAssertions,
-        enableUserAssertions: enableUserAssertions,
-        generateCodeWithCompileTimeErrors: generateCodeWithCompileTimeErrors,
-        generateSourceMap: generateSourceMap,
-        hasIncrementalSupport: hasIncrementalSupport,
-        outputUri: outputUri,
-        platformConfigUri: platformConfigUri ?? _resolvePlatformConfig(
-           libraryRoot, null, !emitJavaScript, const []),
-        preserveComments: preserveComments,
-        preserveUris: preserveUris,
-        sourceMapUri: sourceMapUri,
-        strips: strips,
-        testMode: testMode,
-        trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations,
-        trustPrimitives: trustPrimitives,
-        trustTypeAnnotations: trustTypeAnnotations,
-        useContentSecurityPolicy: useContentSecurityPolicy,
-        useCpsIr: useCpsIr,
-        useFrequencyNamer: useFrequencyNamer,
-        useNewSourceInfo: useNewSourceInfo,
-        useStartupEmitter: useStartupEmitter,
-        verbose: verbose);
-  }
-
-  CompilerOptions._(this.entryPoint, this.libraryRoot, this.packageRoot,
-      this.packageConfig, this.packagesDiscoveryProvider, this.environment,
-      {this.allowMockCompilation: false,
-      this.allowNativeExtensions: false,
-      this.analyzeAll: false,
-      this.analyzeMain: false,
-      this.analyzeOnly: false,
-      this.analyzeSignaturesOnly: false,
-      this.buildId: _UNDETERMINED_BUILD_ID,
-      this.dart2dartMultiFile: false,
-      this.deferredMapUri: null,
-      this.diagnosticOptions: null,
-      this.disableInlining: false,
-      this.disableTypeInference: false,
-      this.dumpInfo: false,
-      this.emitJavaScript: true,
-      this.enableAssertMessage: false,
-      this.enableConditionalDirectives: false,
-      this.enableExperimentalMirrors: false,
-      this.enableMinification: false,
-      this.enableNativeLiveTypeAnalysis: false,
-      this.enableTypeAssertions: false,
-      this.enableUserAssertions: false,
-      this.generateCodeWithCompileTimeErrors: false,
-      this.generateSourceMap: true,
-      this.hasIncrementalSupport: false,
-      this.outputUri: null,
-      this.platformConfigUri: null,
-      this.preserveComments: false,
-      this.preserveUris: false,
-      this.sourceMapUri: null,
-      this.strips: const [],
-      this.testMode: false,
-      this.trustJSInteropTypeAnnotations: false,
-      this.trustPrimitives: false,
-      this.trustTypeAnnotations: false,
-      this.useContentSecurityPolicy: false,
-      this.useCpsIr: false,
-      this.useFrequencyNamer: false,
-      this.useNewSourceInfo: false,
-      this.useStartupEmitter: false,
-      this.verbose: false});
-}
-
 /// Returns a future that completes to a [CompilationResult] when the Dart
 /// sources in [options] have been compiled.
 ///
@@ -547,86 +126,3 @@
   });
 }
 
-String _extractStringOption(
-    List<String> options, String prefix, String defaultValue) {
-  for (String option in options) {
-    if (option.startsWith(prefix)) {
-      return option.substring(prefix.length);
-    }
-  }
-  return defaultValue;
-}
-
-Uri _extractUriOption(List<String> options, String prefix) {
-  var option = _extractStringOption(options, prefix, null);
-  return (option == null) ? null : Uri.parse(option);
-}
-
-// CSV: Comma separated values.
-List<String> _extractCsvOption(List<String> options, String prefix) {
-  for (String option in options) {
-    if (option.startsWith(prefix)) {
-      return option.substring(prefix.length).split(',');
-    }
-  }
-  return const <String>[];
-}
-
-/// Extract list of comma separated values provided for [flag]. Returns an
-/// empty list if [option] contain [flag] without arguments. Returns `null` if
-/// [option] doesn't contain [flag] with or without arguments.
-List<String> _extractOptionalCsvOption(List<String> options, String flag) {
-  String prefix = '$flag=';
-  for (String option in options) {
-    if (option == flag) {
-      return const <String>[];
-    }
-    if (option.startsWith(flag)) {
-      return option.substring(prefix.length).split(',');
-    }
-  }
-  return null;
-}
-
-Uri _resolvePlatformConfigFromOptions(Uri libraryRoot, List<String> options) {
-  return _resolvePlatformConfig(libraryRoot,
-      _extractStringOption(options, "--platform-config=", null),
-      _hasOption(options, '--output-type=dart'),
-      _extractCsvOption(options, '--categories='));
-}
-
-Uri _resolvePlatformConfig(Uri libraryRoot,
-    String platformConfigPath, bool isDart2Dart, Iterable<String> categories) {
-  if (platformConfigPath != null) {
-    return libraryRoot.resolve(platformConfigPath);
-  } else if (isDart2Dart) {
-    return libraryRoot.resolve(_dart2dartPlatform);
-  } else {
-    if (categories.length == 0) {
-      return libraryRoot.resolve(_clientPlatform);
-    }
-    assert(categories.length <= 2);
-    if (categories.contains("Client")) {
-      if (categories.contains("Server")) {
-        return libraryRoot.resolve(_sharedPlatform);
-      }
-      return libraryRoot.resolve(_clientPlatform);
-    }
-    assert(categories.contains("Server"));
-    return libraryRoot.resolve(_serverPlatform);
-  }
-}
-
-bool _hasOption(List<String> options, String option) {
-  return options.indexOf(option) >= 0;
-}
-
-/// Locations of the platform descriptor files relative to the library root.
-const String _clientPlatform = "lib/dart_client.platform";
-const String _serverPlatform = "lib/dart_server.platform";
-const String _sharedPlatform = "lib/dart_shared.platform";
-const String _dart2dartPlatform = "lib/dart2dart.platform";
-
-const String _UNDETERMINED_BUILD_ID = "build number could not be determined";
-const bool _forceIncrementalSupport =
-    const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT');
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 9e28d01..9e04e16 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -16,18 +16,17 @@
     checkValidPackageUri;
 
 import '../compiler_new.dart' as api;
-import 'commandline_options.dart';
 import 'common.dart';
 import 'common/tasks.dart' show
     GenericTask;
 import 'compiler.dart';
-import 'diagnostics/diagnostic_listener.dart' show
-    DiagnosticOptions;
 import 'diagnostics/messages.dart' show
     Message;
 import 'elements/elements.dart' as elements;
 import 'environment.dart';
 import 'io/source_file.dart';
+import 'options.dart' show
+    CompilerOptions;
 import 'platform_configuration.dart' as platform_configuration;
 import 'script.dart';
 
@@ -52,7 +51,7 @@
   Uri get libraryRoot => options.platformConfigUri.resolve(".");
 
   CompilerImpl(this.provider, api.CompilerOutput outputProvider,
-      this.handler, api.CompilerOptions options)
+      this.handler, CompilerOptions options)
       : super(options: options, outputProvider: outputProvider,
           environment: new _Environment(options.environment)) {
     _Environment env = environment;
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index bb51679..1315016 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -309,6 +309,7 @@
 /// A local variable used encode the direct (uncaptured) references to [this].
 class ThisLocal extends Local {
   final ExecutableElement executableContext;
+  final hashCode = ++ElementX.elementHashCode;
 
   ThisLocal(this.executableContext);
 
@@ -352,6 +353,10 @@
   }
 
   Element get analyzableElement => closureClass.methodElement.analyzableElement;
+
+  accept(ElementVisitor visitor, arg) {
+    return visitor.visitMethodElement(this, arg);
+  }
 }
 
 // The box-element for a scope, and the captured variables that need to be
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index ce82723..7c675af 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -29,6 +29,8 @@
     TypeVariableElement;
 import '../enqueue.dart' show
     ResolutionEnqueuer;
+import '../options.dart' show
+    ParserOptions;
 import '../parser/element_listener.dart' show
     ScannerOptions;
 import '../tree/tree.dart' show
@@ -145,6 +147,10 @@
         isConstant == other.isConstant &&
         isEmpty == other.isEmpty;
   }
+
+  String toString() {
+    return 'MapLiteralUse($type,isConstant:$isConstant,isEmpty:$isEmpty)';
+  }
 }
 
 /// A use of a list literal seen during resolution.
@@ -170,6 +176,10 @@
         isConstant == other.isConstant &&
         isEmpty == other.isEmpty;
   }
+
+  String toString() {
+    return 'ListLiteralUse($type,isConstant:$isConstant,isEmpty:$isEmpty)';
+  }
 }
 
 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`.
@@ -178,6 +188,10 @@
   DiagnosticReporter get reporter;
   CoreTypes get coreTypes;
 
+  /// If set to `true` resolution caches will not be cleared. Use this only for
+  /// testing.
+  bool retainCachesForTesting;
+
   void resolveTypedef(TypedefElement typdef);
   void resolveClass(ClassElement cls);
   void registerClass(ClassElement cls);
@@ -190,6 +204,12 @@
   ResolutionWorkItem createWorkItem(
       Element element, ItemCompilationContext compilationContext);
 
+  /// Returns `true` if the [ResolutionImpact] for [element] is cached.
+  bool hasResolutionImpact(Element element);
+
+  /// Returns the precomputed [ResolutionImpact] for [element].
+  ResolutionImpact getResolutionImpact(Element element);
+
   /// Returns the precomputed [WorldImpact] for [element].
   WorldImpact getWorldImpact(Element element);
 
@@ -212,4 +232,5 @@
   void parsePatchClass(ClassElement cls);
   measure(f());
   ScannerOptions getScannerOptionsFor(Element element);
+  ParserOptions get parserOptions;
 }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index b49fdd0..2cfadd3 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -50,7 +50,7 @@
 import 'deferred_load.dart' show DeferredLoadTask, OutputUnit;
 import 'diagnostics/code_location.dart';
 import 'diagnostics/diagnostic_listener.dart' show
-    DiagnosticOptions;
+    DiagnosticReporter;
 import 'diagnostics/invariant.dart' show
     REPORT_EXCESS_RESOLUTION;
 import 'diagnostics/messages.dart' show
@@ -95,6 +95,10 @@
 import 'null_compiler_output.dart' show
     NullCompilerOutput,
     NullSink;
+import 'options.dart' show
+    CompilerOptions,
+    DiagnosticOptions,
+    ParserOptions;
 import 'parser/diet_parser_task.dart' show
     DietParserTask;
 import 'parser/element_listener.dart' show
@@ -191,7 +195,7 @@
       new ResolutionRegistry(null, new TreeElementMapping(null));
 
   /// Options provided from command-line arguments.
-  final api.CompilerOptions options;
+  final CompilerOptions options;
 
   /**
    * If true, stop compilation after type inference is complete. Used for
@@ -356,19 +360,17 @@
     compilationFailedInternal = value;
   }
 
-  Compiler({api.CompilerOptions options,
+  Compiler({CompilerOptions options,
             api.CompilerOutput outputProvider,
             this.environment: const _EmptyEnvironment()})
       : this.options = options,
         this.cacheStrategy = new CacheStrategy(options.hasIncrementalSupport),
         this.userOutputProvider = outputProvider == null
             ? const NullCompilerOutput() : outputProvider {
-
     world = new World(this);
     // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and
     // make its field final.
-    _reporter = new _CompilerDiagnosticReporter(
-        this, options.diagnosticOptions);
+    _reporter = new _CompilerDiagnosticReporter(this, options);
     _parsing = new _CompilerParsing(this);
     _resolution = new _CompilerResolution(this);
     _coreTypes = new _CompilerCoreTypes(_resolution);
@@ -399,8 +401,7 @@
     }
 
     tasks = [
-      dietParser = new DietParserTask(
-          this, enableConditionalDirectives: options.enableConditionalDirectives),
+      dietParser = new DietParserTask(this, parsing.parserOptions),
       scanner = createScannerTask(),
       serialization = new SerializationTask(this),
       libraryLoader = new LibraryLoaderTask(this,
@@ -410,10 +411,8 @@
           this.serialization,
           this,
           environment),
-      parser = new ParserTask(this,
-          enableConditionalDirectives: options.enableConditionalDirectives),
-      patchParser = new PatchParserTask(
-          this, enableConditionalDirectives: options.enableConditionalDirectives),
+      parser = new ParserTask(this, parsing.parserOptions),
+      patchParser = new PatchParserTask(this, parsing.parserOptions),
       resolver = createResolverTask(),
       closureToClassMapper = new closureMapping.ClosureTask(this),
       checker = new TypeCheckerTask(this),
@@ -1957,7 +1956,10 @@
 // TODO(johnniwinther): Move [ResolverTask] here.
 class _CompilerResolution implements Resolution {
   final Compiler compiler;
+  final Map<Element, ResolutionImpact> _resolutionImpactCache =
+      <Element, ResolutionImpact>{};
   final Map<Element, WorldImpact> _worldImpactCache = <Element, WorldImpact>{};
+  bool retainCachesForTesting = false;
 
   _CompilerResolution(this.compiler);
 
@@ -2001,6 +2003,19 @@
   }
 
   @override
+  bool hasResolutionImpact(Element element) {
+    return _resolutionImpactCache.containsKey(element);
+  }
+
+  @override
+  ResolutionImpact getResolutionImpact(Element element) {
+    ResolutionImpact resolutionImpact = _resolutionImpactCache[element];
+    assert(invariant(element, resolutionImpact != null,
+        message: "ResolutionImpact not available for $element."));
+    return resolutionImpact;
+  }
+
+  @override
   WorldImpact getWorldImpact(Element element) {
     WorldImpact worldImpact = _worldImpactCache[element];
     assert(invariant(element, worldImpact != null,
@@ -2016,6 +2031,14 @@
       assert(invariant(element, !element.isSynthesized || tree == null));
       ResolutionImpact resolutionImpact =
           compiler.resolver.resolve(element);
+      if (compiler.serialization.supportSerialization || retainCachesForTesting) {
+        // [ResolutionImpact] is currently only used by serialization. The
+        // enqueuer uses the [WorldImpact] which is always cached.
+        // TODO(johnniwinther): Align these use cases better; maybe only
+        // cache [ResolutionImpact] and let the enqueuer transform it into
+        // a [WorldImpact].
+        _resolutionImpactCache[element] = resolutionImpact;
+      }
       if (tree != null && !compiler.options.analyzeSignaturesOnly) {
         // TODO(het): don't do this if suppressWarnings is on, currently we have
         // to do it because the typechecker also sets types
@@ -2031,17 +2054,21 @@
 
   @override
   void uncacheWorldImpact(Element element) {
+    if (retainCachesForTesting) return;
     if (compiler.serialization.isDeserialized(element)) return;
     assert(invariant(element, _worldImpactCache[element] != null,
         message: "WorldImpact not computed for $element."));
     _worldImpactCache[element] = const WorldImpact();
+    _resolutionImpactCache.remove(element);
   }
 
   @override
   void emptyCache() {
+    if (retainCachesForTesting) return;
     for (Element element in _worldImpactCache.keys) {
       _worldImpactCache[element] = const WorldImpact();
     }
+    _resolutionImpactCache.clear();
   }
 
   @override
@@ -2083,10 +2110,10 @@
     });
   }
 
-  ScannerOptions getScannerOptionsFor(Element element) {
-    return new ScannerOptions(
-      canUseNative: compiler.backend.canLibraryUseNative(element.library));
-  }
+  ScannerOptions getScannerOptionsFor(Element element) =>
+      new ScannerOptions.from(compiler, element.library);
+
+  ParserOptions get parserOptions => compiler.options;
 }
 
 class GlobalDependencyRegistry extends EagerRegistry {
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index e44b840..1afb9d3 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -135,7 +135,8 @@
          BaseImplementationOfNewMixin<ir.Primitive, dynamic>,
          BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>,
          BaseImplementationOfSetIfNullsMixin<ir.Primitive, dynamic>,
-         BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic>
+         BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic>,
+         BaseImplementationOfSuperIndexSetIfNullMixin<ir.Primitive, dynamic>
     implements SemanticSendVisitor<ir.Primitive, dynamic> {
   final TreeElements elements;
   final Compiler compiler;
@@ -2717,6 +2718,22 @@
         sourceInformationBuilder.buildIndexSet(node));
   }
 
+  ir.Primitive translateIfNull(
+       ast.SendSet node,
+       ir.Primitive getValue(),
+       ast.Node rhs,
+       void setValue(ir.Primitive value)) {
+    ir.Primitive value = getValue();
+    // Unlike other compound operators if-null conditionally will not do the
+    // assignment operation.
+    return irBuilder.buildIfNull(value, nested(() {
+      ir.Primitive newValue = build(rhs);
+      setValue(newValue);
+      return newValue;
+    }),
+    sourceInformationBuilder.buildIf(node));
+  }
+
   ir.Primitive translateCompounds(
       ast.SendSet node,
       ir.Primitive getValue(),
@@ -2724,16 +2741,7 @@
       void setValue(ir.Primitive value)) {
     ir.Primitive value = getValue();
     op.BinaryOperator operator = rhs.operator;
-    if (operator.kind == op.BinaryOperatorKind.IF_NULL) {
-      // Unlike other compound operators if-null conditionally will not do the
-      // assignment operation.
-      return irBuilder.buildIfNull(value, nested(() {
-        ir.Primitive newValue = build(rhs.rhs);
-        setValue(newValue);
-        return newValue;
-      }),
-      sourceInformationBuilder.buildIf(node));
-    }
+    assert(operator.kind != op.BinaryOperatorKind.IF_NULL);
 
     Selector operatorSelector =
         new Selector.binaryOperator(operator.selectorName);
@@ -2778,6 +2786,68 @@
   }
 
   @override
+  ir.Primitive handleSuperIndexSetIfNull(
+      ast.SendSet node,
+      Element indexFunction,
+      Element indexSetFunction,
+      ast.Node index,
+      ast.Node rhs,
+      arg,
+      {bool isGetterValid,
+       bool isSetterValid}) {
+    return translateSetIfNull(node, () {
+      if (isGetterValid) {
+        return irBuilder.buildSuperMethodGet(
+            indexFunction, sourceInformationBuilder.buildIndex(node));
+      } else {
+        return buildSuperNoSuchGetter(
+            indexFunction,
+            elements.getGetterTypeMaskInComplexSendSet(node),
+            sourceInformationBuilder.buildIndex(node));
+      }
+    }, rhs, (ir.Primitive result) {
+      if (isSetterValid) {
+        return irBuilder.buildSuperMethodGet(
+            indexSetFunction, sourceInformationBuilder.buildIndexSet(node));
+      } else {
+        return buildSuperNoSuchSetter(
+            indexSetFunction, elements.getTypeMask(node), result,
+            sourceInformationBuilder.buildIndexSet(node));
+      }
+    });
+  }
+
+  @override
+  ir.Primitive visitIndexSetIfNull(
+      ast.SendSet node,
+      ast.Node receiver,
+      ast.Node index,
+      ast.Node rhs,
+      arg) {
+    ir.Primitive target = visit(receiver);
+    ir.Primitive indexValue = visit(index);
+    return translateSetIfNull(node, () {
+      Selector selector = new Selector.index();
+      List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
+      CallStructure callStructure =
+          normalizeDynamicArguments(selector.callStructure, arguments);
+      return irBuilder.buildDynamicInvocation(
+          target,
+          new Selector(selector.kind, selector.memberName, callStructure),
+          elements.getGetterTypeMaskInComplexSendSet(node),
+          arguments,
+          sourceInformationBuilder.buildCall(receiver, node));
+    }, rhs, (ir.Primitive result) {
+      irBuilder.buildDynamicIndexSet(
+          target,
+          elements.getTypeMask(node),
+          indexValue,
+          result,
+          sourceInformationBuilder.buildIndexSet(node));
+    });
+  }
+
+  @override
   ir.Primitive handleDynamicSet(
       ast.SendSet node,
       ast.Node receiver,
diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart
index 8df9c18..5262138 100644
--- a/pkg/compiler/lib/src/dart_types.dart
+++ b/pkg/compiler/lib/src/dart_types.dart
@@ -445,6 +445,8 @@
 }
 
 class InterfaceType extends GenericType {
+  int _hashCode;
+
   InterfaceType(ClassElement element,
                 [List<DartType> typeArguments = const <DartType>[]])
       : super(element, typeArguments) {
@@ -503,7 +505,7 @@
     return member;
   }
 
-  int get hashCode => super.hashCode;
+  int get hashCode => _hashCode ??= super.hashCode;
 
   InterfaceType asRaw() => super.asRaw();
 
@@ -825,6 +827,8 @@
     return visitor.visitDynamicType(this, argument);
   }
 
+  int get hashCode => 91;
+
   String toString() => name;
 }
 
diff --git a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
index 8d5baac..bd57506 100644
--- a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
+++ b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
@@ -4,6 +4,8 @@
 
 library dart2js.diagnostic_listener;
 
+import '../options.dart' show
+    DiagnosticOptions;
 import 'source_span.dart' show
     SourceSpan;
 import 'spannable.dart' show
@@ -12,57 +14,9 @@
     Element;
 import 'messages.dart';
 
-class DiagnosticOptions {
-  /// Emit terse diagnostics without howToFix.
-  final bool terseDiagnostics;
-
-  /// List of packages for which warnings and hints are reported. If `null`,
-  /// no package warnings or hints are reported. If empty, all warnings and
-  /// hints are reported.
-  final List<String> _shownPackageWarnings;
-
-  /// If `true`, warnings are not reported.
-  final bool suppressWarnings;
-
-  /// If `true`, warnings cause the compilation to fail.
-  final bool fatalWarnings;
-
-  /// If `true`, hints are not reported.
-  final bool suppressHints;
-
-  const DiagnosticOptions({
-    this.suppressWarnings: false,
-    this.fatalWarnings: false,
-    this.suppressHints: false,
-    this.terseDiagnostics: false,
-    List<String> shownPackageWarnings: null})
-      : _shownPackageWarnings = shownPackageWarnings;
-
-
-  /// Returns `true` if warnings and hints are shown for all packages.
-  bool get showAllPackageWarnings {
-    return _shownPackageWarnings != null && _shownPackageWarnings.isEmpty;
-  }
-
-  /// Returns `true` if warnings and hints are hidden for all packages.
-  bool get hidePackageWarnings => _shownPackageWarnings == null;
-
-  /// Returns `true` if warnings should be should for [uri].
-  bool showPackageWarningsFor(Uri uri) {
-    if (showAllPackageWarnings) {
-      return true;
-    }
-    if (_shownPackageWarnings != null) {
-      return uri.scheme == 'package' &&
-          _shownPackageWarnings.contains(uri.pathSegments.first);
-    }
-    return false;
-  }
-}
-
 // TODO(johnniwinther): Rename and cleanup this interface. Add severity enum.
 abstract class DiagnosticReporter {
-  DiagnosticOptions get options => const DiagnosticOptions();
+  DiagnosticOptions get options;
 
   // TODO(karlklose): rename log to something like reportInfo.
   void log(message);
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
index 6c2e843..85fd159 100644
--- a/pkg/compiler/lib/src/elements/common.dart
+++ b/pkg/compiler/lib/src/elements/common.dart
@@ -9,6 +9,8 @@
 import '../common/names.dart' show
     Names,
     Uris;
+import '../core_types.dart' show
+    CoreClasses;
 import '../dart_types.dart' show
     DartType,
     InterfaceType,
@@ -430,6 +432,12 @@
   }
 
   @override
+  bool implementsFunction(CoreClasses coreClasses) {
+    return asInstanceOf(coreClasses.functionClass) != null ||
+        callType != null;
+  }
+
+  @override
   bool isSubclassOf(ClassElement cls) {
     // Use [declaration] for both [this] and [cls], because
     // declaration classes hold the superclass hierarchy.
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 214b25d..bed7cea 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -13,8 +13,6 @@
 import '../constants/constant_constructors.dart';
 import '../constants/constructors.dart';
 import '../constants/expressions.dart';
-import '../core_types.dart' show
-    CoreClasses;
 import '../dart_types.dart';
 import '../diagnostics/messages.dart' show
     MessageTemplate;
@@ -2078,10 +2076,6 @@
 
   bool get isAbstract => false;
 
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitFunctionElement(this, arg);
-  }
-
   // A function is defined by the implementation element.
   AstElement get definingElement => implementation;
 }
@@ -2132,6 +2126,10 @@
   bool get isAbstract {
     return !modifiers.isExternal && !hasBody;
   }
+
+  accept(ElementVisitor visitor, arg) {
+    return visitor.visitMethodElement(this, arg);
+  }
 }
 
 abstract class AccessorElementX extends MethodElementX
@@ -2154,6 +2152,10 @@
                  Element enclosing,
                  bool hasBody)
       : super(name, ElementKind.GETTER, modifiers, enclosing, hasBody);
+
+  accept(ElementVisitor visitor, arg) {
+    return visitor.visitGetterElement(this, arg);
+  }
 }
 
 abstract class SetterElementX extends AccessorElementX
@@ -2164,6 +2166,10 @@
                  Element enclosing,
                  bool hasBody)
       : super(name, ElementKind.SETTER, modifiers, enclosing, hasBody);
+
+  accept(ElementVisitor visitor, arg) {
+    return visitor.visitSetterElement(this, arg);
+  }
 }
 
 class LocalFunctionElementX extends BaseFunctionElementX
@@ -2195,6 +2201,10 @@
   }
 
   bool get isLocal => true;
+
+  accept(ElementVisitor visitor, arg) {
+    return visitor.visitLocalFunctionElement(this, arg);
+  }
 }
 
 abstract class ConstantConstructorMixin implements ConstructorElement {
@@ -2689,11 +2699,6 @@
     backendMembers.forEach(f);
   }
 
-  bool implementsFunction(CoreClasses coreClasses) {
-    return asInstanceOf(coreClasses.functionClass) != null ||
-        callType != null;
-  }
-
   // TODO(johnniwinther): Remove these when issue 18630 is fixed.
   ClassElement get patch => super.patch;
   ClassElement get origin => super.origin;
diff --git a/pkg/compiler/lib/src/elements/visitor.dart b/pkg/compiler/lib/src/elements/visitor.dart
index 23d5263..b571e56 100644
--- a/pkg/compiler/lib/src/elements/visitor.dart
+++ b/pkg/compiler/lib/src/elements/visitor.dart
@@ -30,7 +30,10 @@
   R visitFieldElement(FieldElement e, A arg) => null;
   R visitFieldParameterElement(InitializingFormalElement e, A arg) => null;
   R visitAbstractFieldElement(AbstractFieldElement e, A arg) => null;
-  R visitFunctionElement(FunctionElement e, A arg) => null;
+  R visitMethodElement(FunctionElement e, A arg) => null;
+  R visitGetterElement(GetterElement e, A arg) => null;
+  R visitSetterElement(SetterElement e, A arg) => null;
+  R visitLocalFunctionElement(LocalFunctionElement e, A arg) => null;
   R visitConstructorElement(ConstructorElement e, A arg) => null;
   R visitConstructorBodyElement(ConstructorBodyElement e, A arg) => null;
   R visitClassElement(ClassElement e, A arg) => null;
@@ -127,12 +130,31 @@
     return visitElement(e, arg);
   }
 
-  @override
   R visitFunctionElement(FunctionElement e, A arg) {
     return visitElement(e, arg);
   }
 
   @override
+  R visitMethodElement(MethodElement e, A arg) {
+    return visitFunctionElement(e, arg);
+  }
+
+  @override
+  R visitGetterElement(GetterElement e, A arg) {
+    return visitFunctionElement(e, arg);
+  }
+
+  @override
+  R visitSetterElement(SetterElement e, A arg) {
+    return visitFunctionElement(e, arg);
+  }
+
+  @override
+  R visitLocalFunctionElement(LocalFunctionElement e, A arg) {
+    return visitFunctionElement(e, arg);
+  }
+
+  @override
   R visitConstructorElement(ConstructorElement e, A arg) {
     return visitFunctionElement(e, arg);
   }
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index 9628684..468aa72 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -949,6 +949,19 @@
   }
 
   @override
+  T visitIndexSetIfNull(
+      ast.SendSet node,
+      ast.Node receiver,
+      ast.Node index,
+      ast.Node rhs,
+      _) {
+    T receiverType = visit(receiver);
+    T indexType = visit(index);
+    T rhsType = visit(rhs);
+    return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
+  }
+
+  @override
   T visitSuperIndexPrefix(
       ast.Send node,
       MethodElement getter,
@@ -996,6 +1009,17 @@
   }
 
   @override
+  T visitSuperIndexSetIfNull(
+      ast.SendSet node,
+      MethodElement getter,
+      MethodElement setter,
+      ast.Node index,
+      ast.Node rhs,
+      _) {
+    return handleSuperCompoundIndexSet(node, index, rhs);
+  }
+
+  @override
   T visitUnresolvedSuperCompoundIndexSet(
       ast.Send node,
       Element element,
@@ -1007,6 +1031,16 @@
   }
 
   @override
+  T visitUnresolvedSuperIndexSetIfNull(
+      ast.Send node,
+      Element element,
+      ast.Node index,
+      ast.Node rhs,
+      _) {
+    return handleSuperCompoundIndexSet(node, index, rhs);
+  }
+
+  @override
   T visitUnresolvedSuperGetterCompoundIndexSet(
       ast.SendSet node,
       Element element,
@@ -1019,6 +1053,17 @@
   }
 
   @override
+  T visitUnresolvedSuperGetterIndexSetIfNull(
+      ast.SendSet node,
+      Element element,
+      MethodElement setter,
+      ast.Node index,
+      ast.Node rhs,
+      _) {
+    return handleSuperCompoundIndexSet(node, index, rhs);
+  }
+
+  @override
   T visitUnresolvedSuperSetterCompoundIndexSet(
       ast.SendSet node,
       MethodElement getter,
@@ -1031,6 +1076,17 @@
   }
 
   @override
+  T visitUnresolvedSuperSetterIndexSetIfNull(
+      ast.SendSet node,
+      MethodElement getter,
+      Element element,
+      ast.Node index,
+      ast.Node rhs,
+      _) {
+    return handleSuperCompoundIndexSet(node, index, rhs);
+  }
+
+  @override
   T visitUnresolvedSuperIndexPrefix(
       ast.Send node,
       Element element,
diff --git a/pkg/compiler/lib/src/info/send_info.dart b/pkg/compiler/lib/src/info/send_info.dart
index 0c31114..0985360 100644
--- a/pkg/compiler/lib/src/info/send_info.dart
+++ b/pkg/compiler/lib/src/info/send_info.dart
@@ -2225,6 +2225,47 @@
     handleNSMError(node);
   }
 
+  @override
+  errorInvalidIndexSetIfNull(SendSet node, ErroneousElement error, Node index,
+      Node rhs, T arg) {
+    handleNoSend(node);
+  }
+
+  @override
+  visitIndexSetIfNull(SendSet node, Node receiver, Node index, Node rhs,
+      T arg) {
+    handleIndex(node); // t1 = receiver[index]
+    handleIndex(node); // receiver[index] = t2
+  }
+
+  @override
+  visitSuperIndexSetIfNull(SendSet node, MethodElement getter,
+      MethodElement setter, Node index, Node rhs, T arg) {
+    handleSuper(node); // t1 = super[index]
+    handleSuper(node); // super[index] = t2
+  }
+
+  @override
+  visitUnresolvedSuperGetterIndexSetIfNull(Send node, Element element,
+      MethodElement setter, Node index, Node rhs, T arg) {
+    handleNSMSuper(node, element.enclosingClass);
+    handleNSMSuper(node, element.enclosingClass);
+  }
+
+  @override
+  visitUnresolvedSuperIndexSetIfNull(Send node, Element element, Node index,
+      Node rhs, T arg) {
+    handleNSMSuper(node, element.enclosingClass);
+    handleNSMSuper(node, element.enclosingClass);
+  }
+
+  @override
+  visitUnresolvedSuperSetterIndexSetIfNull(Send node, MethodElement getter,
+      Element element, Node index, Node rhs, T arg) {
+    handleSuper(node); // t1 = super[index]
+    handleNSMSuper(node, element.enclosingClass);
+  }
+
   void visitIfNull(Send node, Node left, Node right, T arg) {
     handleNoSend(node);
   }
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index bbac37f..970cc1c 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -25,7 +25,8 @@
 /// parameters to sync* functions that are mutated in the body must be boxed.
 /// (Currently handled in closure.dart).
 ///
-/// Look at [visitFun], [visitDartYield] and [visitAwait] for more explanation.
+/// Look at [rewriteFunction], [visitDartYield] and [visitAwait] for more
+/// explanation.
 abstract class AsyncRewriterBase extends js.NodeVisitor {
 
   // Local variables are hoisted to the top of the function, so they are
@@ -207,7 +208,7 @@
     // Initialize names specific to the subclass.
     initializeNames();
 
-    return node.accept(this);
+    return rewriteFunction(node);
   }
 
   js.Expression get currentErrorHandler {
@@ -665,8 +666,7 @@
   ///   }
   /// }
   ///
-  @override
-  js.Expression visitFun(js.Fun node) {
+  js.Expression rewriteFunction(js.Fun node) {
     beginLabel(newLabel("Function start"));
     // AsyncStar needs a returnlabel for its handling of cancelation. See
     // [visitDartYield].
@@ -720,6 +720,18 @@
   }
 
   @override
+  js.Expression visitFun(js.Fun node) {
+    if (node.asyncModifier.isAsync || node.asyncModifier.isYielding) {
+      // The translation does not handle nested functions that are generators
+      // or asynchronous.  These functions should only be ones that are
+      // introduced by JS foreign code from our own libraries.
+      reporter.internalError(spannable,
+          'Nested function is a generator or asynchronous.');
+    }
+    return node;
+  }
+
+  @override
   js.Expression visitAccess(js.PropertyAccess node) {
     return withExpression2(node.receiver, node.selector,
         (receiver, selector) => js.js('#[#]', [receiver, selector]));
@@ -772,7 +784,7 @@
 
   /// An await is translated to an [awaitStatement].
   ///
-  /// See the comments of [visitFun] for an example.
+  /// See the comments of [rewriteFunction] for an example.
   @override
   js.Expression visitAwait(js.Await node) {
     assert(isAsync || isAsyncStar);
@@ -929,7 +941,7 @@
   /// It is necessary to run all nesting finally-handlers between the jump and
   /// the target. For that [next] is used as a stack of places to go.
   ///
-  /// See also [visitFun].
+  /// See also [rewriteFunction].
   void translateJump(js.Node target, int targetLabel) {
     // Compute a stack of all the 'finally' nodes that must be visited before
     // the jump.
@@ -1432,7 +1444,7 @@
     return result.reversed.toList();
   }
 
-  /// See the comments of [visitFun] for more explanation.
+  /// See the comments of [rewriteFunction] for more explanation.
   void visitTry(js.Try node) {
     if (!shouldTransform(node)) {
       js.Block body = translateInBlock(node.body);
diff --git a/pkg/compiler/lib/src/mirrors/analyze.dart b/pkg/compiler/lib/src/mirrors/analyze.dart
index 313cc92..4f7f09f 100644
--- a/pkg/compiler/lib/src/mirrors/analyze.dart
+++ b/pkg/compiler/lib/src/mirrors/analyze.dart
@@ -9,7 +9,7 @@
 import 'source_mirrors.dart';
 import 'dart2js_mirrors.dart' show Dart2JsMirrorSystem;
 import '../../compiler.dart' as api;
-import '../../compiler_new.dart' as new_api;
+import '../options.dart' show CompilerOptions;
 import '../apiimpl.dart' as apiimpl;
 import '../compiler.dart' show Compiler;
 import '../old_to_new_api.dart';
@@ -59,7 +59,7 @@
       new LegacyCompilerInput(inputProvider),
       new LegacyCompilerOutput(),
       new LegacyCompilerDiagnostics(internalDiagnosticHandler),
-      new new_api.CompilerOptions.parse(
+      new CompilerOptions.parse(
           libraryRoot: libraryRoot,
           packageRoot: packageRoot,
           options: options,
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
new file mode 100644
index 0000000..e6d915b
--- /dev/null
+++ b/pkg/compiler/lib/src/options.dart
@@ -0,0 +1,597 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.src.options;
+
+import 'commandline_options.dart' show Flags;
+import '../compiler.dart' show PackagesDiscoveryProvider;
+
+/// Options used for parsing.
+///
+/// Use this to conditionally support certain constructs, e.g.,
+/// experimental ones.
+abstract class ParserOptions {
+  const ParserOptions();
+
+  /// Support conditional directives, e.g., configurable imports.
+  bool get enableConditionalDirectives;
+}
+
+/// Options used for controlling diagnostic messages.
+abstract class DiagnosticOptions {
+  const DiagnosticOptions();
+
+  /// If `true`, warnings cause the compilation to fail.
+  bool get fatalWarnings;
+
+  /// Emit terse diagnostics without howToFix.
+  bool get terseDiagnostics;
+
+  /// If `true`, warnings are not reported.
+  bool get suppressWarnings;
+
+  /// If `true`, hints are not reported.
+  bool get suppressHints;
+
+  /// Returns `true` if warnings and hints are shown for all packages.
+  bool get showAllPackageWarnings;
+
+  /// Returns `true` if warnings and hints are hidden for all packages.
+  bool get hidePackageWarnings;
+
+  /// Returns `true` if warnings should be should for [uri].
+  bool showPackageWarningsFor(Uri uri);
+}
+
+/// Object for passing options to the compiler. Superclasses are used to select
+/// subsets of these options, enabling each part of the compiler to depend on
+/// as few as possible.
+class CompilerOptions implements DiagnosticOptions, ParserOptions {
+  /// The entry point of the application that is being compiled.
+  final Uri entryPoint;
+
+  /// Root location where SDK libraries are found.
+  final Uri libraryRoot;
+
+  /// Package root location.
+  ///
+  /// If not null then [packageConfig] should be null.
+  final Uri packageRoot;
+
+  /// Location of the package configuration file.
+  ///
+  /// If not null then [packageRoot] should be null.
+  final Uri packageConfig;
+
+  // TODO(sigmund): Move out of here, maybe to CompilerInput. Options should not
+  // hold code, just configuration options.
+  final PackagesDiscoveryProvider packagesDiscoveryProvider;
+
+  /// Resolved constant "environment" values passed to the compiler via the `-D`
+  /// flags.
+  final Map<String, dynamic> environment;
+
+  /// Whether we allow mocking compilation of libraries such as dart:io and
+  /// dart:html for unit testing purposes.
+  final bool allowMockCompilation;
+
+  /// Whether the native extension syntax is supported by the frontend.
+  final bool allowNativeExtensions;
+
+  /// Whether to resolve all functions in the program, not just those reachable
+  /// from main. This implies [analyzeOnly] is true as well.
+  final bool analyzeAll;
+
+  /// Whether to disable tree-shaking for the main script. This marks all
+  /// functions in the main script as reachable (not just a function named
+  /// `main`).
+  // TODO(sigmund): rename. The current name seems to indicate that only the
+  // main function is retained, which is the opposite of what this does.
+  final bool analyzeMain;
+
+  /// Whether to run the compiler just for the purpose of analysis. That is, to
+  /// run resolution and type-checking alone, but otherwise do not generate any
+  /// code.
+  final bool analyzeOnly;
+
+  /// Whether to skip analysis of method bodies and field initializers. Implies
+  /// [analyzeOnly].
+  final bool analyzeSignaturesOnly;
+
+  /// ID associated with this sdk build.
+  final String buildId;
+
+  /// Whether there is a build-id available so we can use it on error messages
+  /// and in the emitted output of the compiler.
+  bool get hasBuildId => buildId != _UNDETERMINED_BUILD_ID;
+
+  /// Location where to generate a map containing details of how deferred
+  /// libraries are subdivided.
+  final Uri deferredMapUri;
+
+  /// Whether to disable inlining during the backend optimizations.
+  // TODO(sigmund): negate, so all flags are positive
+  final bool disableInlining;
+
+  /// Diagnostic option: If `true`, warnings cause the compilation to fail.
+  final bool fatalWarnings;
+
+  /// Diagnostic option: Emit terse diagnostics without howToFix.
+  final bool terseDiagnostics;
+
+  /// Diagnostic option: If `true`, warnings are not reported.
+  final bool suppressWarnings;
+
+  /// Diagnostic option: If `true`, hints are not reported.
+  final bool suppressHints;
+
+  /// Diagnostic option: List of packages for which warnings and hints are
+  /// reported. If `null`, no package warnings or hints are reported. If
+  /// empty, all warnings and hints are reported.
+  final List<String> _shownPackageWarnings;
+
+  /// Whether to disable global type inference.
+  final bool disableTypeInference;
+
+  /// Whether to emit a .json file with a summary of the information used by the
+  /// compiler during optimization. This includes resolution details,
+  /// dependencies between elements, results of type inference, and the output
+  /// code for each function.
+  final bool dumpInfo;
+
+  /// Whether we allow passing an extra argument to `assert`, containing a
+  /// reason for why an assertion fails. (experimental)
+  final bool enableAssertMessage;
+
+  /// Whether to enable the experimental conditional directives feature.
+  final bool enableConditionalDirectives;
+
+  /// Whether the user specified a flag to allow the use of dart:mirrors. This
+  /// silences a warning produced by the compiler.
+  final bool enableExperimentalMirrors;
+
+  /// Whether to enable minification
+  // TODO(sigmund): rename to minify
+  final bool enableMinification;
+
+  /// Whether to model which native classes are live based on annotations on the
+  /// core libraries. If false, all native classes will be included by default.
+  final bool enableNativeLiveTypeAnalysis;
+
+  /// Whether to generate code containing checked-mode assignability checks.
+  final bool enableTypeAssertions;
+
+  /// Whether to generate code containing user's `assert` statements.
+  final bool enableUserAssertions;
+
+  /// Whether to generate output even when there are compile-time errors.
+  final bool generateCodeWithCompileTimeErrors;
+
+  /// Whether to generate a source-map file together with the output program.
+  final bool generateSourceMap;
+
+  /// Whether some values are cached for reuse in incremental compilation.
+  /// Incremental compilation allows calling `Compiler.run` more than once
+  /// (experimental).
+  final bool hasIncrementalSupport;
+
+  /// URI of the main output if the compiler is generating source maps.
+  final Uri outputUri;
+
+  /// Location of the platform configuration file.
+  final Uri platformConfigUri;
+
+  /// Whether to emit URIs in the reflection metadata.
+  final bool preserveUris;
+
+  /// URI where the compiler should generate the output source map file.
+  final Uri sourceMapUri;
+
+  /// The compiler is run from the build bot.
+  final bool testMode;
+
+  /// Whether to trust JS-interop annotations. (experimental)
+  final bool trustJSInteropTypeAnnotations;
+
+  /// Whether to trust primitive types during inference and optimizations.
+  final bool trustPrimitives;
+
+  /// Whether to trust type annotations during inference and optimizations.
+  final bool trustTypeAnnotations;
+
+  /// Whether to generate code compliant with content security policy (CSP).
+  final bool useContentSecurityPolicy;
+
+  /// Use the experimental CPS based backend.
+  final bool useCpsIr;
+
+  /// When obfuscating for minification, whether to use the frequency of a name
+  /// as an heuristic to pick shorter names.
+  final bool useFrequencyNamer;
+
+  /// Whether to use the new source-information implementation for source-maps.
+  /// (experimental)
+  final bool useNewSourceInfo;
+
+  /// Whether the user requested to use the fast startup emitter. The full
+  /// emitter might still be used if the program uses dart:mirrors.
+  final bool useStartupEmitter;
+
+  /// Enable verbose printing during compilation. Includes progress messages
+  /// during each phase and a time-breakdown between phases at the end.
+  final bool verbose;
+
+  // -------------------------------------------------
+  // Options for deprecated features
+  // -------------------------------------------------
+  // TODO(sigmund): delete these as we delete the underlying features
+
+  /// Whether to preserve comments while scanning (only use for dart:mirrors).
+  final bool preserveComments;
+
+  /// Whether to emit JavaScript (false enables dart2dart).
+  final bool emitJavaScript;
+
+  /// When using dart2dart, whether to use the multi file format.
+  final bool dart2dartMultiFile;
+
+  /// Strip option used by dart2dart.
+  final List<String> strips;
+
+  /// Create an options object by parsing flags from [options].
+  factory CompilerOptions.parse(
+      {Uri entryPoint,
+      Uri libraryRoot,
+      Uri packageRoot,
+      Uri packageConfig,
+      PackagesDiscoveryProvider packagesDiscoveryProvider,
+      Map<String, dynamic> environment: const <String, dynamic>{},
+      List<String> options}) {
+    return new CompilerOptions(
+        entryPoint: entryPoint,
+        libraryRoot: libraryRoot,
+        packageRoot: packageRoot,
+        packageConfig: packageConfig,
+        packagesDiscoveryProvider: packagesDiscoveryProvider,
+        environment: environment,
+        allowMockCompilation: _hasOption(options, Flags.allowMockCompilation),
+        allowNativeExtensions: _hasOption(options, Flags.allowNativeExtensions),
+        analyzeAll: _hasOption(options, Flags.analyzeAll),
+        analyzeMain: _hasOption(options, Flags.analyzeMain),
+        analyzeOnly: _hasOption(options, Flags.analyzeOnly),
+        analyzeSignaturesOnly: _hasOption(options, Flags.analyzeSignaturesOnly),
+        buildId: _extractStringOption(
+            options, '--build-id=', _UNDETERMINED_BUILD_ID),
+        dart2dartMultiFile: _hasOption(options, '--output-type=dart-multi'),
+        deferredMapUri: _extractUriOption(options, '--deferred-map='),
+        fatalWarnings: _hasOption(options, Flags.fatalWarnings),
+        terseDiagnostics: _hasOption(options, Flags.terse),
+        suppressWarnings: _hasOption(options, Flags.suppressWarnings),
+        suppressHints: _hasOption(options, Flags.suppressHints),
+        shownPackageWarnings:
+            _extractOptionalCsvOption(options, Flags.showPackageWarnings),
+        disableInlining: _hasOption(options, Flags.disableInlining),
+        disableTypeInference: _hasOption(options, Flags.disableTypeInference),
+        dumpInfo: _hasOption(options, Flags.dumpInfo),
+        emitJavaScript: !(_hasOption(options, '--output-type=dart') ||
+            _hasOption(options, '--output-type=dart-multi')),
+        enableAssertMessage: _hasOption(options, Flags.enableAssertMessage),
+        enableConditionalDirectives:
+            _hasOption(options, Flags.conditionalDirectives),
+        enableExperimentalMirrors:
+            _hasOption(options, Flags.enableExperimentalMirrors),
+        enableMinification: _hasOption(options, Flags.minify),
+        enableNativeLiveTypeAnalysis:
+            !_hasOption(options, Flags.disableNativeLiveTypeAnalysis),
+        enableTypeAssertions: _hasOption(options, Flags.enableCheckedMode),
+        enableUserAssertions: _hasOption(options, Flags.enableCheckedMode),
+        generateCodeWithCompileTimeErrors:
+            _hasOption(options, Flags.generateCodeWithCompileTimeErrors),
+        generateSourceMap: !_hasOption(options, Flags.noSourceMaps),
+        hasIncrementalSupport: _forceIncrementalSupport ||
+            _hasOption(options, Flags.incrementalSupport),
+        outputUri: _extractUriOption(options, '--out='),
+        platformConfigUri:
+            _resolvePlatformConfigFromOptions(libraryRoot, options),
+        preserveComments: _hasOption(options, Flags.preserveComments),
+        preserveUris: _hasOption(options, Flags.preserveUris),
+        sourceMapUri: _extractUriOption(options, '--source-map='),
+        strips: _extractCsvOption(options, '--force-strip='),
+        testMode: _hasOption(options, Flags.testMode),
+        trustJSInteropTypeAnnotations:
+            _hasOption(options, Flags.trustJSInteropTypeAnnotations),
+        trustPrimitives: _hasOption(options, Flags.trustPrimitives),
+        trustTypeAnnotations: _hasOption(options, Flags.trustTypeAnnotations),
+        useContentSecurityPolicy:
+            _hasOption(options, Flags.useContentSecurityPolicy),
+        useCpsIr: _hasOption(options, Flags.useCpsIr),
+        useFrequencyNamer:
+            !_hasOption(options, Flags.noFrequencyBasedMinification),
+        useNewSourceInfo: _hasOption(options, Flags.useNewSourceInfo),
+        useStartupEmitter: _hasOption(options, Flags.fastStartup),
+        verbose: _hasOption(options, Flags.verbose));
+  }
+
+  /// Creates an option object for the compiler.
+  ///
+  /// This validates and normalizes dependent options to be consistent. For
+  /// example, if [analyzeAll] is true, the resulting options object will also
+  /// have [analyzeOnly] as true.
+  factory CompilerOptions(
+      {Uri entryPoint,
+      Uri libraryRoot,
+      Uri packageRoot,
+      Uri packageConfig,
+      PackagesDiscoveryProvider packagesDiscoveryProvider,
+      Map<String, dynamic> environment: const <String, dynamic>{},
+      bool allowMockCompilation: false,
+      bool allowNativeExtensions: false,
+      bool analyzeAll: false,
+      bool analyzeMain: false,
+      bool analyzeOnly: false,
+      bool analyzeSignaturesOnly: false,
+      String buildId: _UNDETERMINED_BUILD_ID,
+      bool dart2dartMultiFile: false,
+      Uri deferredMapUri: null,
+      bool fatalWarnings: false,
+      bool terseDiagnostics: false,
+      bool suppressWarnings: false,
+      bool suppressHints: false,
+      List<String> shownPackageWarnings: null,
+      bool disableInlining: false,
+      bool disableTypeInference: false,
+      bool dumpInfo: false,
+      bool emitJavaScript: true,
+      bool enableAssertMessage: false,
+      bool enableConditionalDirectives: false,
+      bool enableExperimentalMirrors: false,
+      bool enableMinification: false,
+      bool enableNativeLiveTypeAnalysis: true,
+      bool enableTypeAssertions: false,
+      bool enableUserAssertions: false,
+      bool generateCodeWithCompileTimeErrors: false,
+      bool generateSourceMap: true,
+      bool hasIncrementalSupport: false,
+      Uri outputUri: null,
+      Uri platformConfigUri: null,
+      bool preserveComments: false,
+      bool preserveUris: false,
+      Uri sourceMapUri: null,
+      List<String> strips: const [],
+      bool testMode: false,
+      bool trustJSInteropTypeAnnotations: false,
+      bool trustPrimitives: false,
+      bool trustTypeAnnotations: false,
+      bool useContentSecurityPolicy: false,
+      bool useCpsIr: false,
+      bool useFrequencyNamer: true,
+      bool useNewSourceInfo: false,
+      bool useStartupEmitter: false,
+      bool verbose: false}) {
+    // TODO(sigmund): should entrypoint be here? should we validate it is not
+    // null? In unittests we use the same compiler to analyze or build multiple
+    // entrypoints.
+    if (libraryRoot == null) {
+      throw new ArgumentError("[libraryRoot] is null.");
+    }
+    if (!libraryRoot.path.endsWith("/")) {
+      throw new ArgumentError("[libraryRoot] must end with a /");
+    }
+    if (packageRoot != null && packageConfig != null) {
+      throw new ArgumentError("Only one of [packageRoot] or [packageConfig] "
+          "may be given.");
+    }
+    if (packageRoot != null && !packageRoot.path.endsWith("/")) {
+      throw new ArgumentError("[packageRoot] must end with a /");
+    }
+    if (!analyzeOnly) {
+      if (allowNativeExtensions) {
+        throw new ArgumentError(
+            "${Flags.allowNativeExtensions} is only supported in combination "
+            "with ${Flags.analyzeOnly}");
+      }
+    }
+    return new CompilerOptions._(entryPoint, libraryRoot, packageRoot,
+        packageConfig, packagesDiscoveryProvider, environment,
+        allowMockCompilation: allowMockCompilation,
+        allowNativeExtensions: allowNativeExtensions,
+        analyzeAll: analyzeAll,
+        analyzeMain: analyzeMain,
+        analyzeOnly: analyzeOnly || analyzeSignaturesOnly || analyzeAll,
+        analyzeSignaturesOnly: analyzeSignaturesOnly,
+        buildId: buildId,
+        dart2dartMultiFile: dart2dartMultiFile,
+        deferredMapUri: deferredMapUri,
+        fatalWarnings: fatalWarnings,
+        terseDiagnostics: terseDiagnostics,
+        suppressWarnings: suppressWarnings,
+        suppressHints: suppressHints,
+        shownPackageWarnings: shownPackageWarnings,
+        disableInlining: disableInlining || hasIncrementalSupport,
+        disableTypeInference: disableTypeInference || !emitJavaScript,
+        dumpInfo: dumpInfo,
+        emitJavaScript: emitJavaScript,
+        enableAssertMessage: enableAssertMessage,
+        enableConditionalDirectives: enableConditionalDirectives,
+        enableExperimentalMirrors: enableExperimentalMirrors,
+        enableMinification: enableMinification,
+        enableNativeLiveTypeAnalysis: enableNativeLiveTypeAnalysis,
+        enableTypeAssertions: enableTypeAssertions,
+        enableUserAssertions: enableUserAssertions,
+        generateCodeWithCompileTimeErrors: generateCodeWithCompileTimeErrors,
+        generateSourceMap: generateSourceMap,
+        hasIncrementalSupport: hasIncrementalSupport,
+        outputUri: outputUri,
+        platformConfigUri: platformConfigUri ??
+            _resolvePlatformConfig(
+                libraryRoot, null, !emitJavaScript, const []),
+        preserveComments: preserveComments,
+        preserveUris: preserveUris,
+        sourceMapUri: sourceMapUri,
+        strips: strips,
+        testMode: testMode,
+        trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations,
+        trustPrimitives: trustPrimitives,
+        trustTypeAnnotations: trustTypeAnnotations,
+        useContentSecurityPolicy: useContentSecurityPolicy,
+        useCpsIr: useCpsIr,
+        useFrequencyNamer: useFrequencyNamer,
+        useNewSourceInfo: useNewSourceInfo,
+        useStartupEmitter: useStartupEmitter,
+        verbose: verbose);
+  }
+
+  CompilerOptions._(this.entryPoint, this.libraryRoot, this.packageRoot,
+      this.packageConfig, this.packagesDiscoveryProvider, this.environment,
+      {this.allowMockCompilation: false,
+      this.allowNativeExtensions: false,
+      this.analyzeAll: false,
+      this.analyzeMain: false,
+      this.analyzeOnly: false,
+      this.analyzeSignaturesOnly: false,
+      this.buildId: _UNDETERMINED_BUILD_ID,
+      this.dart2dartMultiFile: false,
+      this.deferredMapUri: null,
+      this.fatalWarnings: false,
+      this.terseDiagnostics: false,
+      this.suppressWarnings: false,
+      this.suppressHints: false,
+      List<String> shownPackageWarnings: null,
+      this.disableInlining: false,
+      this.disableTypeInference: false,
+      this.dumpInfo: false,
+      this.emitJavaScript: true,
+      this.enableAssertMessage: false,
+      this.enableConditionalDirectives: false,
+      this.enableExperimentalMirrors: false,
+      this.enableMinification: false,
+      this.enableNativeLiveTypeAnalysis: false,
+      this.enableTypeAssertions: false,
+      this.enableUserAssertions: false,
+      this.generateCodeWithCompileTimeErrors: false,
+      this.generateSourceMap: true,
+      this.hasIncrementalSupport: false,
+      this.outputUri: null,
+      this.platformConfigUri: null,
+      this.preserveComments: false,
+      this.preserveUris: false,
+      this.sourceMapUri: null,
+      this.strips: const [],
+      this.testMode: false,
+      this.trustJSInteropTypeAnnotations: false,
+      this.trustPrimitives: false,
+      this.trustTypeAnnotations: false,
+      this.useContentSecurityPolicy: false,
+      this.useCpsIr: false,
+      this.useFrequencyNamer: false,
+      this.useNewSourceInfo: false,
+      this.useStartupEmitter: false,
+      this.verbose: false})
+      : _shownPackageWarnings = shownPackageWarnings;
+
+  /// Returns `true` if warnings and hints are shown for all packages.
+  bool get showAllPackageWarnings {
+    return _shownPackageWarnings != null && _shownPackageWarnings.isEmpty;
+  }
+
+  /// Returns `true` if warnings and hints are hidden for all packages.
+  bool get hidePackageWarnings => _shownPackageWarnings == null;
+
+  /// Returns `true` if warnings should be should for [uri].
+  bool showPackageWarningsFor(Uri uri) {
+    if (showAllPackageWarnings) {
+      return true;
+    }
+    if (_shownPackageWarnings != null) {
+      return uri.scheme == 'package' &&
+          _shownPackageWarnings.contains(uri.pathSegments.first);
+    }
+    return false;
+  }
+}
+
+String _extractStringOption(
+    List<String> options, String prefix, String defaultValue) {
+  for (String option in options) {
+    if (option.startsWith(prefix)) {
+      return option.substring(prefix.length);
+    }
+  }
+  return defaultValue;
+}
+
+Uri _extractUriOption(List<String> options, String prefix) {
+  var option = _extractStringOption(options, prefix, null);
+  return (option == null) ? null : Uri.parse(option);
+}
+
+// CSV: Comma separated values.
+List<String> _extractCsvOption(List<String> options, String prefix) {
+  for (String option in options) {
+    if (option.startsWith(prefix)) {
+      return option.substring(prefix.length).split(',');
+    }
+  }
+  return const <String>[];
+}
+
+bool _hasOption(List<String> options, String option) {
+  return options.indexOf(option) >= 0;
+}
+
+/// Extract list of comma separated values provided for [flag]. Returns an
+/// empty list if [option] contain [flag] without arguments. Returns `null` if
+/// [option] doesn't contain [flag] with or without arguments.
+List<String> _extractOptionalCsvOption(List<String> options, String flag) {
+  String prefix = '$flag=';
+  for (String option in options) {
+    if (option == flag) {
+      return const <String>[];
+    }
+    if (option.startsWith(flag)) {
+      return option.substring(prefix.length).split(',');
+    }
+  }
+  return null;
+}
+
+Uri _resolvePlatformConfig(Uri libraryRoot, String platformConfigPath,
+    bool isDart2Dart, Iterable<String> categories) {
+  if (platformConfigPath != null) {
+    return libraryRoot.resolve(platformConfigPath);
+  } else if (isDart2Dart) {
+    return libraryRoot.resolve(_dart2dartPlatform);
+  } else {
+    if (categories.length == 0) {
+      return libraryRoot.resolve(_clientPlatform);
+    }
+    assert(categories.length <= 2);
+    if (categories.contains("Client")) {
+      if (categories.contains("Server")) {
+        return libraryRoot.resolve(_sharedPlatform);
+      }
+      return libraryRoot.resolve(_clientPlatform);
+    }
+    assert(categories.contains("Server"));
+    return libraryRoot.resolve(_serverPlatform);
+  }
+}
+
+Uri _resolvePlatformConfigFromOptions(Uri libraryRoot, List<String> options) {
+  return _resolvePlatformConfig(
+      libraryRoot,
+      _extractStringOption(options, "--platform-config=", null),
+      _hasOption(options, '--output-type=dart'),
+      _extractCsvOption(options, '--categories='));
+}
+
+/// Locations of the platform descriptor files relative to the library root.
+const String _clientPlatform = "lib/dart_client.platform";
+const String _serverPlatform = "lib/dart_server.platform";
+const String _sharedPlatform = "lib/dart_shared.platform";
+const String _dart2dartPlatform = "lib/dart2dart.platform";
+
+const String _UNDETERMINED_BUILD_ID = "build number could not be determined";
+const bool _forceIncrementalSupport =
+    const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT');
diff --git a/pkg/compiler/lib/src/parser/class_element_parser.dart b/pkg/compiler/lib/src/parser/class_element_parser.dart
index 319cba5..ab3516e 100644
--- a/pkg/compiler/lib/src/parser/class_element_parser.dart
+++ b/pkg/compiler/lib/src/parser/class_element_parser.dart
@@ -9,12 +9,14 @@
 
 import 'listener.dart' show
     Listener;
+import '../options.dart' show
+    ParserOptions;
 import 'partial_parser.dart' show
     PartialParser;
 
 class ClassElementParser extends PartialParser {
-  ClassElementParser(Listener listener)
-      : super(listener, enableConditionalDirectives: false);
+  ClassElementParser(Listener listener, ParserOptions options)
+      : super(listener, options);
 
   Token parseClassBody(Token token) => fullParseClassBody(token);
 }
diff --git a/pkg/compiler/lib/src/parser/diet_parser_task.dart b/pkg/compiler/lib/src/parser/diet_parser_task.dart
index 9afc8d4..d2db818 100644
--- a/pkg/compiler/lib/src/parser/diet_parser_task.dart
+++ b/pkg/compiler/lib/src/parser/diet_parser_task.dart
@@ -19,28 +19,26 @@
 import 'element_listener.dart' show
     ElementListener,
     ScannerOptions;
+import '../options.dart' show
+    ParserOptions;
 import 'partial_parser.dart' show
     PartialParser;
 
 class DietParserTask extends CompilerTask {
-  final bool _enableConditionalDirectives;
+  final ParserOptions _parserOptions;
 
-  DietParserTask(Compiler compiler, {bool enableConditionalDirectives})
-      : this._enableConditionalDirectives = enableConditionalDirectives,
-        super(compiler);
+  DietParserTask(Compiler compiler, this._parserOptions) : super(compiler);
 
   final String name = 'Diet Parser';
 
   dietParse(CompilationUnitElement compilationUnit, Token tokens) {
     measure(() {
       Function idGenerator = compiler.getNextFreeClassId;
-      ScannerOptions scannerOptions = new ScannerOptions(
-          canUseNative: compiler.backend.canLibraryUseNative(
-              compilationUnit.library));
+      ScannerOptions scannerOptions =
+          new ScannerOptions.from(compiler, compilationUnit.library);
       ElementListener listener = new ElementListener(
           scannerOptions, compiler.reporter, compilationUnit, idGenerator);
-      PartialParser parser = new PartialParser(
-          listener, enableConditionalDirectives: _enableConditionalDirectives);
+      PartialParser parser = new PartialParser(listener, _parserOptions);
       try {
         parser.parseUnit(tokens);
       } on ParserError catch(_) {
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 48bfae31..fa524cc 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -4,6 +4,8 @@
 
 library dart2js.parser.element_listener;
 
+import '../compiler.dart' show
+    Compiler;
 import '../common.dart';
 import '../diagnostics/messages.dart' show
     MessageTemplate;
@@ -57,11 +59,17 @@
 /// Options used for scanning.
 ///
 /// Use this to conditionally support special tokens.
+///
+/// TODO(johnniwinther): This class should be renamed, it is not about options
+/// in the same sense as `CompilerOptions` or `DiagnosticOptions`.
 class ScannerOptions {
   /// If `true` the pseudo keyword `native` is supported.
   final bool canUseNative;
 
   const ScannerOptions({this.canUseNative: false});
+
+  ScannerOptions.from(Compiler compiler, LibraryElement libraryElement) :
+      canUseNative = compiler.backend.canLibraryUseNative(libraryElement);
 }
 
 /**
diff --git a/pkg/compiler/lib/src/parser/parser.dart b/pkg/compiler/lib/src/parser/parser.dart
index 42e432b..80e6de2 100644
--- a/pkg/compiler/lib/src/parser/parser.dart
+++ b/pkg/compiler/lib/src/parser/parser.dart
@@ -4,6 +4,8 @@
 
 library dart2js.parser;
 
+import '../options.dart' show
+    ParserOptions;
 import '../common.dart';
 import '../tokens/keyword.dart' show
     Keyword;
@@ -97,13 +99,12 @@
  */
 class Parser {
   final Listener listener;
+  final ParserOptions parserOptions;
   bool mayParseFunctionExpressions = true;
-  final bool enableConditionalDirectives;
   bool asyncAwaitKeywordsEnabled;
 
-  Parser(this.listener,
-      {this.enableConditionalDirectives: false,
-       this.asyncAwaitKeywordsEnabled: false});
+  Parser(this.listener, this.parserOptions,
+      {this.asyncAwaitKeywordsEnabled: false});
 
   Token parseUnit(Token token) {
     listener.beginCompilationUnit(token);
@@ -180,7 +181,7 @@
   Token parseConditionalUris(Token token) {
     listener.beginConditionalUris(token);
     int count = 0;
-    if (enableConditionalDirectives) {
+    if (parserOptions.enableConditionalDirectives) {
       while (optional('if', token)) {
         count++;
         token = parseConditionalUri(token);
diff --git a/pkg/compiler/lib/src/parser/parser_task.dart b/pkg/compiler/lib/src/parser/parser_task.dart
index fa715aa..a79875f 100644
--- a/pkg/compiler/lib/src/parser/parser_task.dart
+++ b/pkg/compiler/lib/src/parser/parser_task.dart
@@ -11,6 +11,8 @@
     Compiler;
 import '../elements/modelx.dart' show
     ElementX;
+import '../options.dart' show
+    ParserOptions;
 import '../tokens/token.dart' show
     Token;
 import '../tree/tree.dart' show
@@ -26,12 +28,9 @@
     Parser;
 
 class ParserTask extends CompilerTask {
-  final bool _enableConditionalDirectives;
+  final ParserOptions parserOptions;
 
-  ParserTask(Compiler compiler,
-             {bool enableConditionalDirectives: false})
-      : this._enableConditionalDirectives = enableConditionalDirectives,
-        super(compiler);
+  ParserTask(Compiler compiler, this.parserOptions) : super(compiler);
 
   String get name => 'Parser';
 
@@ -43,8 +42,7 @@
     return measure(() {
       NodeListener listener = new NodeListener(
           const ScannerOptions(), reporter, null);
-      Parser parser = new Parser(
-          listener, enableConditionalDirectives: _enableConditionalDirectives);
+      Parser parser = new Parser(listener, parserOptions);
       try {
         parser.parseUnit(token);
       } on ParserError catch(_) {
diff --git a/pkg/compiler/lib/src/parser/partial_elements.dart b/pkg/compiler/lib/src/parser/partial_elements.dart
index d72c6b7..b37fe70 100644
--- a/pkg/compiler/lib/src/parser/partial_elements.dart
+++ b/pkg/compiler/lib/src/parser/partial_elements.dart
@@ -427,7 +427,7 @@
       parsing.measure(() {
         MemberListener listener = new MemberListener(
             parsing.getScannerOptionsFor(this), reporter, this);
-        Parser parser = new ClassElementParser(listener);
+        Parser parser = new ClassElementParser(listener, parsing.parserOptions);
         try {
           Token token = parser.parseTopLevelDeclaration(beginToken);
           assert(identical(token, endToken.next));
@@ -491,7 +491,7 @@
         if (partial.hasParseError) {
           listener.suppressParseErrors = true;
         }
-        doParse(new Parser(listener));
+        doParse(new Parser(listener, parsing.parserOptions));
       } on ParserError catch (e) {
         partial.hasParseError = true;
         return new ErrorNode(element.position, e.reason);
diff --git a/pkg/compiler/lib/src/parser/partial_parser.dart b/pkg/compiler/lib/src/parser/partial_parser.dart
index 1c7722f..355ddd8 100644
--- a/pkg/compiler/lib/src/parser/partial_parser.dart
+++ b/pkg/compiler/lib/src/parser/partial_parser.dart
@@ -5,6 +5,8 @@
 library dart2js.parser.partial;
 
 import '../common.dart';
+import '../options.dart' show
+    ParserOptions;
 import '../util/characters.dart' as Characters show
     $CLOSE_CURLY_BRACKET;
 import '../tokens/token.dart' show
@@ -20,9 +22,8 @@
     Parser;
 
 class PartialParser extends Parser {
-  PartialParser(Listener listener, {bool enableConditionalDirectives})
-      : super(listener,
-          enableConditionalDirectives: enableConditionalDirectives);
+  PartialParser(Listener listener, ParserOptions options)
+      : super(listener, options);
 
   Token parseClassBody(Token token) => skipClassBody(token);
 
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index fb2e437..977d8a9 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -137,6 +137,8 @@
     JavaScriptBackend;
 import 'library_loader.dart' show
     LibraryLoader;
+import 'options.dart' show
+    ParserOptions;
 import 'parser/listener.dart' show
     Listener,
     ParserError;
@@ -159,11 +161,9 @@
 
 class PatchParserTask extends CompilerTask {
   final String name = "Patching Parser";
-  final bool _enableConditionalDirectives;
+  final ParserOptions parserOptions;
 
-  PatchParserTask(Compiler compiler, {bool enableConditionalDirectives})
-      : this._enableConditionalDirectives = enableConditionalDirectives,
-        super(compiler);
+  PatchParserTask(Compiler compiler, this.parserOptions) : super(compiler);
 
   /**
    * Scans a library patch file, applies the method patches and
@@ -198,9 +198,7 @@
                                                         compilationUnit,
                                                         idGenerator);
       try {
-        new PartialParser(patchListener,
-            enableConditionalDirectives: _enableConditionalDirectives)
-            .parseUnit(tokens);
+        new PartialParser(patchListener, parserOptions).parseUnit(tokens);
       } on ParserError catch (e) {
         // No need to recover from a parser error in platform libraries, user
         // will never see this if the libraries are tested correctly.
@@ -217,8 +215,7 @@
 
     measure(() => reporter.withCurrentElement(cls, () {
       MemberListener listener = new PatchMemberListener(compiler, cls);
-      Parser parser = new PatchClassElementParser(
-          listener, enableConditionalDirectives: _enableConditionalDirectives);
+      Parser parser = new PatchClassElementParser(listener, parserOptions);
       try {
         Token token = parser.parseTopLevelDeclaration(cls.beginToken);
         assert(identical(token, cls.endToken.next));
@@ -270,9 +267,8 @@
  * declarations.
  */
 class PatchClassElementParser extends PartialParser {
-  PatchClassElementParser(Listener listener, {bool enableConditionalDirectives})
-      : super(listener,
-          enableConditionalDirectives: enableConditionalDirectives);
+  PatchClassElementParser(Listener listener, ParserOptions options)
+      : super(listener, options);
 
   Token parseClassBody(Token token) => fullParseClassBody(token);
 }
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 69f9786..b72dba8 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -3214,8 +3214,12 @@
         registry.registerDynamicUse(
             new DynamicUse(operatorSelector, null));
 
-        SendStructure sendStructure =
-            new CompoundIndexSetStructure(semantics, operator);
+        SendStructure sendStructure;
+        if (operator.kind == AssignmentOperatorKind.IF_NULL) {
+          sendStructure = new IndexSetIfNullStructure(semantics);
+        } else {
+          sendStructure = new CompoundIndexSetStructure(semantics, operator);
+        }
         registry.registerSendStructure(node, sendStructure);
         return const NoneResult();
       }
@@ -3338,8 +3342,12 @@
         registry.registerDynamicUse(
             new DynamicUse(operatorSelector, null));
 
-        SendStructure sendStructure =
-            new CompoundIndexSetStructure(semantics, operator);
+        SendStructure sendStructure;
+        if (operator.kind == AssignmentOperatorKind.IF_NULL) {
+          sendStructure = new IndexSetIfNullStructure(semantics);
+        } else {
+          sendStructure = new CompoundIndexSetStructure(semantics, operator);
+        }
         registry.registerSendStructure(node, sendStructure);
         return const NoneResult();
       }
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor.dart b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
index e28d3e1..4aaba70 100644
--- a/pkg/compiler/lib/src/resolution/semantic_visitor.dart
+++ b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
@@ -3181,8 +3181,7 @@
       A arg);
 
   /// Compound index assignment of [rhs] with [operator] to [index] on the
-  /// index operators of [receiver] whose getter and setter are defined by
-  /// [getterSelector] and [setterSelector], respectively.
+  /// index operators of [receiver].
   ///
   /// For instance:
   ///
@@ -3219,8 +3218,8 @@
       A arg);
 
   /// Compound index assignment of [rhs] with [operator] to [index] on a super
-  /// super class where the index getter is undefined and the index setter is
-  /// defined by [setter].
+  /// class where the index getter is undefined and the index setter is defined
+  /// by [setter].
   ///
   /// For instance:
   ///
@@ -3240,8 +3239,8 @@
       A arg);
 
   /// Compound index assignment of [rhs] with [operator] to [index] on a super
-  /// super class where the index getter is defined by [getter] but the index
-  /// setter is undefined.
+  /// class where the index getter is defined by [getter] but the index setter
+  /// is undefined.
   ///
   /// For instance:
   ///
@@ -3262,7 +3261,7 @@
       A arg);
 
   /// Compound index assignment of [rhs] with [operator] to [index] on a super
-  /// super class where the index getter and setter are undefined.
+  /// class where the index getter and setter are undefined.
   ///
   /// For instance:
   ///
@@ -3280,6 +3279,99 @@
       Node rhs,
       A arg);
 
+  /// If-null assignment expression of [rhs] to [index] on the index operators
+  /// of [receiver].
+  ///
+  /// For instance:
+  ///
+  ///     m(receiver, index, rhs) => receiver[index] ??= rhs;
+  ///
+  R visitIndexSetIfNull(
+      SendSet node,
+      Node receiver,
+      Node index,
+      Node rhs,
+      A arg);
+
+  /// If-null assignment expression of [rhs] to [index] on the index operators
+  /// of a super class defined by [getter] and [setter].
+  ///
+  /// For instance:
+  ///
+  ///     class B {
+  ///       operator [](index) {}
+  ///       operator [](index, value) {}
+  ///     }
+  ///     class C extends B {
+  ///       m(index, rhs) => super[index] ??= rhs;
+  ///     }
+  ///
+  R visitSuperIndexSetIfNull(
+      SendSet node,
+      MethodElement getter,
+      MethodElement setter,
+      Node index,
+      Node rhs,
+      A arg);
+
+  /// If-null assignment expression of [rhs] to [index] on a super class where
+  /// the index getter is undefined and the index setter is defined by [setter].
+  ///
+  /// For instance:
+  ///
+  ///     class B {
+  ///       operator [](index, value) {}
+  ///     }
+  ///     class C extends B {
+  ///       m() => super[1] ??= 42;
+  ///     }
+  ///
+  R visitUnresolvedSuperGetterIndexSetIfNull(
+      Send node,
+      Element element,
+      MethodElement setter,
+      Node index,
+      Node rhs,
+      A arg);
+
+  /// If-null assignment expression of [rhs] to [index] on a super class where
+  /// the index getter is defined by [getter] but the index setter is undefined.
+  ///
+  /// For instance:
+  ///
+  ///     class B {
+  ///       operator [](index) => 42;
+  ///     }
+  ///     class C extends B {
+  ///       m() => super[1] ??= 42;
+  ///     }
+  ///
+  R visitUnresolvedSuperSetterIndexSetIfNull(
+      Send node,
+      MethodElement getter,
+      Element element,
+      Node index,
+      Node rhs,
+      A arg);
+
+  /// If-null assignment expression of [rhs] to [index] on a super class where
+  /// the index getter and setter are undefined.
+  ///
+  /// For instance:
+  ///
+  ///     class B {
+  ///     }
+  ///     class C extends B {
+  ///       m() => super[1] ??= 42;
+  ///     }
+  ///
+  R visitUnresolvedSuperIndexSetIfNull(
+      Send node,
+      Element element,
+      Node index,
+      Node rhs,
+      A arg);
+
   /// Prefix expression with [operator] of the property on [receiver] whose
   /// getter and setter are defined by [getterSelector] and [setterSelector],
   /// respectively.
@@ -5087,6 +5179,22 @@
       Node rhs,
       A arg);
 
+  /// If-null assignment expression of [rhs] to [index] on the index operators
+  /// of an invalid expression.
+  ///
+  /// For instance:
+  ///
+  ///     import 'foo.dart' as p;
+  ///
+  ///     m(index, rhs) => p[index] ??= rhs;
+  ///
+  R errorInvalidIndexSetIfNull(
+      SendSet node,
+      ErroneousElement error,
+      Node index,
+      Node rhs,
+      A arg);
+
   /// Unary operation with [operator] on an invalid expression.
   ///
   /// For instance:
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart b/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
index 75272f3..36db8a8b 100644
--- a/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
+++ b/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
@@ -179,6 +179,16 @@
   }
 
   @override
+  R errorInvalidIndexSetIfNull(
+      SendSet node,
+      ErroneousElement error,
+      Node index,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node, error, arg);
+  }
+
+  @override
   R errorInvalidIndexPrefix(
       Send node,
       ErroneousElement error,
@@ -1842,6 +1852,59 @@
       A arg) {
     return bulkHandleSetIfNull(node, arg);
   }
+
+  @override
+  R visitIndexSetIfNull(
+      SendSet node,
+      Node receiver,
+      Node index,
+      Node rhs,
+      A arg) {
+    return bulkHandleSetIfNull(node, arg);
+  }
+
+  @override
+  R visitSuperIndexSetIfNull(
+      SendSet node,
+      MethodElement getter,
+      MethodElement setter,
+      Node index,
+      Node rhs,
+      A arg) {
+    return bulkHandleSetIfNull(node, arg);
+  }
+
+  @override
+  R visitUnresolvedSuperGetterIndexSetIfNull(
+      Send node,
+      Element element,
+      MethodElement setter,
+      Node index,
+      Node rhs,
+      A arg) {
+    return bulkHandleSetIfNull(node, arg);
+  }
+
+  @override
+  R visitUnresolvedSuperSetterIndexSetIfNull(
+      Send node,
+      MethodElement getter,
+      Element element,
+      Node index,
+      Node rhs,
+      A arg) {
+    return bulkHandleSetIfNull(node, arg);
+  }
+
+  @override
+  R visitUnresolvedSuperIndexSetIfNull(
+      Send node,
+      Element element,
+      Node index,
+      Node rhs,
+      A arg) {
+    return bulkHandleSetIfNull(node, arg);
+  }
 }
 
 /// Mixin that implements all `visitXInvoke` methods of [SemanticSendVisitor] by
@@ -4044,15 +4107,6 @@
   }
 
   @override
-  R errorInvalidAssert(
-      Send node,
-      NodeList arguments,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
   R errorInvalidCompound(
       Send node,
       ErroneousElement error,
@@ -7222,6 +7276,83 @@
       A arg) {
     return null;
   }
+
+  @override
+  R visitIndexSetIfNull(
+      SendSet node,
+      Node receiver,
+      Node index,
+      Node rhs,
+      A arg) {
+    apply(receiver, arg);
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperIndexSetIfNull(
+      SendSet node,
+      MethodElement getter,
+      MethodElement setter,
+      Node index,
+      Node rhs,
+      A arg) {
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitUnresolvedSuperGetterIndexSetIfNull(
+      Send node,
+      Element element,
+      MethodElement setter,
+      Node index,
+      Node rhs,
+      A arg) {
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitUnresolvedSuperSetterIndexSetIfNull(
+      Send node,
+      MethodElement getter,
+      Element element,
+      Node index,
+      Node rhs,
+      A arg) {
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+
+  @override
+  R visitUnresolvedSuperIndexSetIfNull(
+      Send node,
+      Element element,
+      Node index,
+      Node rhs,
+      A arg) {
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorInvalidIndexSetIfNull(
+      SendSet node,
+      ErroneousElement error,
+      Node index,
+      Node rhs,
+      A arg) {
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
 }
 
 /// [SemanticDeclarationVisitor] that visits subnodes.
@@ -9866,7 +9997,7 @@
         arg);
   }
 
-
+  @override
   R visitSuperGetterSetterPrefix(
       Send node,
       FunctionElement getter,
@@ -11826,7 +11957,72 @@
   }
 }
 
+/// Simplified handling of super if-null assignments.
+abstract class BaseImplementationOfSuperIndexSetIfNullMixin<R, A>
+    implements SemanticSendVisitor<R, A> {
 
+  /// Handle a super index if-null assignments, like `super[index] ??= rhs`.
+  R handleSuperIndexSetIfNull(
+      SendSet node,
+      Element indexFunction,
+      Element indexSetFunction,
+      Node index,
+      Node rhs,
+      A arg,
+      {bool isGetterValid,
+       bool isSetterValid});
+
+  @override
+  R visitSuperIndexSetIfNull(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      Node rhs,
+      A arg) {
+    return handleSuperIndexSetIfNull(
+        node, indexFunction, indexSetFunction, index, rhs, arg,
+        isGetterValid: true, isSetterValid: true);
+  }
+
+  @override
+  R visitUnresolvedSuperGetterIndexSetIfNull(
+      Send node,
+      Element indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      Node rhs,
+      A arg) {
+    return handleSuperIndexSetIfNull(
+        node, indexFunction, indexSetFunction, index, rhs, arg,
+        isGetterValid: false, isSetterValid: true);
+  }
+
+  @override
+  R visitUnresolvedSuperSetterIndexSetIfNull(
+      Send node,
+      FunctionElement indexFunction,
+      Element indexSetFunction,
+      Node index,
+      Node rhs,
+      A arg) {
+    return handleSuperIndexSetIfNull(
+        node, indexFunction, indexSetFunction, index, rhs, arg,
+        isGetterValid: true, isSetterValid: false);
+  }
+
+  @override
+  R visitUnresolvedSuperIndexSetIfNull(
+      Send node,
+      Element element,
+      Node index,
+      Node rhs,
+      A arg) {
+    return handleSuperIndexSetIfNull(
+        node, element, element, index, rhs, arg,
+        isGetterValid: false, isSetterValid: false);
+  }
+}
 
 /// Mixin that groups all `visitSuperXPrefix`, `visitSuperXPostfix` methods by
 /// delegating calls to `handleSuperXPostfixPrefix` methods.
diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
index 5ff76ef..647e80e 100644
--- a/pkg/compiler/lib/src/resolution/send_structure.dart
+++ b/pkg/compiler/lib/src/resolution/send_structure.dart
@@ -1990,6 +1990,80 @@
   String toString() => 'compound []=($operator,$semantics)';
 }
 
+/// The structure for a [Send] that is a if-null assignment on the index
+/// operator. For instance `a[b] ??= c`.
+class IndexSetIfNullStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the index operations.
+  final AccessSemantics semantics;
+
+  IndexSetIfNullStructure(this.semantics);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.EXPRESSION:
+        return visitor.visitIndexSetIfNull(
+            node,
+            node.receiver,
+            node.arguments.first,
+            node.arguments.tail.head,
+            arg);
+      case AccessKind.UNRESOLVED_SUPER:
+        return visitor.visitUnresolvedSuperIndexSetIfNull(
+            node,
+            semantics.element,
+            node.arguments.first,
+            node.arguments.tail.head,
+            arg);
+      case AccessKind.INVALID:
+        return visitor.errorInvalidIndexSetIfNull(
+            node,
+            semantics.element,
+            node.arguments.first,
+            node.arguments.tail.head,
+            arg);
+      case AccessKind.COMPOUND:
+        CompoundAccessSemantics compoundSemantics = semantics;
+        switch (compoundSemantics.compoundAccessKind) {
+          case CompoundAccessKind.SUPER_GETTER_SETTER:
+            return visitor.visitSuperIndexSetIfNull(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                node.arguments.first,
+                node.arguments.tail.head,
+                arg);
+          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
+            return visitor.visitUnresolvedSuperGetterIndexSetIfNull(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                node.arguments.first,
+                node.arguments.tail.head,
+                arg);
+          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
+            return visitor.visitUnresolvedSuperSetterIndexSetIfNull(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                node.arguments.first,
+                node.arguments.tail.head,
+                arg);
+          default:
+            // This is not a valid case.
+            break;
+        }
+        break;
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(
+        node, "Invalid index set if-null: ${semantics}");
+  }
+
+  String toString() => 'index set if-null []??=($semantics)';
+}
+
 /// The structure for a [Send] that is a prefix operations. For instance
 /// `++a`.
 class PrefixStructure<R, A> implements SendStructure<R, A> {
diff --git a/pkg/compiler/lib/src/serialization/element_serialization.dart b/pkg/compiler/lib/src/serialization/element_serialization.dart
index d9877a4..86c3337 100644
--- a/pkg/compiler/lib/src/serialization/element_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/element_serialization.dart
@@ -308,10 +308,13 @@
     mixins = mixins.reversed.toList();
     InterfaceType supertype = element.thisType.asInstanceOf(superclass);
 
-
     encoder.setType(Key.SUPERTYPE, supertype);
     encoder.setTypes(Key.MIXINS, mixins);
     encoder.setTypes(Key.INTERFACES, element.interfaces.toList());
+    FunctionType callType = element.declaration.callType;
+    if (callType != null) {
+      encoder.setType(Key.CALL_TYPE, element.callType);
+    }
 
     if (element.isMixinApplication) {
       MixinApplicationElement mixinElement = element;
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
new file mode 100644
index 0000000..5bc9d23
--- /dev/null
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -0,0 +1,700 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Functions for asserting equivalence across serialization.
+
+library dart2js.serialization.equivalence;
+
+import '../common/resolution.dart';
+import '../constants/expressions.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../elements/visitor.dart';
+import '../universe/selector.dart';
+import '../universe/use.dart';
+
+/// Equality based equivalence function.
+bool equality(a, b) => a == b;
+
+/// Returns `true` if the elements in [a] and [b] are pair-wise equivalent
+/// according to [elementEquivalence].
+bool areListsEquivalent(
+    List a,
+    List b,
+    [bool elementEquivalence(a, b) = equality]) {
+
+  if (a.length != b.length) return false;
+  for (int i = 0; i < a.length && i < b.length; i++) {
+    if (!elementEquivalence(a[i], b[i])) {
+      return false;
+    }
+  }
+  return true;
+}
+
+/// Returns `true` if the elements in [a] and [b] are equivalent as sets using
+/// [elementEquivalence] to determine element equivalence.
+bool areSetsEquivalent(
+    Iterable set1,
+    Iterable set2,
+    [bool elementEquivalence(a, b) = equality]) {
+  Set remaining = set2.toSet();
+  for (var element1 in set1) {
+    bool found = false;
+    for (var element2 in set2) {
+      if (elementEquivalence(element1, element2)) {
+        found = true;
+        remaining.remove(element2);
+        break;
+      }
+    }
+    if (!found) {
+      return false;
+    }
+  }
+  return remaining.isEmpty;
+}
+
+/// Returns `true` if elements [a] and [b] are equivalent.
+bool areElementsEquivalent(Element a, Element b) {
+  if (identical(a, b)) return true;
+  if (a == null || b == null) return false;
+  return const ElementIdentityEquivalence().visit(a, b);
+}
+
+/// Returns `true` if types [a] and [b] are equivalent.
+bool areTypesEquivalent(DartType a, DartType b) {
+  if (identical(a, b)) return true;
+  if (a == null || b == null) return false;
+  return const TypeEquivalence().visit(a, b);
+}
+
+/// Returns `true` if constants [a] and [b] are equivalent.
+bool areConstantsEquivalent(ConstantExpression exp1, ConstantExpression exp2) {
+  if (identical(exp1, exp2)) return true;
+  if (exp1 == null || exp2 == null) return false;
+  return const ConstantEquivalence().visit(exp1, exp2);
+}
+
+/// Returns `true` if the lists of elements, [a] and [b], are equivalent.
+bool areElementListsEquivalent(List<Element> a, List<Element> b) {
+  return areListsEquivalent(a, b, areElementsEquivalent);
+}
+
+/// Returns `true` if the lists of types, [a] and [b], are equivalent.
+bool areTypeListsEquivalent(List<DartType> a, List<DartType> b) {
+  return areListsEquivalent(a, b, areTypesEquivalent);
+}
+
+/// Returns `true` if the lists of constants, [a] and [b], are equivalent.
+bool areConstantListsEquivalent(List<ConstantExpression> a,
+                                List<ConstantExpression> b) {
+  return areListsEquivalent(a, b, areConstantsEquivalent);
+}
+
+/// Returns `true` if the selectors [a] and [b] are equivalent.
+bool areSelectorsEquivalent(Selector a, Selector b) {
+  return a.kind == b.kind &&
+         a.callStructure == b.callStructure &&
+         areNamesEquivalent(a.memberName, b.memberName);
+}
+
+/// Returns `true` if the names [a] and [b] are equivalent.
+bool areNamesEquivalent(Name a, Name b) {
+  return a.text == b.text &&
+         a.isSetter == b.isSetter &&
+         areElementsEquivalent(a.library, b.library);
+}
+
+/// Returns `true` if the dynamic uses [a] and [b] are equivalent.
+bool areDynamicUsesEquivalent(DynamicUse a, DynamicUse b) {
+  return areSelectorsEquivalent(a.selector, b.selector);
+}
+
+/// Returns `true` if the static uses [a] and [b] are equivalent.
+bool areStaticUsesEquivalent(StaticUse a, StaticUse b) {
+  return a.kind == b.kind &&
+         areElementsEquivalent(a.element, b.element);
+}
+
+/// Returns `true` if the type uses [a] and [b] are equivalent.
+bool areTypeUsesEquivalent(TypeUse a, TypeUse b) {
+  return a.kind == b.kind &&
+         areTypesEquivalent(a.type, b.type);
+}
+
+/// Returns `true` if the list literal uses [a] and [b] are equivalent.
+bool areListLiteralUsesEquivalent(ListLiteralUse a, ListLiteralUse b) {
+  return areTypesEquivalent(a.type, b.type) &&
+         a.isConstant == b.isConstant &&
+         a.isEmpty == b.isEmpty;
+}
+
+/// Returns `true` if the map literal uses [a] and [b] are equivalent.
+bool areMapLiteralUsesEquivalent(MapLiteralUse a, MapLiteralUse b) {
+  return areTypesEquivalent(a.type, b.type) &&
+         a.isConstant == b.isConstant &&
+         a.isEmpty == b.isEmpty;
+}
+
+/// Strategy for testing equivalence.
+///
+/// Use this strategy to determine equivalence without failing on inequivalence.
+class TestStrategy {
+  const TestStrategy();
+
+  bool test(var object1, var object2, String property, var value1, var value2) {
+    return value1 == value2;
+  }
+
+  bool testLists(
+      Object object1, Object object2, String property,
+      List list1, List list2,
+      [bool elementEquivalence(a, b) = equality]) {
+    return areListsEquivalent(list1, list2, elementEquivalence);
+  }
+
+  bool testSets(
+      var object1, var object2, String property,
+      Iterable set1, Iterable set2,
+      [bool elementEquivalence(a, b) = equality]) {
+    return areSetsEquivalent(set1, set2, elementEquivalence);
+  }
+
+  bool testElements(
+      Object object1, Object object2, String property,
+      Element element1, Element element2) {
+    return areElementsEquivalent(element1, element2);
+  }
+
+  bool testTypes(
+      Object object1, Object object2, String property,
+      DartType type1, DartType type2) {
+    return areTypesEquivalent(type1, type2);
+  }
+
+  bool testConstants(
+      Object object1, Object object2, String property,
+      ConstantExpression exp1, ConstantExpression exp2) {
+    return areConstantsEquivalent(exp1, exp2);
+  }
+
+  bool testTypeLists(
+      Object object1, Object object2, String property,
+      List<DartType> list1, List<DartType> list2) {
+    return areTypeListsEquivalent(list1, list2);
+  }
+
+  bool testConstantLists(
+      Object object1, Object object2, String property,
+      List<ConstantExpression> list1,
+      List<ConstantExpression> list2) {
+    return areConstantListsEquivalent(list1, list2);
+  }
+
+}
+
+/// Visitor that checks for equivalence of [Element]s.
+class ElementIdentityEquivalence extends BaseElementVisitor<bool, Element> {
+  final TestStrategy strategy;
+
+  const ElementIdentityEquivalence([this.strategy = const TestStrategy()]);
+
+  bool visit(Element element1, Element element2) {
+    if (element1 == null && element2 == null) {
+      return true;
+    } else if (element1 == null || element2 == null) {
+      return false;
+    }
+    element1 = element1.declaration;
+    element2 = element2.declaration;
+    if (element1 == element2) {
+      return true;
+    }
+    return
+        strategy.test(
+            element1, element2, 'kind',
+            element1.kind, element2.kind) &&
+        element1.accept(this, element2);
+  }
+
+  @override
+  bool visitElement(Element e, Element arg) {
+    throw new UnsupportedError("Unsupported element $e");
+  }
+
+  @override
+  bool visitLibraryElement(LibraryElement element1, LibraryElement element2) {
+    return
+        strategy.test(element1, element2,
+            'canonicalUri',
+            element1.canonicalUri, element2.canonicalUri);
+  }
+
+  @override
+  bool visitCompilationUnitElement(CompilationUnitElement element1,
+                                   CompilationUnitElement element2) {
+    return
+        strategy.test(element1, element2,
+            'name',
+            element1.name, element2.name) &&
+        visit(element1.library, element2.library);
+  }
+
+  @override
+  bool visitClassElement(ClassElement element1, ClassElement element2) {
+    return
+        strategy.test(element1, element2,
+            'name',
+            element1.name, element2.name) &&
+        visit(element1.library, element2.library);
+  }
+
+  bool checkMembers(Element element1, Element element2) {
+    if (!strategy.test(element1, element2, 'name',
+                       element1.name, element2.name)) {
+      return false;
+    }
+    if (element1.enclosingClass != null || element2.enclosingClass != null) {
+      return visit(element1.enclosingClass, element2.enclosingClass);
+    } else {
+      return visit(element1.library, element2.library);
+    }
+  }
+
+  @override
+  bool visitFieldElement(FieldElement element1, FieldElement element2) {
+    return checkMembers(element1, element2);
+  }
+
+  @override
+  bool visitConstructorElement(ConstructorElement element1,
+                               ConstructorElement element2) {
+    return checkMembers(element1, element2);
+  }
+
+  @override
+  bool visitMethodElement(MethodElement element1,
+                          MethodElement element2) {
+    return checkMembers(element1, element2);
+  }
+
+  @override
+  bool visitGetterElement(GetterElement element1,
+                          GetterElement element2) {
+    return checkMembers(element1, element2);
+  }
+
+  @override
+  bool visitSetterElement(SetterElement element1,
+                          SetterElement element2) {
+    return checkMembers(element1, element2);
+  }
+
+  @override
+  bool visitLocalFunctionElement(LocalFunctionElement element1,
+                                 LocalFunctionElement element2) {
+    // TODO(johnniwinther): Define an equivalence on locals.
+    return checkMembers(element1.memberContext, element2.memberContext);
+  }
+
+  bool visitAbstractFieldElement(AbstractFieldElement element1,
+                                 AbstractFieldElement element2) {
+    return checkMembers(element1, element2);
+  }
+
+  @override
+  bool visitTypeVariableElement(TypeVariableElement element1,
+                                TypeVariableElement element2) {
+    return
+        strategy.test(
+            element1, element2, 'name',
+            element1.name, element2.name) &&
+        visit(element1.typeDeclaration, element2.typeDeclaration);
+  }
+
+  @override
+  bool visitTypedefElement(TypedefElement element1, TypedefElement element2) {
+    return
+        strategy.test(
+            element1, element2, 'name',
+            element1.name, element2.name) &&
+        visit(element1.library, element2.library);
+  }
+
+  @override
+  bool visitParameterElement(ParameterElement element1,
+                             ParameterElement element2) {
+    return
+        strategy.test(
+            element1, element2, 'name',
+            element1.name, element2.name) &&
+        visit(element1.functionDeclaration, element2.functionDeclaration);
+  }
+
+  @override
+  bool visitImportElement(ImportElement element1, ImportElement element2) {
+    return
+        visit(element1.importedLibrary, element2.importedLibrary) &&
+        visit(element1.library, element2.library);
+  }
+
+  @override
+  bool visitExportElement(ExportElement element1, ExportElement element2) {
+    return
+        visit(element1.exportedLibrary, element2.exportedLibrary) &&
+        visit(element1.library, element2.library);
+  }
+
+  @override
+  bool visitPrefixElement(PrefixElement element1, PrefixElement element2) {
+    return
+        strategy.test(
+            element1, element2, 'name',
+            element1.name, element2.name) &&
+        visit(element1.library, element2.library);
+  }
+}
+
+
+/// Visitor that checks for equivalence of [DartType]s.
+class TypeEquivalence implements DartTypeVisitor<bool, DartType> {
+  final TestStrategy strategy;
+
+  const TypeEquivalence([this.strategy = const TestStrategy()]);
+
+  bool visit(DartType type1, DartType type2) {
+    return
+        strategy.test(type1, type2, 'kind', type1.kind, type2.kind) &&
+        type1.accept(this, type2);
+  }
+
+  @override
+  bool visitDynamicType(DynamicType type, DynamicType other) => true;
+
+  @override
+  bool visitFunctionType(FunctionType type, FunctionType other) {
+    return
+        strategy.testTypeLists(
+            type, other, 'parameterTypes',
+            type.parameterTypes, other.parameterTypes) &&
+        strategy.testTypeLists(
+            type, other, 'optionalParameterTypes',
+            type.optionalParameterTypes, other.optionalParameterTypes) &&
+        strategy.testTypeLists(
+            type, other, 'namedParameterTypes',
+            type.namedParameterTypes, other.namedParameterTypes) &&
+        strategy.testLists(
+            type, other, 'namedParameters',
+            type.namedParameters, other.namedParameters);
+  }
+
+  bool visitGenericType(GenericType type, GenericType other) {
+    return
+        strategy.testElements(
+            type, other, 'element',
+            type.element, other.element) &&
+        strategy.testTypeLists(
+            type, other, 'typeArguments',
+            type.typeArguments, other.typeArguments);
+  }
+
+  @override
+  bool visitMalformedType(MalformedType type, MalformedType other) => true;
+
+  @override
+  bool visitStatementType(StatementType type, StatementType other) {
+    throw new UnsupportedError("Unsupported type: $type");
+  }
+
+  @override
+  bool visitTypeVariableType(TypeVariableType type, TypeVariableType other) {
+    return
+        strategy.testElements(
+            type, other, 'element',
+            type.element, other.element);
+  }
+
+  @override
+  bool visitVoidType(VoidType type, VoidType argument) => true;
+
+  @override
+  bool visitInterfaceType(InterfaceType type, InterfaceType other) {
+    return visitGenericType(type, other);
+  }
+
+  @override
+  bool visitTypedefType(TypedefType type, TypedefType other) {
+    return visitGenericType(type, other);
+  }
+}
+
+/// Visitor that checks for structural equivalence of [ConstantExpression]s.
+class ConstantEquivalence
+    implements ConstantExpressionVisitor<bool, ConstantExpression> {
+  final TestStrategy strategy;
+
+  const ConstantEquivalence([this.strategy = const TestStrategy()]);
+
+  @override
+  bool visit(ConstantExpression exp1, ConstantExpression exp2) {
+    if (identical(exp1, exp2)) return true;
+    return
+        strategy.test(exp1, exp2, 'kind', exp1.kind, exp2.kind) &&
+        exp1.accept(this, exp2);
+  }
+
+  @override
+  bool visitBinary(BinaryConstantExpression exp1,
+                   BinaryConstantExpression exp2) {
+    return
+        strategy.test(exp1, exp2, 'operator', exp1.operator, exp2.operator) &&
+        strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) &&
+        strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right);
+  }
+
+  @override
+  bool visitConcatenate(ConcatenateConstantExpression exp1,
+                   ConcatenateConstantExpression exp2) {
+    return
+        strategy.testConstantLists(
+            exp1, exp2, 'expressions',
+            exp1.expressions, exp2.expressions);
+  }
+
+  @override
+  bool visitConditional(ConditionalConstantExpression exp1,
+                   ConditionalConstantExpression exp2) {
+    return
+        strategy.testConstants(
+            exp1, exp2, 'condition', exp1.condition, exp2.condition) &&
+        strategy.testConstants(
+            exp1, exp2, 'trueExp', exp1.trueExp, exp2.trueExp) &&
+        strategy.testConstants(
+            exp1, exp2, 'falseExp', exp1.falseExp, exp2.falseExp);
+  }
+
+  @override
+  bool visitConstructed(ConstructedConstantExpression exp1,
+                   ConstructedConstantExpression exp2) {
+    return
+        strategy.testTypes(
+            exp1, exp2, 'type',
+            exp1.type, exp2.type) &&
+        strategy.testElements(
+            exp1, exp2, 'target',
+            exp1.target, exp2.target) &&
+        strategy.testConstantLists(
+            exp1, exp2, 'arguments',
+            exp1.arguments, exp2.arguments) &&
+        strategy.test(exp1, exp2, 'callStructure',
+             exp1.callStructure, exp2.callStructure);
+  }
+
+  @override
+  bool visitFunction(FunctionConstantExpression exp1,
+                FunctionConstantExpression exp2) {
+    return
+        strategy.testElements(
+            exp1, exp2, 'element',
+            exp1.element, exp2.element);
+  }
+
+  @override
+  bool visitIdentical(IdenticalConstantExpression exp1,
+                 IdenticalConstantExpression exp2) {
+    return
+        strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) &&
+        strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right);
+  }
+
+  @override
+  bool visitList(ListConstantExpression exp1, ListConstantExpression exp2) {
+    return
+        strategy.testTypes(
+            exp1, exp2, 'type',
+            exp1.type, exp2.type) &&
+        strategy.testConstantLists(
+            exp1, exp2, 'values',
+            exp1.values, exp2.values);
+  }
+
+  @override
+  bool visitMap(MapConstantExpression exp1, MapConstantExpression exp2) {
+    return
+        strategy.testTypes(
+            exp1, exp2, 'type',
+            exp1.type, exp2.type) &&
+        strategy.testConstantLists(
+            exp1, exp2, 'keys',
+            exp1.keys, exp2.keys) &&
+        strategy.testConstantLists(
+            exp1, exp2, 'values',
+            exp1.values, exp2.values);
+  }
+
+  @override
+  bool visitNamed(NamedArgumentReference exp1, NamedArgumentReference exp2) {
+    return strategy.test(exp1, exp2, 'name', exp1.name, exp2.name);
+  }
+
+  @override
+  bool visitPositional(PositionalArgumentReference exp1,
+                  PositionalArgumentReference exp2) {
+    return strategy.test(exp1, exp2, 'index', exp1.index, exp2.index);
+  }
+
+  @override
+  bool visitSymbol(SymbolConstantExpression exp1,
+                   SymbolConstantExpression exp2) {
+    // TODO: implement visitSymbol
+    return true;
+  }
+
+  @override
+  bool visitType(TypeConstantExpression exp1, TypeConstantExpression exp2) {
+    return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type);
+  }
+
+  @override
+  bool visitUnary(UnaryConstantExpression exp1, UnaryConstantExpression exp2) {
+    return
+        strategy.test(exp1, exp2, 'operator', exp1.operator, exp2.operator) &&
+        strategy.testConstants(
+            exp1, exp2, 'expression', exp1.expression, exp2.expression);
+  }
+
+  @override
+  bool visitVariable(VariableConstantExpression exp1,
+                VariableConstantExpression exp2) {
+    return
+        strategy.testElements(
+            exp1, exp2, 'element',
+            exp1.element, exp2.element);
+  }
+
+  @override
+  bool visitBool(BoolConstantExpression exp1, BoolConstantExpression exp2) {
+    return
+        strategy.test(
+            exp1, exp2, 'primitiveValue',
+            exp1.primitiveValue, exp2.primitiveValue);
+  }
+
+  @override
+  bool visitDouble(DoubleConstantExpression exp1,
+                   DoubleConstantExpression exp2) {
+    return
+        strategy.test(
+            exp1, exp2, 'primitiveValue',
+            exp1.primitiveValue, exp2.primitiveValue);
+  }
+
+  @override
+  bool visitInt(IntConstantExpression exp1, IntConstantExpression exp2) {
+    return
+        strategy.test(
+            exp1, exp2, 'primitiveValue',
+            exp1.primitiveValue, exp2.primitiveValue);
+  }
+
+  @override
+  bool visitNull(NullConstantExpression exp1, NullConstantExpression exp2) {
+    return true;
+  }
+
+  @override
+  bool visitString(StringConstantExpression exp1,
+                   StringConstantExpression exp2) {
+    return
+        strategy.test(
+            exp1, exp2, 'primitiveValue',
+            exp1.primitiveValue, exp2.primitiveValue);
+  }
+
+  @override
+  bool visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp1,
+                                BoolFromEnvironmentConstantExpression exp2) {
+    return
+        strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) &&
+        strategy.testConstants(
+            exp1, exp2, 'defaultValue',
+            exp1.defaultValue, exp2.defaultValue);
+  }
+
+  @override
+  bool visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp1,
+                               IntFromEnvironmentConstantExpression exp2) {
+    return
+        strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) &&
+        strategy.testConstants(
+            exp1, exp2, 'defaultValue',
+            exp1.defaultValue, exp2.defaultValue);
+  }
+
+  @override
+  bool visitStringFromEnvironment(
+      StringFromEnvironmentConstantExpression exp1,
+      StringFromEnvironmentConstantExpression exp2) {
+    return
+        strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) &&
+        strategy.testConstants(
+            exp1, exp2, 'defaultValue',
+            exp1.defaultValue, exp2.defaultValue);
+  }
+
+  @override
+  bool visitStringLength(StringLengthConstantExpression exp1,
+                    StringLengthConstantExpression exp2) {
+    return
+        strategy.testConstants(
+            exp1, exp2, 'expression',
+            exp1.expression, exp2.expression);
+  }
+
+  @override
+  bool visitDeferred(DeferredConstantExpression exp1,
+                DeferredConstantExpression exp2) {
+    // TODO: implement visitDeferred
+    return true;
+  }
+}
+
+/// Tests the equivalence of [impact1] and [impact2] using [strategy].
+bool testResolutionImpactEquivalence(
+    ResolutionImpact impact1,
+    ResolutionImpact impact2,
+    [TestStrategy strategy = const TestStrategy()]) {
+  return
+      strategy.testSets(
+          impact1, impact2, 'constSymbolNames',
+          impact1.constSymbolNames, impact2.constSymbolNames) &&
+      strategy.testSets(
+          impact1, impact2, 'constantLiterals',
+          impact1.constantLiterals, impact2.constantLiterals,
+          areConstantsEquivalent) &&
+      strategy.testSets(
+          impact1, impact2, 'dynamicUses',
+          impact1.dynamicUses, impact2.dynamicUses,
+          areDynamicUsesEquivalent) &&
+      strategy.testSets(
+          impact1, impact2, 'features',
+          impact1.features, impact2.features) &&
+      strategy.testSets(
+          impact1, impact2, 'listLiterals',
+          impact1.listLiterals, impact2.listLiterals,
+          areListLiteralUsesEquivalent) &&
+      strategy.testSets(
+          impact1, impact2, 'mapLiterals',
+          impact1.mapLiterals, impact2.mapLiterals,
+          areMapLiteralUsesEquivalent) &&
+      strategy.testSets(
+          impact1, impact2, 'staticUses',
+          impact1.staticUses, impact2.staticUses,
+          areStaticUsesEquivalent) &&
+      strategy.testSets(
+          impact1, impact2, 'typeUses',
+          impact1.typeUses, impact2.typeUses,
+          areTypeUsesEquivalent);
+}
diff --git a/pkg/compiler/lib/src/serialization/impact_serialization.dart b/pkg/compiler/lib/src/serialization/impact_serialization.dart
index ef86609..979ec15 100644
--- a/pkg/compiler/lib/src/serialization/impact_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/impact_serialization.dart
@@ -5,26 +5,58 @@
 library dart2js.serialization.impact;
 
 import '../dart_types.dart';
+import '../common/resolution.dart';
+import '../constants/expressions.dart';
 import '../elements/elements.dart';
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
 import '../universe/world_impact.dart';
 import '../universe/use.dart';
+import '../util/enumset.dart';
 
 import 'keys.dart';
 import 'serialization.dart';
 
-/// Visitor that serializes a [WorldImpact] object using an [ObjectEncoder].
+/// Visitor that serializes a [ResolutionImpact] object using an
+/// [ObjectEncoder].
 class ImpactSerializer implements WorldImpactVisitor {
+  final ObjectEncoder objectEncoder;
   final ListEncoder staticUses;
   final ListEncoder dynamicUses;
   final ListEncoder typeUses;
 
   ImpactSerializer(ObjectEncoder objectEncoder)
-      : staticUses = objectEncoder.createList(Key.STATIC_USES),
+      : this.objectEncoder = objectEncoder,
+        staticUses = objectEncoder.createList(Key.STATIC_USES),
         dynamicUses = objectEncoder.createList(Key.DYNAMIC_USES),
         typeUses = objectEncoder.createList(Key.TYPE_USES);
 
+  void serialize(ResolutionImpact resolutionImpact) {
+    resolutionImpact.apply(this);
+    objectEncoder.setStrings(Key.SYMBOLS, resolutionImpact.constSymbolNames);
+    objectEncoder.setConstants(
+        Key.CONSTANTS, resolutionImpact.constantLiterals);
+    objectEncoder.setEnums(Key.FEATURES, resolutionImpact.features);
+    if (resolutionImpact.listLiterals.isNotEmpty) {
+      ListEncoder encoder = objectEncoder.createList(Key.LISTS);
+      for (ListLiteralUse use in resolutionImpact.listLiterals) {
+        ObjectEncoder useEncoder = encoder.createObject();
+        useEncoder.setType(Key.TYPE, use.type);
+        useEncoder.setBool(Key.IS_CONST, use.isConstant);
+        useEncoder.setBool(Key.IS_EMPTY, use.isEmpty);
+      }
+    }
+    if (resolutionImpact.mapLiterals.isNotEmpty) {
+      ListEncoder encoder = objectEncoder.createList(Key.MAPS);
+      for (MapLiteralUse use in resolutionImpact.mapLiterals) {
+        ObjectEncoder useEncoder = encoder.createObject();
+        useEncoder.setType(Key.TYPE, use.type);
+        useEncoder.setBool(Key.IS_CONST, use.isConstant);
+        useEncoder.setBool(Key.IS_EMPTY, use.isEmpty);
+      }
+    }
+  }
+
   @override
   void visitDynamicUse(DynamicUse dynamicUse) {
     ObjectEncoder object = dynamicUses.createObject();
@@ -66,22 +98,47 @@
 }
 
 /// A deserialized [WorldImpact] object.
-class DeserializedWorldImpact extends WorldImpact with WorldImpactBuilder {}
+class DeserializedResolutionImpact extends WorldImpact
+    implements ResolutionImpact {
+  final Iterable<String> constSymbolNames;
+  final Iterable<ConstantExpression> constantLiterals;
+  final Iterable<DynamicUse> dynamicUses;
+  final EnumSet<Feature> _features;
+  final Iterable<ListLiteralUse> listLiterals;
+  final Iterable<MapLiteralUse> mapLiterals;
+  final Iterable<StaticUse> staticUses;
+  final Iterable<TypeUse> typeUses;
+
+  DeserializedResolutionImpact({
+    this.constSymbolNames,
+    this.constantLiterals,
+    this.dynamicUses,
+    EnumSet<Feature> features,
+    this.listLiterals,
+    this.mapLiterals,
+    this.staticUses,
+    this.typeUses})
+      : this._features = features;
+
+  Iterable<Feature> get features => _features.iterable(Feature.values);
+}
 
 class ImpactDeserializer {
   /// Deserializes a [WorldImpact] from [objectDecoder].
-  static WorldImpact deserializeImpact(ObjectDecoder objectDecoder) {
-    DeserializedWorldImpact worldImpact = new DeserializedWorldImpact();
-    ListDecoder staticUses = objectDecoder.getList(Key.STATIC_USES);
-    for (int index = 0; index < staticUses.length; index++) {
-      ObjectDecoder object = staticUses.getObject(index);
+  static ResolutionImpact deserializeImpact(ObjectDecoder objectDecoder) {
+    ListDecoder staticUseDecoder = objectDecoder.getList(Key.STATIC_USES);
+    List<StaticUse> staticUses = <StaticUse>[];
+    for (int index = 0; index < staticUseDecoder.length; index++) {
+      ObjectDecoder object = staticUseDecoder.getObject(index);
       StaticUseKind kind = object.getEnum(Key.KIND, StaticUseKind.values);
       Element element = object.getElement(Key.ELEMENT);
-      worldImpact.registerStaticUse(new StaticUse.internal(element, kind));
+      staticUses.add(new StaticUse.internal(element, kind));
     }
-    ListDecoder dynamicUses = objectDecoder.getList(Key.DYNAMIC_USES);
-    for (int index = 0; index < dynamicUses.length; index++) {
-      ObjectDecoder object = dynamicUses.getObject(index);
+
+    ListDecoder dynamicUseDecoder = objectDecoder.getList(Key.DYNAMIC_USES);
+    List<DynamicUse> dynamicUses = <DynamicUse>[];
+    for (int index = 0; index < dynamicUseDecoder.length; index++) {
+      ObjectDecoder object = dynamicUseDecoder.getObject(index);
       SelectorKind kind = object.getEnum(Key.KIND, SelectorKind.values);
       int argumentCount = object.getInt(Key.ARGUMENTS);
       List<String> namedArguments =
@@ -89,7 +146,7 @@
       String name = object.getString(Key.NAME);
       bool isSetter = object.getBool(Key.IS_SETTER);
       LibraryElement library = object.getElement(Key.LIBRARY, isOptional: true);
-      worldImpact.registerDynamicUse(
+      dynamicUses.add(
           new DynamicUse(
               new Selector(
                   kind,
@@ -97,13 +154,63 @@
                   new CallStructure(argumentCount, namedArguments)),
               null));
     }
-    ListDecoder typeUses = objectDecoder.getList(Key.TYPE_USES);
-    for (int index = 0; index < typeUses.length; index++) {
-      ObjectDecoder object = typeUses.getObject(index);
+
+    ListDecoder typeUseDecoder = objectDecoder.getList(Key.TYPE_USES);
+    List<TypeUse> typeUses = <TypeUse>[];
+    for (int index = 0; index < typeUseDecoder.length; index++) {
+      ObjectDecoder object = typeUseDecoder.getObject(index);
       TypeUseKind kind = object.getEnum(Key.KIND, TypeUseKind.values);
       DartType type = object.getType(Key.TYPE);
-      worldImpact.registerTypeUse(new TypeUse.internal(type, kind));
+      typeUses.add(new TypeUse.internal(type, kind));
     }
-    return worldImpact;
+
+    List<String> constSymbolNames =
+        objectDecoder.getStrings(Key.SYMBOLS, isOptional: true);
+
+    List<ConstantExpression> constantLiterals =
+        objectDecoder.getConstants(Key.CONSTANTS, isOptional: true);
+
+    EnumSet<Feature> features =
+        objectDecoder.getEnums(Key.FEATURES, isOptional: true);
+
+    ListDecoder listLiteralDecoder =
+        objectDecoder.getList(Key.LISTS, isOptional: true);
+    List<ListLiteralUse> listLiterals = const <ListLiteralUse>[];
+    if (listLiteralDecoder != null) {
+      listLiterals = <ListLiteralUse>[];
+      for (int i = 0; i < listLiteralDecoder.length; i++) {
+        ObjectDecoder useDecoder = listLiteralDecoder.getObject(i);
+        DartType type = useDecoder.getType(Key.TYPE);
+        bool isConstant = useDecoder.getBool(Key.IS_CONST);
+        bool isEmpty = useDecoder.getBool(Key.IS_EMPTY);
+        listLiterals.add(new ListLiteralUse(
+            type, isConstant: isConstant, isEmpty: isEmpty));
+      }
+    }
+
+    ListDecoder mapLiteralDecoder =
+        objectDecoder.getList(Key.MAPS, isOptional: true);
+    List<MapLiteralUse> mapLiterals = const <MapLiteralUse>[];
+    if (mapLiteralDecoder != null) {
+      mapLiterals = <MapLiteralUse>[];
+      for (int i = 0; i < mapLiteralDecoder.length; i++) {
+        ObjectDecoder useDecoder = mapLiteralDecoder.getObject(i);
+        DartType type = useDecoder.getType(Key.TYPE);
+        bool isConstant = useDecoder.getBool(Key.IS_CONST);
+        bool isEmpty = useDecoder.getBool(Key.IS_EMPTY);
+        mapLiterals.add(new MapLiteralUse(
+            type, isConstant: isConstant, isEmpty: isEmpty));
+      }
+    }
+
+    return new DeserializedResolutionImpact(
+        constSymbolNames: constSymbolNames,
+        constantLiterals: constantLiterals,
+        dynamicUses: dynamicUses,
+        features: features,
+        listLiterals: listLiterals,
+        mapLiterals: mapLiterals,
+        staticUses: staticUses,
+        typeUses: typeUses);
   }
 }
diff --git a/pkg/compiler/lib/src/serialization/keys.dart b/pkg/compiler/lib/src/serialization/keys.dart
index 8882b1d..7758be6 100644
--- a/pkg/compiler/lib/src/serialization/keys.dart
+++ b/pkg/compiler/lib/src/serialization/keys.dart
@@ -10,6 +10,7 @@
   static const Key ARGUMENTS = const Key('arguments');
   static const Key BOUND = const Key('bound');
   static const Key CALL_STRUCTURE = const Key('callStructure');
+  static const Key CALL_TYPE = const Key('callType');
   static const Key CANONICAL_URI = const Key('canonicalUri');
   static const Key CLASS = const Key('class');
   static const Key COMPILATION_UNIT = const Key('compilation-unit');
@@ -29,6 +30,7 @@
   static const Key EXPORT_SCOPE = const Key('export-scope');
   static const Key EXPRESSION = const Key('expression');
   static const Key FALSE = const Key('false');
+  static const Key FEATURES = const Key('features');
   static const Key FIELD = const Key('field');
   static const Key FIELDS = const Key('fields');
   static const Key FUNCTION = const Key('function');
@@ -42,6 +44,7 @@
   static const Key IS_ABSTRACT = const Key('isAbstract');
   static const Key IS_CONST = const Key('isConst');
   static const Key IS_DEFERRED = const Key('isDeferred');
+  static const Key IS_EMPTY = const Key('isEmpty');
   static const Key IS_EXTERNAL = const Key('isExternal');
   static const Key IS_FINAL = const Key('isFinal');
   static const Key IS_NAMED = const Key('isNamed');
@@ -58,6 +61,8 @@
   static const Key LIBRARY = const Key('library');
   static const Key LIBRARY_DEPENDENCY = const Key('library-dependency');
   static const Key LIBRARY_NAME = const Key('library-name');
+  static const Key LISTS = const Key('lists');
+  static const Key MAPS = const Key('maps');
   static const Key MEMBERS = const Key('members');
   static const Key MIXIN = const Key('mixin');
   static const Key MIXINS = const Key('mixins');
@@ -78,6 +83,7 @@
   static const Key STATIC_USES = const Key('static-uses');
   static const Key SUPERTYPE = const Key('supertype');
   static const Key SUPERTYPES = const Key('supertypes');
+  static const Key SYMBOLS = const Key('symbols');
   static const Key TAGS = const Key('tags');
   static const Key TRUE = const Key('true');
   static const Key TYPE = const Key('type');
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index 4a0d17e..7c02c7a 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -309,10 +309,19 @@
 
 class AbstractFieldElementZ extends ElementZ implements AbstractFieldElement {
   final String name;
-  final FunctionElement getter;
-  final FunctionElement setter;
+  final GetterElementZ getter;
+  final SetterElementZ setter;
 
-  AbstractFieldElementZ(this.name, this.getter, this.setter);
+  AbstractFieldElementZ(this.name, this.getter, this.setter) {
+    if (getter != null) {
+      getter.abstractField = this;
+      getter.setter = setter;
+    }
+    if (setter != null) {
+      setter.abstractField = this;
+      setter.getter = getter;
+    }
+  }
 
   FunctionElement get _canonicalElement => getter != null ? getter : setter;
 
@@ -738,7 +747,6 @@
 }
 
 abstract class ClassElementMixin implements ElementZ, ClassElement {
-
   InterfaceType _createType(List<DartType> typeArguments) {
     return new InterfaceType(this, typeArguments);
   }
@@ -770,11 +778,6 @@
   bool get hasLocalScopeMembers => _unsupported('hasLocalScopeMembers');
 
   @override
-  bool implementsFunction(CoreClasses coreClasses) {
-    return _unsupported('implementsFunction');
-  }
-
-  @override
   bool get isEnumClass => false;
 
   @override
@@ -818,6 +821,7 @@
   DartType _supertype;
   OrderedTypeSet _allSupertypesAndSelf;
   Link<DartType> _interfaces;
+  FunctionType _callType;
 
   ClassElementZ(ObjectDecoder decoder)
       : super(decoder);
@@ -851,6 +855,7 @@
         _allSupertypesAndSelf =
             new OrderedTypeSetBuilder(this)
               .createOrderedTypeSet(_supertype, _interfaces);
+        _callType = _decoder.getType(Key.CALL_TYPE, isOptional: true);
       }
     }
   }
@@ -892,6 +897,12 @@
 
   @override
   bool get isUnnamedMixinApplication => false;
+
+  @override
+  FunctionType get callType {
+    _ensureSuperHierarchy();
+    return _callType;
+  }
 }
 
 abstract class MixinApplicationElementMixin
@@ -1349,7 +1360,7 @@
 
   @override
   accept(ElementVisitor visitor, arg) {
-    return visitor.visitFunctionElement(this, arg);
+    return visitor.visitMethodElement(this, arg);
   }
 
   @override
@@ -1422,7 +1433,7 @@
 
   @override
   accept(ElementVisitor visitor, arg) {
-    return visitor.visitFunctionElement(this, arg);
+    return visitor.visitLocalFunctionElement(this, arg);
   }
 
   @override
@@ -1436,7 +1447,10 @@
          ParametersMixin,
          TypedElementMixin,
          MemberElementMixin
-    implements FunctionElement {
+    implements GetterElement {
+
+  AbstractFieldElement abstractField;
+  SetterElement setter;
 
   GetterElementZ(ObjectDecoder decoder)
       : super(decoder);
@@ -1446,7 +1460,7 @@
 
   @override
   accept(ElementVisitor visitor, arg) {
-    return visitor.visitFunctionElement(this, arg);
+    return visitor.visitGetterElement(this, arg);
   }
 }
 
@@ -1474,7 +1488,10 @@
          ParametersMixin,
          TypedElementMixin,
          MemberElementMixin
-    implements FunctionElement {
+    implements SetterElement {
+
+  AbstractFieldElement abstractField;
+  GetterElement getter;
 
   SetterElementZ(ObjectDecoder decoder)
       : super(decoder);
@@ -1484,7 +1501,7 @@
 
   @override
   accept(ElementVisitor visitor, arg) {
-    return visitor.visitFunctionElement(this, arg);
+    return visitor.visitSetterElement(this, arg);
   }
 }
 
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index a336321..6f046d4 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -7,6 +7,7 @@
 import '../elements/elements.dart';
 import '../constants/expressions.dart';
 import '../dart_types.dart';
+import '../util/enumset.dart';
 
 import 'constant_serialization.dart';
 import 'element_serialization.dart';
@@ -103,6 +104,17 @@
     _map[key] = new EnumValue(value);
   }
 
+  /// Maps the [key] entry to the set of enum [values] in the encoded object.
+  void setEnums(K key, Iterable values) {
+    setEnumSet(key, new EnumSet.fromValues(values));
+  }
+
+  /// Maps the [key] entry to the enum [set] in the encoded object.
+  void setEnumSet(K key, EnumSet set) {
+    _checkKey(key);
+    _map[key] = new IntValue(set.value);
+  }
+
   /// Maps the [key] entry to the [element] in the encoded object.
   void setElement(K key, Element element) {
     _checkKey(key);
@@ -321,6 +333,22 @@
     return enumValues[value];
   }
 
+  /// Returns the set of enum values associated with [key] in the decoded
+  /// object.
+  ///
+  /// If no value is associated with [key], then if [isOptional] is `true`,
+  /// [defaultValue] is returned, otherwise an exception is thrown.
+  EnumSet getEnums(K key, {bool isOptional: false}) {
+    int value = _map[_getKeyValue(key)];
+    if (value == null) {
+      if (isOptional) {
+        return const EnumSet.fixed(0);
+      }
+      throw new StateError("enum values '$key' not found in $_map.");
+    }
+    return new EnumSet.fixed(value);
+  }
+
   /// Returns the [Element] value associated with [key] in the decoded object.
   ///
   /// If no value is associated with [key], then if [isOptional] is `true`,
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 95059fa..b7119eca 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -5,6 +5,7 @@
 library dart2js.serialization.task;
 
 import '../common/resolution.dart' show
+    ResolutionImpact,
     ResolutionWorkItem;
 import '../common/tasks.dart' show
     CompilerTask;
@@ -89,5 +90,6 @@
 abstract class DeserializerSystem {
   LibraryElement readLibrary(Uri resolvedUri);
   bool isDeserialized(Element element);
+  ResolutionImpact getResolutionImpact(Element element);
   WorldImpact computeWorldImpact(Element element);
 }
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 8c8f78c..ad5905d 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -1037,6 +1037,7 @@
 class SsaBuilder extends ast.Visitor
     with BaseImplementationOfCompoundsMixin,
          BaseImplementationOfSetIfNullsMixin,
+         BaseImplementationOfSuperIndexSetIfNullMixin,
          SemanticSendResolvedMixin,
          NewBulkMixin,
          ErrorBulkMixin
@@ -7108,6 +7109,32 @@
   }
 
   @override
+  handleSuperIndexSetIfNull(
+      ast.SendSet node,
+      Element indexFunction,
+      Element indexSetFunction,
+      ast.Node index,
+      ast.Node rhs,
+      arg,
+      {bool isGetterValid,
+       bool isSetterValid}) {
+    handleCompoundSendSet(node);
+  }
+
+  @override
+  visitIndexSetIfNull(
+      ast.SendSet node,
+      ast.Node receiver,
+      ast.Node index,
+      ast.Node rhs,
+      arg,
+      {bool isGetterValid,
+       bool isSetterValid}) {
+    generateIsDeferredLoadedCheckOfSend(node);
+    handleIndexSendSet(node);
+  }
+
+  @override
   handleTypeLiteralConstantSetIfNulls(
       ast.SendSet node,
       ConstantExpression constant,
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index 818a6d7..bed1d60 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -181,6 +181,8 @@
     _directSubclasses = _directSubclasses.prepend(subclass);
   }
 
+  Iterable<ClassHierarchyNode> get directSubclasses => _directSubclasses;
+
   /// Returns `true` if [other] is contained in the subtree of this node.
   ///
   /// This means that [other] is a subclass of [cls].
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index 014ceef..8bef9fa 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -62,18 +62,27 @@
                     this.memberName,
                     this.callStructure,
                     this.hashCode) {
-    assert(kind == SelectorKind.INDEX ||
-           (memberName != Names.INDEX_NAME &&
-            memberName != Names.INDEX_SET_NAME));
-    assert(kind == SelectorKind.OPERATOR ||
-           kind == SelectorKind.INDEX ||
-           !Elements.isOperatorName(memberName.text) ||
-           identical(memberName.text, '??'));
-    assert(kind == SelectorKind.CALL ||
-           kind == SelectorKind.GETTER ||
-           kind == SelectorKind.SETTER ||
-           Elements.isOperatorName(memberName.text) ||
-           identical(memberName.text, '??'));
+    assert(invariant(NO_LOCATION_SPANNABLE,
+        kind == SelectorKind.INDEX ||
+        (memberName != Names.INDEX_NAME &&
+         memberName != Names.INDEX_SET_NAME),
+        message: "kind=$kind,memberName=$memberName,"
+                 "callStructure:$callStructure"));
+    assert(invariant(NO_LOCATION_SPANNABLE,
+        kind == SelectorKind.OPERATOR ||
+        kind == SelectorKind.INDEX ||
+        !Elements.isOperatorName(memberName.text) ||
+        memberName.text == '??',
+        message: "kind=$kind,memberName=$memberName,"
+                 "callStructure:$callStructure"));
+    assert(invariant(NO_LOCATION_SPANNABLE,
+        kind == SelectorKind.CALL ||
+        kind == SelectorKind.GETTER ||
+        kind == SelectorKind.SETTER ||
+        Elements.isOperatorName(memberName.text) ||
+        memberName.text == '??',
+        message: "kind=$kind,memberName=$memberName,"
+                 "callStructure:$callStructure"));
   }
 
   // TODO(johnniwinther): Extract caching.
diff --git a/pkg/dart2js_incremental/lib/dart2js_incremental.dart b/pkg/dart2js_incremental/lib/dart2js_incremental.dart
index ea42c5a..86ef905 100644
--- a/pkg/dart2js_incremental/lib/dart2js_incremental.dart
+++ b/pkg/dart2js_incremental/lib/dart2js_incremental.dart
@@ -18,9 +18,11 @@
     CompilerDiagnostics,
     CompilerInput,
     CompilerOutput,
-    CompilerOptions,
     Diagnostic;
 
+import 'package:compiler/src/options.dart' show
+    CompilerOptions;
+
 import 'package:compiler/src/null_compiler_output.dart' show
     NullCompilerOutput;
 
diff --git a/pkg/dart2js_incremental/lib/library_updater.dart b/pkg/dart2js_incremental/lib/library_updater.dart
index b8a5c62..a5cdc02 100644
--- a/pkg/dart2js_incremental/lib/library_updater.dart
+++ b/pkg/dart2js_incremental/lib/library_updater.dart
@@ -330,10 +330,10 @@
       Token token = new Scanner(_entrySourceFiles[library]).tokenize();
       _entryUnitTokens[library] = token;
       // Using two parsers to only create the nodes we want ([LibraryTag]).
-      Parser parser = new Parser(new Listener());
+      Parser parser = new Parser(new Listener(), compiler.options);
       NodeListener listener = new NodeListener(
           compiler, library.entryCompilationUnit);
-      Parser nodeParser = new Parser(listener);
+      Parser nodeParser = new Parser(listener, compiler.options);
       Iterator<LibraryTag> tags = library.tags.iterator;
       while (token.kind != EOF_TOKEN) {
         token = parser.parseMetadataStar(token);
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 04d7097..20b2a8a 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -280,7 +280,13 @@
   }
   set_sources_assignment_filter(custom_sources_filter)
 
-  defines = [ "DART_IO_SECURE_SOCKET_DISABLED" ]
+  if (is_mac || is_ios) {
+    libs = [
+      "Security.framework",
+    ]
+  } else {
+    defines = [ "DART_IO_SECURE_SOCKET_DISABLED" ]
+  }
 
   sources = io_impl_sources_gypi.sources + builtin_impl_sources_gypi.sources
   sources += [
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 9a2f9ec..764c00e 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -498,10 +498,12 @@
 
 
 Dart_Handle DartUtils::LoadScript(const char* script_uri) {
+  Dart_TimelineEvent("LoadScript",
+                     Dart_TimelineGetMicros(),
+                     Dart_GetMainPortId(),
+                     Dart_Timeline_Event_Async_Begin,
+                     0, NULL, NULL);
   Dart_Handle uri = Dart_NewStringFromCString(script_uri);
-  IsolateData* isolate_data =
-      reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData());
-  Dart_TimelineAsyncBegin("LoadScript", &(isolate_data->load_async_id));
   return LoadDataAsync_Invoke(Dart_Null(), uri, Dart_Null());
 }
 
diff --git a/runtime/bin/io_impl_sources.gypi b/runtime/bin/io_impl_sources.gypi
index af5c712..ccb050c 100644
--- a/runtime/bin/io_impl_sources.gypi
+++ b/runtime/bin/io_impl_sources.gypi
@@ -51,6 +51,7 @@
     'secure_socket.h',
     'secure_socket_boringssl.cc',
     'secure_socket_boringssl.h',
+    'secure_socket_ios.cc',
     'secure_socket_macos.cc',
     'secure_socket_macos.h',
     'secure_socket_unsupported.cc',
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index 7ff2bfa..6532fbc 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -27,7 +27,6 @@
         package_root(NULL),
         packages_file(NULL),
         udp_receive_buffer(NULL),
-        load_async_id(-1),
         builtin_lib_(NULL) {
     if (package_root != NULL) {
       ASSERT(packages_file == NULL);
@@ -67,7 +66,6 @@
   char* package_root;
   char* packages_file;
   uint8_t* udp_receive_buffer;
-  int64_t load_async_id;
 
  private:
   Dart_Handle builtin_lib_;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 8d58c70..fdf6248 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -840,9 +840,11 @@
     result = Dart_RunLoop();
     CHECK_RESULT(result);
 
-    if (isolate_data->load_async_id >= 0) {
-      Dart_TimelineAsyncEnd("LoadScript", isolate_data->load_async_id);
-    }
+    Dart_TimelineEvent("LoadScript",
+                       Dart_TimelineGetMicros(),
+                       Dart_GetMainPortId(),
+                       Dart_Timeline_Event_Async_End,
+                       0, NULL, NULL);
 
     result = DartUtils::SetupIOLibrary(script_uri);
     CHECK_RESULT(result);
@@ -1202,6 +1204,7 @@
   snprintf(*isolate_snapshot_fname, len + 1, "%s.%s", filename, kIsolateSuffix);
 }
 
+
 static void GenerateFullSnapshot() {
   // Create a full snapshot of the script.
   Dart_Handle result;
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 2641ac1..24c83fd 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -76,14 +76,16 @@
 
 char** Platform::Environment(intptr_t* count) {
 #if TARGET_OS_IOS
-  // TODO(iposva): On Mac (desktop), _NSGetEnviron() is used to access the
-  // environ from shared libraries or bundles. This is present in crt_externs.h
-  // which is unavailable on iOS. On iOS, everything is statically linked for
-  // now. So arguably, accessing the environ directly with a "extern char
-  // **environ" will work. But this approach is brittle as the target with this
-  // CU could be a dynamic framework (introduced in iOS 8). A more elegant
-  // approach needs to be devised.
-  return NULL;
+  // TODO(zra,chinmaygarde): On iOS, environment variables are seldom used. Wire
+  // this up if someone needs it. In the meantime, we return an empty array.
+  char** result;
+  result = reinterpret_cast<char**>(Dart_ScopeAllocate(1 * sizeof(*result)));
+  if (result == NULL) {
+    return NULL;
+  }
+  result[0] = NULL;
+  *count = 0;
+  return result;
 #else
   // Using environ directly is only safe as long as we do not
   // provide access to modifying environment variables.
diff --git a/runtime/bin/secure_socket_ios.cc b/runtime/bin/secure_socket_ios.cc
new file mode 100644
index 0000000..76da230
--- /dev/null
+++ b/runtime/bin/secure_socket_ios.cc
@@ -0,0 +1,1340 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED)
+
+#include "platform/globals.h"
+#if TARGET_OS_IOS
+
+#include "bin/secure_socket.h"
+#include "bin/secure_socket_macos.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/syslimits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecureTransport.h>
+#include <Security/Security.h>
+
+#include "bin/builtin.h"
+#include "bin/dartutils.h"
+#include "bin/lockers.h"
+#include "bin/log.h"
+#include "bin/socket.h"
+#include "bin/thread.h"
+#include "bin/utils.h"
+
+#include "platform/text_buffer.h"
+#include "platform/utils.h"
+
+#include "include/dart_api.h"
+
+// Return the error from the containing function if handle is an error handle.
+#define RETURN_IF_ERROR(handle)                                                \
+  {                                                                            \
+    Dart_Handle __handle = handle;                                             \
+    if (Dart_IsError((__handle))) {                                            \
+      return __handle;                                                         \
+    }                                                                          \
+  }
+
+namespace dart {
+namespace bin {
+
+static const int kSSLFilterNativeFieldIndex = 0;
+static const int kSecurityContextNativeFieldIndex = 0;
+static const int kX509NativeFieldIndex = 0;
+
+static const bool SSL_LOG_STATUS = false;
+static const bool SSL_LOG_DATA = false;
+static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000;
+
+// SSLCertContext wraps the certificates needed for a SecureTransport
+// connection. Fields are protected by the mutex_ field, and may only be set
+// once. This is to allow access by both the Dart thread and the IOService
+// thread. Setters return false if the field was already set.
+class SSLCertContext {
+ public:
+  SSLCertContext() :
+      mutex_(new Mutex()),
+      trusted_certs_(NULL),
+      trust_builtin_(false) {}
+
+  ~SSLCertContext() {
+    delete mutex_;
+    if (trusted_certs_ != NULL) {
+      CFRelease(trusted_certs_);
+    }
+  }
+
+  CFMutableArrayRef trusted_certs() {
+    MutexLocker m(mutex_);
+    return trusted_certs_;
+  }
+  void add_trusted_cert(SecCertificateRef trusted_cert) {
+    // Takes ownership of trusted_cert.
+    MutexLocker m(mutex_);
+    if (trusted_certs_ == NULL) {
+      trusted_certs_ = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    }
+    CFArrayAppendValue(trusted_certs_, trusted_cert);
+    CFRelease(trusted_cert);  // trusted_cert is retained by the array.
+  }
+
+  bool trust_builtin() {
+    MutexLocker m(mutex_);
+    return trust_builtin_;
+  }
+  void set_trust_builtin(bool trust_builtin) {
+    MutexLocker m(mutex_);
+    trust_builtin_ = trust_builtin;
+  }
+
+ private:
+  // The context is accessed both by Dart code and the IOService. This mutex
+  // protects all fields.
+  Mutex* mutex_;
+  CFMutableArrayRef trusted_certs_;
+  bool trust_builtin_;
+
+  DISALLOW_COPY_AND_ASSIGN(SSLCertContext);
+};
+
+// Handle an error reported from the SecureTransport library.
+static void ThrowIOException(OSStatus status,
+                             const char* exception_type,
+                             const char* message) {
+  TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE);
+  status_message.Printf("OSStatus = %ld: https://www.osstatus.com",
+      static_cast<intptr_t>(status));
+  OSError os_error_struct(status, status_message.buf(), OSError::kBoringSSL);
+  Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
+  Dart_Handle exception =
+      DartUtils::NewDartIOException(exception_type, message, os_error);
+  ASSERT(!Dart_IsError(exception));
+  Dart_ThrowException(exception);
+  UNREACHABLE();
+}
+
+
+static void CheckStatus(OSStatus status,
+                        const char* type,
+                        const char* message) {
+  if (status == noErr) {
+    return;
+  }
+  ThrowIOException(status, type, message);
+}
+
+
+static SSLFilter* GetFilter(Dart_NativeArguments args) {
+  SSLFilter* filter;
+  Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
+  ASSERT(Dart_IsInstance(dart_this));
+  ThrowIfError(Dart_GetNativeInstanceField(
+      dart_this,
+      kSSLFilterNativeFieldIndex,
+      reinterpret_cast<intptr_t*>(&filter)));
+  return filter;
+}
+
+
+static void DeleteFilter(void* isolate_data,
+                         Dart_WeakPersistentHandle handle,
+                         void* context_pointer) {
+  SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer);
+  delete filter;
+}
+
+
+static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) {
+  ASSERT(filter != NULL);
+  const int approximate_size_of_filter = 1500;
+  Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
+  RETURN_IF_ERROR(dart_this);
+  ASSERT(Dart_IsInstance(dart_this));
+  Dart_Handle err = Dart_SetNativeInstanceField(
+      dart_this,
+      kSSLFilterNativeFieldIndex,
+      reinterpret_cast<intptr_t>(filter));
+  RETURN_IF_ERROR(err);
+  Dart_NewWeakPersistentHandle(dart_this,
+                               reinterpret_cast<void*>(filter),
+                               approximate_size_of_filter,
+                               DeleteFilter);
+  return Dart_Null();
+}
+
+
+static SSLCertContext* GetSecurityContext(Dart_NativeArguments args) {
+  SSLCertContext* context;
+  Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
+  ASSERT(Dart_IsInstance(dart_this));
+  ThrowIfError(Dart_GetNativeInstanceField(
+      dart_this,
+      kSecurityContextNativeFieldIndex,
+      reinterpret_cast<intptr_t*>(&context)));
+  return context;
+}
+
+
+static void DeleteCertContext(void* isolate_data,
+                              Dart_WeakPersistentHandle handle,
+                              void* context_pointer) {
+  SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer);
+  delete context;
+}
+
+
+static Dart_Handle SetSecurityContext(Dart_NativeArguments args,
+                                      SSLCertContext* context) {
+  const int approximate_size_of_context = 1500;
+  Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
+  RETURN_IF_ERROR(dart_this);
+  ASSERT(Dart_IsInstance(dart_this));
+  Dart_Handle err = Dart_SetNativeInstanceField(
+      dart_this,
+      kSecurityContextNativeFieldIndex,
+      reinterpret_cast<intptr_t>(context));
+  RETURN_IF_ERROR(err);
+  Dart_NewWeakPersistentHandle(dart_this,
+                               context,
+                               approximate_size_of_context,
+                               DeleteCertContext);
+  return Dart_Null();
+}
+
+
+static void ReleaseCertificate(void* isolate_data,
+                               Dart_WeakPersistentHandle handle,
+                               void* context_pointer) {
+  SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(context_pointer);
+  CFRelease(cert);
+}
+
+
+static Dart_Handle WrappedX509Certificate(SecCertificateRef certificate) {
+  const intptr_t approximate_size_of_certificate = 1500;
+  if (certificate == NULL) {
+    return Dart_Null();
+  }
+  Dart_Handle x509_type =
+      DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate");
+  if (Dart_IsError(x509_type)) {
+    return x509_type;
+  }
+  Dart_Handle arguments[] = { NULL };
+
+  Dart_Handle result =
+      Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments);
+  if (Dart_IsError(result)) {
+    return result;
+  }
+  ASSERT(Dart_IsInstance(result));
+
+  // CFRetain in case the returned Dart object outlives the SecurityContext.
+  // CFRelease is in the Dart object's finalizer
+  CFRetain(certificate);
+  Dart_NewWeakPersistentHandle(result,
+                               reinterpret_cast<void*>(certificate),
+                               approximate_size_of_certificate,
+                               ReleaseCertificate);
+
+  Dart_Handle status = Dart_SetNativeInstanceField(
+      result,
+      kX509NativeFieldIndex,
+      reinterpret_cast<intptr_t>(certificate));
+  if (Dart_IsError(status)) {
+    return status;
+  }
+  return result;
+}
+
+
+void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) {
+  Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
+  SSLFilter* filter = new SSLFilter();  // Deleted in DeleteFilter finalizer.
+  Dart_Handle err = SetFilter(args, filter);
+  if (Dart_IsError(err)) {
+    delete filter;
+    Dart_PropagateError(err);
+  }
+  err = filter->Init(dart_this);
+  if (Dart_IsError(err)) {
+    // The finalizer was set up by SetFilter. It will delete `filter` if there
+    // is an error.
+    filter->Destroy();
+    Dart_PropagateError(err);
+  }
+}
+
+
+void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) {
+  Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
+  Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
+  Dart_Handle context_object = ThrowIfError(Dart_GetNativeArgument(args, 2));
+  bool is_server = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3));
+  bool request_client_certificate =
+      DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
+  bool require_client_certificate =
+      DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5));
+
+  const char* host_name = NULL;
+  // TODO(whesse): Is truncating a Dart string containing \0 what we want?
+  ThrowIfError(Dart_StringToCString(host_name_object, &host_name));
+
+  SSLCertContext* context = NULL;
+  if (!Dart_IsNull(context_object)) {
+    ThrowIfError(Dart_GetNativeInstanceField(
+        context_object,
+        kSecurityContextNativeFieldIndex,
+        reinterpret_cast<intptr_t*>(&context)));
+  }
+
+  GetFilter(args)->Connect(dart_this,
+                           host_name,
+                           context,
+                           is_server,
+                           request_client_certificate,
+                           require_client_certificate);
+}
+
+
+void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) {
+  SSLFilter* filter = GetFilter(args);
+  // The SSLFilter is deleted in the finalizer for the Dart object created by
+  // SetFilter. There is no need to NULL-out the native field for the SSLFilter
+  // here because the SSLFilter won't be deleted until the finalizer for the
+  // Dart object runs while the Dart object is being GCd. This approach avoids a
+  // leak if Destroy isn't called, and avoids a NULL-dereference if Destroy is
+  // called more than once.
+  filter->Destroy();
+}
+
+
+void FUNCTION_NAME(SecureSocket_Handshake)(Dart_NativeArguments args) {
+  OSStatus status = GetFilter(args)->CheckHandshake();
+  CheckStatus(status, "HandshakeException", "Handshake error");
+}
+
+
+void FUNCTION_NAME(SecureSocket_GetSelectedProtocol)(
+    Dart_NativeArguments args) {
+  Dart_SetReturnValue(args, Dart_Null());
+}
+
+
+void FUNCTION_NAME(SecureSocket_Renegotiate)(Dart_NativeArguments args) {
+  bool use_session_cache =
+      DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1));
+  bool request_client_certificate =
+      DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 2));
+  bool require_client_certificate =
+      DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3));
+  GetFilter(args)->Renegotiate(use_session_cache,
+                               request_client_certificate,
+                               require_client_certificate);
+}
+
+
+void FUNCTION_NAME(SecureSocket_RegisterHandshakeCompleteCallback)(
+    Dart_NativeArguments args) {
+  Dart_Handle handshake_complete =
+      ThrowIfError(Dart_GetNativeArgument(args, 1));
+  if (!Dart_IsClosure(handshake_complete)) {
+    Dart_ThrowException(DartUtils::NewDartArgumentError(
+        "Illegal argument to RegisterHandshakeCompleteCallback"));
+  }
+  GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete);
+}
+
+
+void FUNCTION_NAME(SecureSocket_RegisterBadCertificateCallback)(
+    Dart_NativeArguments args) {
+  Dart_Handle callback =
+      ThrowIfError(Dart_GetNativeArgument(args, 1));
+  if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) {
+    Dart_ThrowException(DartUtils::NewDartArgumentError(
+        "Illegal argument to RegisterBadCertificateCallback"));
+  }
+  GetFilter(args)->RegisterBadCertificateCallback(callback);
+}
+
+
+void FUNCTION_NAME(SecureSocket_PeerCertificate)(Dart_NativeArguments args) {
+  Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate());
+}
+
+
+void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) {
+  intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args));
+  Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer));
+}
+
+
+void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) {
+  SSLCertContext* cert_context = new SSLCertContext();
+  // cert_context deleted in DeleteCertContext finalizer.
+  Dart_Handle err = SetSecurityContext(args, cert_context);
+  if (Dart_IsError(err)) {
+    delete cert_context;
+    Dart_PropagateError(err);
+  }
+}
+
+
+void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
+    Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartUnsupportedError(
+      "SecurityContext.usePrivateKeyBytes is not yet implemented."));
+}
+
+
+void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
+    Dart_NativeArguments args) {
+  SSLCertContext* context = GetSecurityContext(args);
+
+  OSStatus status = noErr;
+  SecCertificateRef cert = NULL;
+  {
+    ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1)));
+    CFDataRef cfdata = CFDataCreateWithBytesNoCopy(
+        NULL, buffer.get(), buffer.length(), kCFAllocatorNull);
+    cert = SecCertificateCreateWithData(NULL, cfdata);
+    CFRelease(cfdata);
+  }
+
+  // Add the certs to the context.
+  if (cert != NULL) {
+    context->add_trusted_cert(cert);
+  } else {
+    status = errSSLBadCert;
+  }
+  CheckStatus(status, "TlsException", "Failure in setTrustedCertificatesBytes");
+}
+
+
+void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) {
+  Dart_SetReturnValue(args, Dart_NewBoolean(false));
+}
+
+
+void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
+    Dart_NativeArguments args) {
+  SSLCertContext* context = GetSecurityContext(args);
+  context->set_trust_builtin(true);
+}
+
+
+void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
+    Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartUnsupportedError(
+      "SecurityContext.useCertificateChainBytes is not yet implemented."));
+}
+
+
+void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
+    Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartUnsupportedError(
+      "SecurityContext.setClientAuthoritiesBytes is not yet implemented."));
+}
+
+
+void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
+    Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartUnsupportedError(
+      "ALPN is not supported on this platform"));
+}
+
+
+void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartUnsupportedError(
+      "X509Certificate.subject is not yet implemented."));
+}
+
+
+void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartUnsupportedError(
+      "X509Certificate.issuer is not supported on this platform."));
+}
+
+
+void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartUnsupportedError(
+      "X509Certificate.startValidity is not supported on this platform."));
+}
+
+
+void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) {
+    Dart_ThrowException(DartUtils::NewDartUnsupportedError(
+      "X509Certificate.endValidity is not supported on this platform."));
+}
+
+
+// Pushes data through the SSL filter, reading and writing from circular
+// buffers shared with Dart. Called from the IOService thread.
+//
+// The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to
+// pass encrypted and plaintext data to and from the C++ SSLFilter object.
+//
+// ProcessFilter is called with a CObject array containing the pointer to
+// the SSLFilter, encoded as an int, and the start and end positions of the
+// valid data in the four circular buffers.  The function only reads from
+// the valid data area of the input buffers, and only writes to the free
+// area of the output buffers.  The function returns the new start and end
+// positions in the buffers, but it only updates start for input buffers, and
+// end for output buffers.  Therefore, the Dart thread can simultaneously
+// write to the free space and end pointer of input buffers, and read from
+// the data space of output buffers, and modify the start pointer.
+//
+// When ProcessFilter returns, the Dart thread is responsible for combining
+// the updated pointers from Dart and C++, to make the new valid state of
+// the circular buffer.
+CObject* SSLFilter::ProcessFilterRequest(const CObjectArray& request) {
+  CObjectIntptr filter_object(request[0]);
+  SSLFilter* filter = reinterpret_cast<SSLFilter*>(filter_object.Value());
+  bool in_handshake = CObjectBool(request[1]).Value();
+  intptr_t starts[SSLFilter::kNumBuffers];
+  intptr_t ends[SSLFilter::kNumBuffers];
+  for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) {
+    starts[i] = CObjectInt32(request[2 * i + 2]).Value();
+    ends[i] = CObjectInt32(request[2 * i + 3]).Value();
+  }
+
+  OSStatus status = filter->ProcessAllBuffers(starts, ends, in_handshake);
+  if (status == noErr) {
+    CObjectArray* result = new CObjectArray(
+        CObject::NewArray(SSLFilter::kNumBuffers * 2));
+    for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) {
+      result->SetAt(2 * i, new CObjectInt32(CObject::NewInt32(starts[i])));
+      result->SetAt(2 * i + 1, new CObjectInt32(CObject::NewInt32(ends[i])));
+    }
+    return result;
+  } else {
+    TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE);
+    status_message.Printf("OSStatus = %ld: https://www.osstatus.com",
+        static_cast<intptr_t>(status));
+    CObjectArray* result = new CObjectArray(CObject::NewArray(2));
+    result->SetAt(0, new CObjectInt32(CObject::NewInt32(status)));
+    result->SetAt(1, new CObjectString(CObject::NewString(
+        status_message.buf())));
+    return result;
+  }
+}
+
+
+// Usually buffer_starts_ and buffer_ends_ are populated by ProcessAllBuffers,
+// called from ProcessFilterRequest, called from the IOService thread.
+// However, the first call to SSLHandshake comes from the Dart thread, and so
+// doesn't go through there. This results in calls to SSLReadCallback and
+// SSLWriteCallback in which buffer_starts_ and buffer_ends_ haven't been set
+// up. In that case, since we're coming from Dart anyway, we can access the
+// fieds directly from the Dart objects.
+intptr_t SSLFilter::GetBufferStart(intptr_t idx) const {
+  if (buffer_starts_[idx] != NULL) {
+    return *buffer_starts_[idx];
+  }
+  Dart_Handle buffer_handle =
+      ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx]));
+  Dart_Handle start_handle =
+      ThrowIfError(Dart_GetField(buffer_handle, DartUtils::NewString("start")));
+  int64_t start = DartUtils::GetIntegerValue(start_handle);
+  return static_cast<intptr_t>(start);
+}
+
+
+intptr_t SSLFilter::GetBufferEnd(intptr_t idx) const {
+  if (buffer_ends_[idx] != NULL) {
+    return *buffer_ends_[idx];
+  }
+  Dart_Handle buffer_handle =
+      ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx]));
+  Dart_Handle end_handle =
+      ThrowIfError(Dart_GetField(buffer_handle, DartUtils::NewString("end")));
+  int64_t end = DartUtils::GetIntegerValue(end_handle);
+  return static_cast<intptr_t>(end);
+}
+
+
+void SSLFilter::SetBufferStart(intptr_t idx, intptr_t value) {
+  if (buffer_starts_[idx] != NULL) {
+    *buffer_starts_[idx] = value;
+    return;
+  }
+  Dart_Handle buffer_handle =
+      ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx]));
+  ThrowIfError(DartUtils::SetIntegerField(
+      buffer_handle, "start", static_cast<int64_t>(value)));
+}
+
+
+void SSLFilter::SetBufferEnd(intptr_t idx, intptr_t value) {
+  if (buffer_ends_[idx] != NULL) {
+    *buffer_ends_[idx] = value;
+    return;
+  }
+  Dart_Handle buffer_handle =
+      ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx]));
+  ThrowIfError(DartUtils::SetIntegerField(
+      buffer_handle, "end", static_cast<int64_t>(value)));
+}
+
+
+OSStatus SSLFilter::ProcessAllBuffers(intptr_t starts[kNumBuffers],
+                                      intptr_t ends[kNumBuffers],
+                                      bool in_handshake) {
+  for (intptr_t i = 0; i < kNumBuffers; ++i) {
+    buffer_starts_[i] = &starts[i];
+    buffer_ends_[i] = &ends[i];
+  }
+
+  if (in_handshake) {
+    OSStatus status = Handshake();
+    if (status != noErr) {
+      return status;
+    }
+  } else {
+    for (intptr_t i = 0; i < kNumBuffers; ++i) {
+      intptr_t start = starts[i];
+      intptr_t end = ends[i];
+      intptr_t size =
+          isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_;
+      if (start < 0 || end < 0 || start >= size || end >= size) {
+        FATAL("Out-of-bounds internal buffer access in dart:io SecureSocket");
+      }
+      switch (i) {
+        case kReadPlaintext:
+          // Write data to the circular buffer's free space.  If the buffer
+          // is full, neither if statement is executed and nothing happens.
+          if (start <= end) {
+            // If the free space may be split into two segments,
+            // then the first is [end, size), unless start == 0.
+            // Then, since the last free byte is at position start - 2,
+            // the interval is [end, size - 1).
+            intptr_t buffer_end = (start == 0) ? size - 1 : size;
+            intptr_t bytes = 0;
+            OSStatus status =
+                ProcessReadPlaintextBuffer(end, buffer_end, &bytes);
+            if ((status != noErr) && (status != errSSLWouldBlock)) {
+              return status;
+            }
+            end += bytes;
+            ASSERT(end <= size);
+            if (end == size) {
+              end = 0;
+            }
+          }
+          if (start > end + 1) {
+            intptr_t bytes = 0;
+            OSStatus status =
+                ProcessReadPlaintextBuffer(end, start - 1, &bytes);
+            if ((status != noErr) && (status != errSSLWouldBlock)) {
+              return status;
+            }
+            end += bytes;
+            ASSERT(end < start);
+          }
+          ends[i] = end;
+          break;
+        case kWritePlaintext:
+          // Read/Write data from circular buffer.  If the buffer is empty,
+          // neither if statement's condition is true.
+          if (end < start) {
+            // Data may be split into two segments.  In this case,
+            // the first is [start, size).
+            intptr_t bytes = 0;
+            OSStatus status = ProcessWritePlaintextBuffer(start, size, &bytes);
+            if ((status != noErr) && (status != errSSLWouldBlock)) {
+              return status;
+            }
+            start += bytes;
+            ASSERT(start <= size);
+            if (start == size) {
+              start = 0;
+            }
+          }
+          if (start < end) {
+            intptr_t bytes = 0;
+            OSStatus status = ProcessWritePlaintextBuffer(start, end, &bytes);
+            if ((status != noErr) && (status != errSSLWouldBlock)) {
+              return status;
+            }
+            start += bytes;
+            ASSERT(start <= end);
+          }
+          starts[i] = start;
+          break;
+        case kReadEncrypted:
+        case kWriteEncrypted:
+          // These buffers are advanced through SSLReadCallback and
+          // SSLWriteCallback, which are called from SSLRead, SSLWrite, and
+          // SSLHandshake.
+          break;
+        default:
+          UNREACHABLE();
+      }
+    }
+  }
+
+  for (intptr_t i = 0; i < kNumBuffers; ++i) {
+    buffer_starts_[i] = NULL;
+    buffer_ends_[i] = NULL;
+  }
+  return noErr;
+}
+
+
+Dart_Handle SSLFilter::Init(Dart_Handle dart_this) {
+  ASSERT(string_start_ == NULL);
+  string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start"));
+  ASSERT(string_start_ != NULL);
+  ASSERT(string_length_ == NULL);
+  string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length"));
+  ASSERT(string_length_ != NULL);
+  ASSERT(bad_certificate_callback_ == NULL);
+  bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null());
+  ASSERT(bad_certificate_callback_ != NULL);
+
+  // Caller handles cleanup on an error.
+  return InitializeBuffers(dart_this);
+}
+
+
+Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) {
+  // Create SSLFilter buffers as ExternalUint8Array objects.
+  Dart_Handle buffers_string = DartUtils::NewString("buffers");
+  RETURN_IF_ERROR(buffers_string);
+  Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string);
+  RETURN_IF_ERROR(dart_buffers_object);
+  Dart_Handle secure_filter_impl_type = Dart_InstanceGetType(dart_this);
+  RETURN_IF_ERROR(secure_filter_impl_type);
+  Dart_Handle size_string = DartUtils::NewString("SIZE");
+  RETURN_IF_ERROR(size_string);
+  Dart_Handle dart_buffer_size = Dart_GetField(
+      secure_filter_impl_type, size_string);
+  RETURN_IF_ERROR(dart_buffer_size);
+
+  int64_t buffer_size = 0;
+  Dart_Handle err = Dart_IntegerToInt64(dart_buffer_size, &buffer_size);
+  RETURN_IF_ERROR(err);
+
+  Dart_Handle encrypted_size_string = DartUtils::NewString("ENCRYPTED_SIZE");
+  RETURN_IF_ERROR(encrypted_size_string);
+
+  Dart_Handle dart_encrypted_buffer_size = Dart_GetField(
+      secure_filter_impl_type, encrypted_size_string);
+  RETURN_IF_ERROR(dart_encrypted_buffer_size);
+
+  int64_t encrypted_buffer_size = 0;
+  err = Dart_IntegerToInt64(dart_encrypted_buffer_size, &encrypted_buffer_size);
+  RETURN_IF_ERROR(err);
+
+  if (buffer_size <= 0 || buffer_size > 1 * MB) {
+    FATAL("Invalid buffer size in _ExternalBuffer");
+  }
+  if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) {
+    FATAL("Invalid encrypted buffer size in _ExternalBuffer");
+  }
+  buffer_size_ = static_cast<intptr_t>(buffer_size);
+  encrypted_buffer_size_ = static_cast<intptr_t>(encrypted_buffer_size);
+
+  Dart_Handle data_identifier = DartUtils::NewString("data");
+  RETURN_IF_ERROR(data_identifier);
+
+  for (int i = 0; i < kNumBuffers; i++) {
+    int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_;
+    buffers_[i] = new uint8_t[size];
+    ASSERT(buffers_[i] != NULL);
+    buffer_starts_[i] = NULL;
+    buffer_ends_[i] = NULL;
+    dart_buffer_objects_[i] = NULL;
+  }
+
+  Dart_Handle result = Dart_Null();
+  for (int i = 0; i < kNumBuffers; ++i) {
+    int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_;
+    result = Dart_ListGetAt(dart_buffers_object, i);
+    if (Dart_IsError(result)) {
+      break;
+    }
+
+    dart_buffer_objects_[i] = Dart_NewPersistentHandle(result);
+    ASSERT(dart_buffer_objects_[i] != NULL);
+    Dart_Handle data =
+        Dart_NewExternalTypedData(Dart_TypedData_kUint8, buffers_[i], size);
+    if (Dart_IsError(data)) {
+      result = data;
+      break;
+    }
+    result = Dart_HandleFromPersistent(dart_buffer_objects_[i]);
+    if (Dart_IsError(result)) {
+      break;
+    }
+    result = Dart_SetField(result, data_identifier, data);
+    if (Dart_IsError(result)) {
+      break;
+    }
+  }
+
+  // Caller handles cleanup on an error.
+  return result;
+}
+
+
+void SSLFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) {
+  ASSERT(NULL == handshake_complete_);
+  handshake_complete_ = Dart_NewPersistentHandle(complete);
+  ASSERT(handshake_complete_ != NULL);
+}
+
+
+void SSLFilter::RegisterBadCertificateCallback(Dart_Handle callback) {
+  ASSERT(bad_certificate_callback_ != NULL);
+  Dart_DeletePersistentHandle(bad_certificate_callback_);
+  bad_certificate_callback_ = Dart_NewPersistentHandle(callback);
+  ASSERT(bad_certificate_callback_ != NULL);
+}
+
+
+Dart_Handle SSLFilter::PeerCertificate() {
+  if (peer_certs_ == NULL) {
+    return Dart_Null();
+  }
+
+  CFTypeRef item = CFArrayGetValueAtIndex(peer_certs_, 0);
+  ASSERT(CFGetTypeID(item) == SecCertificateGetTypeID());
+  SecCertificateRef cert =
+      reinterpret_cast<SecCertificateRef>(const_cast<void*>(item));
+  if (cert == NULL) {
+    return Dart_Null();
+  }
+
+  return WrappedX509Certificate(cert);
+}
+
+
+void SSLFilter::Connect(Dart_Handle dart_this,
+                        const char* hostname,
+                        SSLCertContext* context,
+                        bool is_server,
+                        bool request_client_certificate,
+                        bool require_client_certificate) {
+  if (in_handshake_) {
+    FATAL("Connect called twice on the same _SecureFilter.");
+  }
+
+  // Create the underlying context
+  SSLContextRef ssl_context = SSLCreateContext(
+      NULL, is_server ? kSSLServerSide : kSSLClientSide, kSSLStreamType);
+
+  // Configure the context.
+  OSStatus status;
+  status = SSLSetPeerDomainName(ssl_context, hostname, strlen(hostname));
+  CheckStatus(status,
+      "TlsException",
+      "Failed to set peer domain name");
+
+  status = SSLSetIOFuncs(
+      ssl_context, SSLFilter::SSLReadCallback, SSLFilter::SSLWriteCallback);
+  CheckStatus(status,
+      "TlsException",
+      "Failed to set IO Callbacks");
+
+  status = SSLSetConnection(
+      ssl_context, reinterpret_cast<SSLConnectionRef>(this));
+  CheckStatus(status,
+      "TlsException",
+      "Failed to set connection object");
+
+  // Always evaluate the certs manually so that we can cache the peer
+  // certificates in the context for calls to peerCertificate.
+  status = SSLSetSessionOption(
+      ssl_context, kSSLSessionOptionBreakOnServerAuth, true);
+  CheckStatus(status,
+      "TlsException",
+      "Failed to set BreakOnServerAuth option");
+
+  status = SSLSetProtocolVersionMin(ssl_context, kTLSProtocol1);
+  CheckStatus(status,
+      "TlsException",
+      "Failed to set minimum protocol version to kTLSProtocol1");
+
+  if (is_server) {
+    SSLAuthenticate auth =
+        require_client_certificate
+        ? kAlwaysAuthenticate
+        : (request_client_certificate ? kTryAuthenticate : kNeverAuthenticate);
+    status = SSLSetClientSideAuthenticate(ssl_context, auth);
+    CheckStatus(status,
+        "TlsException",
+        "Failed to set client authentication mode");
+
+    // If we're at least trying client authentication, then break handshake
+    // for client authentication.
+    if (auth != kNeverAuthenticate) {
+      status = SSLSetSessionOption(
+          ssl_context, kSSLSessionOptionBreakOnClientAuth, true);
+      CheckStatus(status,
+          "TlsException",
+          "Failed to set client authentication mode");
+    }
+  }
+
+  // Add the contexts to our wrapper.
+  cert_context_ = context;
+  ssl_context_ = ssl_context;
+  is_server_ = is_server;
+
+  // Kick-off the handshake. Expect the handshake to need more data.
+  // SSLHandshake calls our SSLReadCallback and SSLWriteCallback.
+  status = SSLHandshake(ssl_context);
+  ASSERT(status != noErr);
+  if (status == errSSLWouldBlock) {
+    status = noErr;
+    in_handshake_ = true;
+  }
+  CheckStatus(status,
+     "HandshakeException",
+      is_server_ ? "Handshake error in server" : "Handshake error in client");
+}
+
+
+OSStatus SSLFilter::EvaluatePeerTrust() {
+  OSStatus status = noErr;
+
+  if (SSL_LOG_STATUS) {
+    Log::Print("Handshake evaluating trust.\n");
+  }
+  SecTrustRef peer_trust = NULL;
+  status = SSLCopyPeerTrust(ssl_context_, &peer_trust);
+  if (status != noErr) {
+    if (is_server_ && (status == errSSLBadCert)) {
+      // A client certificate was requested, but not required, and wasn't sent.
+      return noErr;
+    }
+    if (SSL_LOG_STATUS) {
+      Log::Print("Handshake error from SSLCopyPeerTrust(): %ld.\n",
+          static_cast<intptr_t>(status));
+    }
+    return status;
+  }
+
+  CFArrayRef trusted_certs = NULL;
+  if (cert_context_->trusted_certs() != NULL) {
+    trusted_certs = CFArrayCreateCopy(NULL, cert_context_->trusted_certs());
+  } else {
+    trusted_certs = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
+  }
+
+  status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs);
+  if (status != noErr) {
+    if (SSL_LOG_STATUS) {
+      Log::Print("Handshake error from SecTrustSetAnchorCertificates: %ld\n",
+          static_cast<intptr_t>(status));
+    }
+    CFRelease(trusted_certs);
+    CFRelease(peer_trust);
+    return status;
+  }
+
+  if (SSL_LOG_STATUS) {
+    Log::Print("Handshake %s built in root certs\n",
+        cert_context_->trust_builtin() ? "trusting" : "not trusting");
+  }
+
+  status = SecTrustSetAnchorCertificatesOnly(
+      peer_trust, !cert_context_->trust_builtin());
+  if (status != noErr) {
+    CFRelease(trusted_certs);
+    CFRelease(peer_trust);
+    return status;
+  }
+
+  SecTrustResultType trust_result;
+  status = SecTrustEvaluate(peer_trust, &trust_result);
+  if (status != noErr) {
+    CFRelease(trusted_certs);
+    CFRelease(peer_trust);
+    return status;
+  }
+
+  // Grab the peer's certificate chain.
+  CFIndex peer_chain_length = SecTrustGetCertificateCount(peer_trust);
+  CFMutableArrayRef peer_certs =
+      CFArrayCreateMutable(NULL, peer_chain_length, &kCFTypeArrayCallBacks);
+  for (CFIndex i = 0; i < peer_chain_length; ++i) {
+    CFArrayAppendValue(peer_certs,
+                       SecTrustGetCertificateAtIndex(peer_trust, i));
+  }
+  peer_certs_ = peer_certs;
+
+  CFRelease(trusted_certs);
+  CFRelease(peer_trust);
+
+  if ((trust_result == kSecTrustResultProceed) ||
+      (trust_result == kSecTrustResultUnspecified)) {
+    // Trusted.
+    return noErr;
+  } else {
+    if (SSL_LOG_STATUS) {
+      Log::Print("Trust eval failed: trust_restul = %d\n", trust_result);
+    }
+    bad_cert_ = true;
+    return errSSLBadCert;
+  }
+}
+
+
+OSStatus SSLFilter::Handshake() {
+  ASSERT(cert_context_ != NULL);
+  ASSERT(ssl_context_ != NULL);
+  // Try and push handshake along.
+  if (SSL_LOG_STATUS) {
+    Log::Print("Doing SSLHandshake\n");
+  }
+  OSStatus status = SSLHandshake(ssl_context_);
+  if (SSL_LOG_STATUS) {
+    Log::Print("SSLHandshake returned %ld\n", static_cast<intptr_t>(status));
+  }
+
+  if ((status == errSSLServerAuthCompleted) ||
+      (status == errSSLClientAuthCompleted)) {
+    status = EvaluatePeerTrust();
+    if (status == errSSLBadCert) {
+      // Need to invoke the bad certificate callback.
+      return noErr;
+    } else if (status != noErr) {
+      return status;
+    }
+    // When trust evaluation succeeds, we can call SSLHandshake again
+    // immediately.
+    status = SSLHandshake(ssl_context_);
+  }
+
+  if (status == errSSLWouldBlock) {
+    in_handshake_ = true;
+    return noErr;
+  }
+
+  // Handshake succeeded.
+  if ((in_handshake_) && (status == noErr)) {
+    if (SSL_LOG_STATUS) {
+      Log::Print("Finished with the Handshake\n");
+    }
+    connected_ = true;
+  }
+  return status;
+}
+
+
+// Returns false if Handshake should fail, and true if Handshake should
+// proceed.
+Dart_Handle SSLFilter::InvokeBadCertCallback(SecCertificateRef peer_cert) {
+  Dart_Handle callback = bad_certificate_callback_;
+  if (Dart_IsNull(callback)) {
+    return callback;
+  }
+  Dart_Handle args[1];
+  args[0] = WrappedX509Certificate(peer_cert);
+  if (Dart_IsError(args[0])) {
+    return args[0];
+  }
+  Dart_Handle result = Dart_InvokeClosure(callback, 1, args);
+  if (!Dart_IsError(result) && !Dart_IsBoolean(result)) {
+    result = Dart_NewUnhandledExceptionError(DartUtils::NewDartIOException(
+        "HandshakeException",
+        "BadCertificateCallback returned a value that was not a boolean",
+        Dart_Null()));
+  }
+  return result;
+}
+
+
+OSStatus SSLFilter::CheckHandshake() {
+  if (bad_cert_ && in_handshake_) {
+    if (SSL_LOG_STATUS) {
+      Log::Print("Invoking bad certificate callback\n");
+    }
+    ASSERT(peer_certs_ != NULL);
+    CFIndex peer_certs_len = CFArrayGetCount(peer_certs_);
+    ASSERT(peer_certs_len > 0);
+    CFTypeRef item = CFArrayGetValueAtIndex(peer_certs_, peer_certs_len - 1);
+    ASSERT(item != NULL);
+    ASSERT(CFGetTypeID(item) == SecCertificateGetTypeID());
+    SecCertificateRef peer_cert =
+        reinterpret_cast<SecCertificateRef>(const_cast<void*>(item));
+    Dart_Handle result = InvokeBadCertCallback(peer_cert);
+    ThrowIfError(result);
+    if (Dart_IsNull(result)) {
+      return errSSLBadCert;
+    } else {
+      bool good_cert = DartUtils::GetBooleanValue(result);
+      bad_cert_ = !good_cert;
+      return good_cert ? noErr : errSSLBadCert;
+    }
+  }
+
+  if (connected_ && in_handshake_) {
+    if (SSL_LOG_STATUS) {
+      Log::Print("Invoking handshake complete callback\n");
+    }
+    ThrowIfError(Dart_InvokeClosure(
+        Dart_HandleFromPersistent(handshake_complete_), 0, NULL));
+    in_handshake_ = false;
+  }
+  return noErr;
+}
+
+
+void SSLFilter::Renegotiate(bool use_session_cache,
+                            bool request_client_certificate,
+                            bool require_client_certificate) {
+  // The SSL_REQUIRE_CERTIFICATE option only takes effect if the
+  // SSL_REQUEST_CERTIFICATE option is also set, so set it.
+  request_client_certificate =
+      request_client_certificate || require_client_certificate;
+  // TODO(24070, 24069): Implement setting the client certificate parameters,
+  //   and triggering rehandshake.
+}
+
+
+SSLFilter::~SSLFilter() {
+  // cert_context_ deleted by finalizer. Don't delete here.
+  cert_context_ = NULL;
+  if (ssl_context_ != NULL) {
+    CFRelease(ssl_context_);
+    ssl_context_ = NULL;
+  }
+  if (peer_certs_ != NULL) {
+    CFRelease(peer_certs_);
+    peer_certs_ = NULL;
+  }
+  if (hostname_ != NULL) {
+    free(hostname_);
+    hostname_ = NULL;
+  }
+  for (int i = 0; i < kNumBuffers; ++i) {
+    if (buffers_[i] != NULL) {
+      delete[] buffers_[i];
+      buffers_[i] = NULL;
+    }
+  }
+}
+
+
+void SSLFilter::Destroy() {
+  if (ssl_context_ != NULL) {
+    SSLClose(ssl_context_);
+  }
+  for (int i = 0; i < kNumBuffers; ++i) {
+    if (dart_buffer_objects_[i] != NULL) {
+      Dart_DeletePersistentHandle(dart_buffer_objects_[i]);
+      dart_buffer_objects_[i] = NULL;
+    }
+  }
+  if (string_start_ != NULL) {
+    Dart_DeletePersistentHandle(string_start_);
+    string_start_ = NULL;
+  }
+  if (string_length_ != NULL) {
+    Dart_DeletePersistentHandle(string_length_);
+    string_length_ = NULL;
+  }
+  if (handshake_complete_ != NULL) {
+    Dart_DeletePersistentHandle(handshake_complete_);
+    handshake_complete_ = NULL;
+  }
+  if (bad_certificate_callback_ != NULL) {
+    Dart_DeletePersistentHandle(bad_certificate_callback_);
+    bad_certificate_callback_ = NULL;
+  }
+}
+
+
+OSStatus SSLFilter::SSLReadCallback(SSLConnectionRef connection,
+                                    void* data, size_t* data_requested) {
+  // Copy at most `data_requested` bytes from `buffers_[kReadEncrypted]` into
+  // `data`
+  ASSERT(connection != NULL);
+  ASSERT(data != NULL);
+  ASSERT(data_requested != NULL);
+
+  SSLFilter* filter =
+      const_cast<SSLFilter*>(reinterpret_cast<const SSLFilter*>(connection));
+  uint8_t* datap = reinterpret_cast<uint8_t*>(data);
+  uint8_t* buffer = filter->buffers_[kReadEncrypted];
+  intptr_t start = filter->GetBufferStart(kReadEncrypted);
+  intptr_t end = filter->GetBufferEnd(kReadEncrypted);
+  intptr_t size = filter->encrypted_buffer_size_;
+  intptr_t requested = static_cast<intptr_t>(*data_requested);
+  intptr_t data_read = 0;
+
+  if (end < start) {
+    // Data may be split into two segments.  In this case,
+    // the first is [start, size).
+    intptr_t buffer_end = (start == 0) ? size - 1 : size;
+    intptr_t available = buffer_end - start;
+    intptr_t bytes = requested < available ? requested : available;
+    memmove(datap, &buffer[start], bytes);
+    start += bytes;
+    datap += bytes;
+    data_read += bytes;
+    requested -= bytes;
+    ASSERT(start <= size);
+    if (start == size) {
+      start = 0;
+    }
+  }
+  if ((requested > 0) && (start < end)) {
+    intptr_t available = end - start;
+    intptr_t bytes = requested < available ? requested : available;
+    memmove(datap, &buffer[start], bytes);
+    start += bytes;
+    datap += bytes;
+    data_read += bytes;
+    requested -= bytes;
+    ASSERT(start <= end);
+  }
+
+  if (SSL_LOG_DATA) {
+    Log::Print("SSLReadCallback: requested: %ld, read %ld bytes\n",
+        *data_requested, data_read);
+  }
+
+  filter->SetBufferStart(kReadEncrypted, start);
+  bool short_read = data_read < static_cast<intptr_t>(*data_requested);
+  *data_requested = data_read;
+  return short_read ? errSSLWouldBlock : noErr;
+}
+
+
+// Read decrypted data from the filter to the circular buffer.
+OSStatus SSLFilter::ProcessReadPlaintextBuffer(intptr_t start,
+                                               intptr_t end,
+                                               intptr_t* bytes_processed) {
+  ASSERT(bytes_processed != NULL);
+  intptr_t length = end - start;
+  OSStatus status = noErr;
+  size_t bytes = 0;
+  if (length > 0) {
+    status = SSLRead(
+        ssl_context_,
+        reinterpret_cast<void*>((buffers_[kReadPlaintext] + start)),
+        length,
+        &bytes);
+    if (SSL_LOG_STATUS) {
+      Log::Print("SSLRead: status = %ld\n", static_cast<intptr_t>(status));
+    }
+    if ((status != noErr) && (status != errSSLWouldBlock)) {
+      *bytes_processed = 0;
+      return status;
+    }
+  }
+  if (SSL_LOG_DATA) {
+    Log::Print("ProcessReadPlaintextBuffer: requested: %ld, read %ld bytes\n",
+        length, bytes);
+  }
+  *bytes_processed = static_cast<intptr_t>(bytes);
+  return status;
+}
+
+
+OSStatus SSLFilter::SSLWriteCallback(SSLConnectionRef connection,
+                                     const void* data, size_t* data_provided) {
+  // Copy at most `data_provided` bytes from data into
+  // `buffers_[kWriteEncrypted]`.
+  ASSERT(connection != NULL);
+  ASSERT(data != NULL);
+  ASSERT(data_provided != NULL);
+
+  SSLFilter* filter =
+    const_cast<SSLFilter*>(reinterpret_cast<const SSLFilter*>(connection));
+  const uint8_t* datap = reinterpret_cast<const uint8_t*>(data);
+  uint8_t* buffer = filter->buffers_[kWriteEncrypted];
+  intptr_t start = filter->GetBufferStart(kWriteEncrypted);
+  intptr_t end = filter->GetBufferEnd(kWriteEncrypted);
+  intptr_t size = filter->encrypted_buffer_size_;
+  intptr_t provided = static_cast<intptr_t>(*data_provided);
+  intptr_t data_written = 0;
+
+  // is full, neither if statement is executed and nothing happens.
+  if (start <= end) {
+    // If the free space may be split into two segments,
+    // then the first is [end, size), unless start == 0.
+    // Then, since the last free byte is at position start - 2,
+    // the interval is [end, size - 1).
+    intptr_t buffer_end = (start == 0) ? size - 1 : size;
+    intptr_t available = buffer_end - end;
+    intptr_t bytes = provided < available ? provided : available;
+    memmove(&buffer[end], datap, bytes);
+    end += bytes;
+    datap += bytes;
+    data_written += bytes;
+    provided -= bytes;
+    ASSERT(end <= size);
+    if (end == size) {
+      end = 0;
+    }
+  }
+  if ((provided > 0) && (start > end + 1)) {
+    intptr_t available = (start - 1) - end;
+    intptr_t bytes = provided < available ? provided : available;
+    memmove(&buffer[end], datap, bytes);
+    end += bytes;
+    datap += bytes;
+    data_written += bytes;
+    provided -= bytes;
+    ASSERT(end < start);
+  }
+
+  if (SSL_LOG_DATA) {
+    Log::Print("SSLWriteCallback: provided: %ld, written %ld bytes\n",
+        *data_provided, data_written);
+  }
+
+  filter->SetBufferEnd(kWriteEncrypted, end);
+  *data_provided = data_written;
+  return (data_written == 0) ? errSSLWouldBlock : noErr;
+}
+
+
+OSStatus SSLFilter::ProcessWritePlaintextBuffer(intptr_t start,
+                                                intptr_t end,
+                                                intptr_t* bytes_processed) {
+  ASSERT(bytes_processed != NULL);
+  intptr_t length = end - start;
+  OSStatus status = noErr;
+  size_t bytes = 0;
+  if (length > 0) {
+    status = SSLWrite(
+        ssl_context_,
+        reinterpret_cast<void*>(buffers_[kWritePlaintext] + start),
+        length,
+        &bytes);
+    if (SSL_LOG_STATUS) {
+      Log::Print("SSLWrite: status = %ld\n", static_cast<intptr_t>(status));
+    }
+    if ((status != noErr) && (status != errSSLWouldBlock)) {
+      *bytes_processed = 0;
+      return status;
+    }
+  }
+  if (SSL_LOG_DATA) {
+    Log::Print("ProcessWritePlaintextBuffer: requested: %ld, written: %ld\n",
+        length, bytes);
+  }
+  *bytes_processed = static_cast<intptr_t>(bytes);
+  return status;
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // TARGET_OS_IOS
+
+#endif  // !defined(DART_IO_SECURE_SOCKET_DISABLED)
diff --git a/runtime/bin/secure_socket_macos.cc b/runtime/bin/secure_socket_macos.cc
index 5e6e320..84b10c0 100644
--- a/runtime/bin/secure_socket_macos.cc
+++ b/runtime/bin/secure_socket_macos.cc
@@ -5,7 +5,7 @@
 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED)
 
 #include "platform/globals.h"
-#if defined(TARGET_OS_MACOS)
+#if defined(TARGET_OS_MACOS) && !TARGET_OS_IOS
 
 #include "bin/secure_socket.h"
 #include "bin/secure_socket_macos.h"
@@ -377,65 +377,6 @@
 }
 
 
-// Where the argument to the constructor is the handle for an object
-// implementing List<int>, this class creates a scope in which the memory
-// backing the list can be accessed.
-//
-// Do not make Dart_ API calls while in a ScopedMemBuffer.
-// Do not call Dart_PropagateError while in a ScopedMemBuffer.
-class ScopedMemBuffer {
- public:
-  explicit ScopedMemBuffer(Dart_Handle object) {
-    if (!Dart_IsTypedData(object) && !Dart_IsList(object)) {
-      Dart_ThrowException(DartUtils::NewDartArgumentError(
-          "Argument is not a List<int>"));
-    }
-
-    uint8_t* bytes = NULL;
-    intptr_t bytes_len = 0;
-    bool is_typed_data = false;
-    if (Dart_IsTypedData(object)) {
-      is_typed_data = true;
-      Dart_TypedData_Type typ;
-      ThrowIfError(Dart_TypedDataAcquireData(
-          object,
-          &typ,
-          reinterpret_cast<void**>(&bytes),
-          &bytes_len));
-    } else {
-      ASSERT(Dart_IsList(object));
-      ThrowIfError(Dart_ListLength(object, &bytes_len));
-      bytes = Dart_ScopeAllocate(bytes_len);
-      ASSERT(bytes != NULL);
-      ThrowIfError(Dart_ListGetAsBytes(object, 0, bytes, bytes_len));
-    }
-
-    object_ = object;
-    bytes_ = bytes;
-    bytes_len_ = bytes_len;
-    is_typed_data_ = is_typed_data;
-  }
-
-  ~ScopedMemBuffer() {
-    if (is_typed_data_) {
-      ThrowIfError(Dart_TypedDataReleaseData(object_));
-    }
-  }
-
-  uint8_t* get() const { return bytes_; }
-  intptr_t length() const { return bytes_len_; }
-
- private:
-  Dart_Handle object_;
-  uint8_t* bytes_;
-  intptr_t bytes_len_;
-  bool is_typed_data_;
-
-  DISALLOW_ALLOCATION();
-  DISALLOW_COPY_AND_ASSIGN(ScopedMemBuffer);
-};
-
-
 static const char* GetPasswordArgument(Dart_NativeArguments args,
                                        intptr_t index) {
   Dart_Handle password_object =
@@ -2022,7 +1963,7 @@
 }  // namespace bin
 }  // namespace dart
 
-#endif  // defined(TARGET_OS_MACOS)
+#endif  // defined(TARGET_OS_MACOS) && !TARGET_OS_IOS
 
 #endif  // !defined(DART_IO_DISABLED) &&
         // !defined(DART_IO_SECURE_SOCKET_DISABLED)
diff --git a/runtime/bin/secure_socket_macos.h b/runtime/bin/secure_socket_macos.h
index e78321c..c088d8c 100644
--- a/runtime/bin/secure_socket_macos.h
+++ b/runtime/bin/secure_socket_macos.h
@@ -143,6 +143,64 @@
   DISALLOW_COPY_AND_ASSIGN(SSLFilter);
 };
 
+// Where the argument to the constructor is the handle for an object
+// implementing List<int>, this class creates a scope in which the memory
+// backing the list can be accessed.
+//
+// Do not make Dart_ API calls while in a ScopedMemBuffer.
+// Do not call Dart_PropagateError while in a ScopedMemBuffer.
+class ScopedMemBuffer {
+ public:
+  explicit ScopedMemBuffer(Dart_Handle object) {
+    if (!Dart_IsTypedData(object) && !Dart_IsList(object)) {
+      Dart_ThrowException(DartUtils::NewDartArgumentError(
+          "Argument is not a List<int>"));
+    }
+
+    uint8_t* bytes = NULL;
+    intptr_t bytes_len = 0;
+    bool is_typed_data = false;
+    if (Dart_IsTypedData(object)) {
+      is_typed_data = true;
+      Dart_TypedData_Type typ;
+      ThrowIfError(Dart_TypedDataAcquireData(
+          object,
+          &typ,
+          reinterpret_cast<void**>(&bytes),
+          &bytes_len));
+    } else {
+      ASSERT(Dart_IsList(object));
+      ThrowIfError(Dart_ListLength(object, &bytes_len));
+      bytes = Dart_ScopeAllocate(bytes_len);
+      ASSERT(bytes != NULL);
+      ThrowIfError(Dart_ListGetAsBytes(object, 0, bytes, bytes_len));
+    }
+
+    object_ = object;
+    bytes_ = bytes;
+    bytes_len_ = bytes_len;
+    is_typed_data_ = is_typed_data;
+  }
+
+  ~ScopedMemBuffer() {
+    if (is_typed_data_) {
+      ThrowIfError(Dart_TypedDataReleaseData(object_));
+    }
+  }
+
+  uint8_t* get() const { return bytes_; }
+  intptr_t length() const { return bytes_len_; }
+
+ private:
+  Dart_Handle object_;
+  uint8_t* bytes_;
+  intptr_t bytes_len_;
+  bool is_typed_data_;
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_COPY_AND_ASSIGN(ScopedMemBuffer);
+};
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index c880e17..da43d94 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -983,10 +983,14 @@
                                              void* user_data);
 
 typedef enum {
-  Dart_Timeline_Event_Begin,       // Phase = 'B'.
-  Dart_Timeline_Event_End,         // Phase = 'E'.
-  Dart_Timeline_Event_Instant,     // Phase = 'i'.
-  Dart_Timeline_Event_Duration,    // Phase = 'X'.
+  Dart_Timeline_Event_Begin,          // Phase = 'B'.
+  Dart_Timeline_Event_End,            // Phase = 'E'.
+  Dart_Timeline_Event_Instant,        // Phase = 'i'.
+  Dart_Timeline_Event_Duration,       // Phase = 'X'.
+  Dart_Timeline_Event_Async_Begin,    // Phase = 'b'.
+  Dart_Timeline_Event_Async_End,      // Phase = 'e'.
+  Dart_Timeline_Event_Async_Instant,  // Phase = 'n'.
+  Dart_Timeline_Event_Counter,        // Phase = 'C'.
 } Dart_Timeline_Event_Type;
 
 /**
@@ -1009,65 +1013,12 @@
                                     const char** argument_values);
 
 /**
- * Add a duration timeline event to the embedder stream.
+ * Associates a name with the current thread. This name will be used to name
+ * threads in the timeline. Can only be called after a call to Dart_Initialize.
  *
- * \param label The name of the event.
- * \param start_micros The start of the duration (in microseconds)
- * \param end_micros The end of the duration (in microseconds)
- *
- * NOTE: All timestamps should be acquired from Dart_TimelineGetMicros.
+ * \param name The name of the thread.
  */
-DART_EXPORT void Dart_TimelineDuration(const char* label,
-                                       int64_t start_micros,
-                                       int64_t end_micros);
-
-
-/**
- * Add an instant timeline event to the embedder stream.
- *
- * \param label The name of event.
- *
- * NOTE: All timestamps should be acquired from Dart_TimelineGetMicros.
- */
-DART_EXPORT void Dart_TimelineInstant(const char* label);
-
-
-/**
- * Adds an asynchronous begin timeline event to the embedder stream.
- *
- * \param label The name of event.
- * \param async_id Pointer that receives the asynchronous id for this async
- *   operation. If it is less than 0 the event was not added to the timeline.
- *
- * NOTE: All timestamps should be acquired from Dart_TimelineGetMicros.
- */
-DART_EXPORT void Dart_TimelineAsyncBegin(const char* label,
-                                         int64_t* async_id);
-
-
-/**
- * Adds an asynchronous instant timeline event to the embedder stream.
- *
- * \param label The name of event.
- * \param async_id the asynchronous id received by Dart_TimelineAsyncBegin.
- *
- * NOTE: All timestamps should be acquired from Dart_TimelineGetMicros.
- */
-DART_EXPORT void Dart_TimelineAsyncInstant(const char* label,
-                                           int64_t async_id);
-
-
-/**
- * Adds an asynchronous end timeline event to the embedder stream.
- *
- * \param label The name of event.
- * \param async_id the asynchronous id received by Dart_TimelineAsyncBegin.
- *
- * NOTE: All timestamps should be acquired from Dart_TimelineGetMicros.
- */
-DART_EXPORT void Dart_TimelineAsyncEnd(const char* label,
-                                       int64_t async_id);
-
+DART_EXPORT void Dart_SetThreadName(const char* name);
 
 /**
  * Called by the VM to let the embedder know when to start recording into the
diff --git a/runtime/lib/null_patch.dart b/runtime/lib/null_patch.dart
index fb117d1..61972d1 100644
--- a/runtime/lib/null_patch.dart
+++ b/runtime/lib/null_patch.dart
@@ -7,13 +7,12 @@
 patch class Null {
 
   factory Null._uninstantiable() {
-    throw new UnsupportedError(
-        "class Null cannot be instantiated");
+    throw new UnsupportedError("class Null cannot be instantiated");
   }
 
-  int get _identityHashCode {
-    return 2011;  // The year Dart was announced and a prime.
-  }
+  static const _HASH_CODE = 2011; // The year Dart was announced and a prime.
+  int get _identityHashCode => _HASH_CODE;
+  int get hashCode => _HASH_CODE;
 
   String toString() {
     return 'null';
diff --git a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart b/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
index d3e0252..fb63fba 100644
--- a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
+++ b/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
@@ -4,26 +4,54 @@
 
 part of cpu_profiler;
 
-class CodeCallTreeNode {
-  final ProfileCode profileCode;
+abstract class CallTreeNode {
+  final List<CallTreeNode> children;
   final int count;
   double get percentage => _percentage;
   double _percentage = 0.0;
-  final children;
   final Set<String> attributes = new Set<String>();
-  CodeCallTreeNode(this.profileCode, this.count, int childCount)
-      : children = new List<CodeCallTreeNode>(childCount) {
+
+  // Either a ProfileCode or a ProfileFunction.
+  Object get profileData;
+  String get name;
+
+  CallTreeNode(this.children, this.count);
+}
+
+class CodeCallTreeNode extends CallTreeNode {
+  final ProfileCode profileCode;
+
+  Object get profileData => profileCode;
+
+  String get name => profileCode.code.name;
+
+  final Set<String> attributes = new Set<String>();
+  CodeCallTreeNode(this.profileCode, int count)
+      : super(new List<CodeCallTreeNode>(), count) {
     attributes.addAll(profileCode.attributes);
   }
 }
 
-class CodeCallTree {
+class CallTree {
   final bool inclusive;
-  final CodeCallTreeNode root;
-  CodeCallTree(this.inclusive, this.root) {
+  final CallTreeNode root;
+
+  CallTree(this.inclusive, this.root);
+}
+
+class CodeCallTree extends CallTree {
+  CodeCallTree(bool inclusive, CodeCallTreeNode root)
+      : super(inclusive, root) {
     _setCodePercentage(null, root);
   }
 
+  CodeCallTree filtered(CallTreeNodeFilter filter) {
+    var treeFilter = new _FilteredCodeCallTreeBuilder(filter, this);
+    treeFilter.build();
+    _setCodePercentage(null, treeFilter.filtered.root);
+    return treeFilter.filtered;
+  }
+
   _setCodePercentage(CodeCallTreeNode parent, CodeCallTreeNode node) {
     assert(node != null);
     var parentPercentage = 1.0;
@@ -67,18 +95,17 @@
   FunctionCallTreeNodeCode(this.code, this.ticks);
 }
 
-class FunctionCallTreeNode {
+class FunctionCallTreeNode extends CallTreeNode {
   final ProfileFunction profileFunction;
-  final int count;
-  double get percentage => _percentage;
-  double _percentage = 0.0;
-  final children = new List<FunctionCallTreeNode>();
-  final Set<String> attributes = new Set<String>();
   final codes = new List<FunctionCallTreeNodeCode>();
   int _totalCodeTicks = 0;
   int get totalCodesTicks => _totalCodeTicks;
 
-  FunctionCallTreeNode(this.profileFunction, this.count){
+  String get name => profileFunction.function.name;
+  Object get profileData => profileFunction;
+
+  FunctionCallTreeNode(this.profileFunction, int count)
+      : super(new List<FunctionCallTreeNode>(), count) {
     profileFunction._addKindBasedAttributes(attributes);
   }
 
@@ -140,27 +167,21 @@
 
 /// Predicate filter function. Returns true if path from root to [node] and all
 /// of [node]'s children should be added to the filtered tree.
-typedef bool FunctionCallTreeNodeFilter(FunctionCallTreeNode node);
+typedef bool CallTreeNodeFilter(CallTreeNode node);
 
 /// Build a filter version of a FunctionCallTree.
-class _FilteredFunctionCallTreeBuilder {
+abstract class _FilteredCallTreeBuilder {
   /// The filter.
-  final FunctionCallTreeNodeFilter filter;
+  final CallTreeNodeFilter filter;
   /// The unfiltered tree.
-  final FunctionCallTree _unfilteredTree;
+  final CallTree _unfilteredTree;
   /// The filtered tree (construct by [build]).
-  final FunctionCallTree filtered;
+  final CallTree filtered;
   final List _currentPath = [];
 
   /// Construct a filtered tree builder using [filter] and [tree].
-  _FilteredFunctionCallTreeBuilder(this.filter, FunctionCallTree tree)
-      : _unfilteredTree = tree,
-        filtered =
-          new FunctionCallTree(
-              tree.inclusive,
-              new FunctionCallTreeNode(
-                  tree.root.profileFunction,
-                  tree.root.count));
+  _FilteredCallTreeBuilder(this.filter, CallTree tree, this.filtered)
+      : _unfilteredTree = tree;
 
   /// Build the filtered tree.
   build() {
@@ -170,16 +191,18 @@
     _descend(_unfilteredTree.root);
   }
 
-  FunctionCallTreeNode _findFunctionInChildren(FunctionCallTreeNode current,
-                                               FunctionCallTreeNode needle) {
+  CallTreeNode _findInChildren(CallTreeNode current,
+                               CallTreeNode needle) {
     for (var child in current.children) {
-      if (child.profileFunction == needle.profileFunction) {
+      if (child.profileData == needle.profileData) {
         return child;
       }
     }
     return null;
   }
 
+  CallTreeNode _copyNode(CallTreeNode node);
+
   /// Add all nodes in [_currentPath].
   FunctionCallTreeNode _addCurrentPath() {
     FunctionCallTreeNode current = filtered.root;
@@ -191,10 +214,10 @@
       // toAdd is from the unfiltered tree.
       var toAdd = _currentPath[i];
       // See if we already have a node for toAdd in the filtered tree.
-      var child = _findFunctionInChildren(current, toAdd);
+      var child = _findInChildren(current, toAdd);
       if (child == null) {
         // New node.
-        child = new FunctionCallTreeNode(toAdd.profileFunction, toAdd.count);
+        child = _copyNode(toAdd);
         current.children.add(child);
       }
       current = child;
@@ -204,13 +227,13 @@
   }
 
   /// Starting at [current] append [next] and all of [next]'s sub-trees
-  _appendTree(FunctionCallTreeNode current, FunctionCallTreeNode next) {
+  _appendTree(CallTreeNode current, CallTreeNode next) {
     if (next == null) {
       return;
     }
-    var child = _findFunctionInChildren(current, next);
+    var child = _findInChildren(current, next);
     if (child == null) {
-      child = new FunctionCallTreeNode(next.profileFunction, next.count);
+      child = _copyNode(next);
       current.children.add(child);
     }
     current = child;
@@ -221,13 +244,13 @@
 
   /// Add path from root to [child], [child], and all of [child]'s sub-trees
   /// to filtered tree.
-  _addTree(FunctionCallTreeNode child) {
+  _addTree(CallTreeNode child) {
     var current = _addCurrentPath();
     _appendTree(current, child);
   }
 
   /// Descend further into the tree. [current] is from the unfiltered tree.
-  _descend(FunctionCallTreeNode current) {
+  _descend(CallTreeNode current) {
     if (current == null) {
       return;
     }
@@ -256,14 +279,39 @@
   }
 }
 
-class FunctionCallTree {
-  final bool inclusive;
-  final FunctionCallTreeNode root;
-  FunctionCallTree(this.inclusive, this.root) {
+class _FilteredFunctionCallTreeBuilder extends _FilteredCallTreeBuilder {
+  _FilteredFunctionCallTreeBuilder(CallTreeNodeFilter filter,
+                                   FunctionCallTree tree)
+    : super(filter, tree,
+            new FunctionCallTree(tree.inclusive,
+                new FunctionCallTreeNode(tree.root.profileData,
+                                         tree.root.count)));
+
+  _copyNode(FunctionCallTreeNode node) {
+    return new FunctionCallTreeNode(node.profileData, node.count);
+  }
+}
+
+class _FilteredCodeCallTreeBuilder extends _FilteredCallTreeBuilder {
+  _FilteredCodeCallTreeBuilder(CallTreeNodeFilter filter,
+                               CodeCallTree tree)
+    : super(filter, tree,
+            new CodeCallTree(tree.inclusive,
+                new CodeCallTreeNode(tree.root.profileData,
+                                     tree.root.count)));
+
+  _copyNode(CodeCallTreeNode node) {
+    return new CodeCallTreeNode(node.profileData, node.count);
+  }
+}
+
+class FunctionCallTree extends CallTree {
+  FunctionCallTree(bool inclusive, FunctionCallTreeNode root)
+      : super(inclusive, root) {
     _setFunctionPercentage(null, root);
   }
 
-  FunctionCallTree filtered(FunctionCallTreeNodeFilter filter) {
+  FunctionCallTree filtered(CallTreeNodeFilter filter) {
     var treeFilter = new _FilteredFunctionCallTreeBuilder(filter, this);
     treeFilter.build();
     _setFunctionPercentage(null, treeFilter.filtered.root);
@@ -732,7 +780,8 @@
     // Child node count.
     var children = data[_dataCursor++];
     // Create node.
-    var node = new CodeCallTreeNode(code, count, children);
+    var node = new CodeCallTreeNode(code, count);
+    node.children.length = children;
     return node;
   }
 
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.dart b/runtime/observatory/lib/src/elements/cpu_profile.dart
index 6f74bbc..e9d9805 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile.dart
@@ -547,26 +547,62 @@
 class StackTraceTreeConfigElement extends ObservatoryElement {
   StackTraceTreeConfigElement.created() : super.created();
 
+  attached() {
+    super.attached();
+    var filterElement = shadowRoot.querySelector('#filterInput');
+    keyDownSubscription = filterElement.onKeyDown.listen(_onKeyDown);
+    blurSubscription = filterElement.onBlur.listen(_onBlur);
+  }
+
+  detached() {
+    super.detached();
+    keyDownSubscription?.cancel();
+    blurSubscription?.cancel();
+  }
+
+  void _onKeyDown(KeyboardEvent keyEvent) {
+    if (keyEvent.keyCode == 13) {
+      // On enter, update the filter string.
+      filterString =
+          (shadowRoot.querySelector('#filterInput') as InputElement).value;
+      if (onTreeConfigChange == null) {
+        return;
+      }
+      onTreeConfigChange(modeSelector, directionSelector, filterString);
+    }
+  }
+
+  void _onBlur(Event event) {
+    // Input box has lost focus, update the display to match the active
+    // filter string.
+    (shadowRoot.querySelector('#filterInput') as InputElement).value =
+        filterString;
+  }
+
   void modeSelectorChanged(oldValue) {
     if (onTreeConfigChange == null) {
       return;
     }
-    onTreeConfigChange(modeSelector, directionSelector);
+    onTreeConfigChange(modeSelector, directionSelector, filterString);
   }
 
   void directionSelectorChanged(oldValue) {
     if (onTreeConfigChange == null) {
       return;
     }
-    onTreeConfigChange(modeSelector, directionSelector);
+    onTreeConfigChange(modeSelector, directionSelector, filterString);
   }
 
   Function onTreeConfigChange;
+  StreamSubscription keyDownSubscription;
+  StreamSubscription blurSubscription;
   @observable bool show = true;
   @observable bool showModeSelector = true;
   @observable bool showDirectionSelector = true;
+  @observable bool showFilter = true;
   @observable String modeSelector = 'Function';
   @observable String directionSelector = 'Up';
+  @observable String filterString;
 }
 
 class FunctionCallTreeNodeRow extends VirtualTreeRow {
@@ -588,6 +624,7 @@
   }
 
   void onRender(DivElement rowDiv) {
+    rowDiv.children.add(makeGap(ems:0.1));
     rowDiv.children.add(
         makeText(totalPercent, toolTip: 'global % on stack'));
     rowDiv.children.add(makeGap());
@@ -640,6 +677,7 @@
   }
 
   void onRender(DivElement rowDiv) {
+    rowDiv.children.add(makeGap(ems:0.1));
     rowDiv.children.add(
         makeText(totalPercent, toolTip: 'global % on stack'));
     rowDiv.children.add(makeGap());
@@ -709,9 +747,8 @@
     var applySize = (e) {
       Rectangle rect = e.getBoundingClientRect();
       final totalHeight = window.innerHeight;
-      final top = rect.top;
       final bottomMargin = 200;
-      final mainHeight = totalHeight - top - bottomMargin;
+      final mainHeight = totalHeight - bottomMargin;
       e.style.setProperty('height', '${mainHeight}px');
     };
     HtmlElement e2 = $['cpuProfileVirtualTree'];
@@ -732,7 +769,9 @@
     _renderTask.queue();
   }
 
-  onTreeConfigChange(String modeSelector, String directionSelector) {
+  onTreeConfigChange(String modeSelector,
+                     String directionSelector,
+                     String filterString) {
     ProfileTreeDirection direction = ProfileTreeDirection.Exclusive;
     if (directionSelector != 'Up') {
       direction = ProfileTreeDirection.Inclusive;
@@ -741,6 +780,16 @@
     if (modeSelector == 'Code') {
       mode = ProfileTreeMode.Code;
     }
+    // Clear the filter.
+    cpuProfileVirtualTreeElement.filter = null;
+    if (filterString != null) {
+      filterString = filterString.trim();
+      if (filterString.isNotEmpty) {
+        cpuProfileVirtualTreeElement.filter = (CallTreeNode node) {
+          return node.name.contains(filterString);
+        };
+      }
+    }
     cpuProfileVirtualTreeElement.direction = direction;
     cpuProfileVirtualTreeElement.mode = mode;
     _renderTask.queue();
@@ -967,7 +1016,9 @@
     _renderTask.queue();
   }
 
-  onTreeConfigChange(String modeSelector, String directionSelector) {
+  onTreeConfigChange(String modeSelector,
+                     String directionSelector,
+                     String filterString) {
     ProfileTreeDirection direction = ProfileTreeDirection.Exclusive;
     if (directionSelector != 'Up') {
       direction = ProfileTreeDirection.Inclusive;
@@ -1272,11 +1323,22 @@
   ProfileTreeMode mode = ProfileTreeMode.Function;
   CpuProfile profile;
   VirtualTree virtualTree;
-  FunctionCallTreeNodeFilter functionFilter;
+  CallTreeNodeFilter filter;
+  StreamSubscription _resizeSubscription;
   @observable bool show = true;
 
   CpuProfileVirtualTreeElement.created() : super.created();
 
+  attached() {
+    super.attached();
+    _resizeSubscription = window.onResize.listen((_) => _updateSize());
+  }
+
+  detached() {
+    super.detached();
+    _resizeSubscription?.cancel();
+  }
+
   void render() {
     _updateView();
   }
@@ -1288,6 +1350,7 @@
   }
 
   void _updateView() {
+    _updateSize();
     virtualTree?.clear();
     virtualTree?.uninstall();
     virtualTree = null;
@@ -1301,6 +1364,13 @@
     virtualTree?.refresh();
   }
 
+  void _updateSize() {
+    var treeBody = shadowRoot.querySelector('#tree');
+    assert(treeBody != null);
+    int windowHeight = window.innerHeight - 32;
+    treeBody.style.height = '${windowHeight}px';
+  }
+
   void _buildFunctionTree(bool exclusive) {
     var treeBody = shadowRoot.querySelector('#tree');
     assert(treeBody != null);
@@ -1312,8 +1382,8 @@
     if (tree == null) {
       return;
     }
-    if (functionFilter != null) {
-      tree = tree.filtered(functionFilter);
+    if (filter != null) {
+      tree = tree.filtered(filter);
     }
     for (var child in tree.root.children) {
       virtualTree.rows.add(
@@ -1335,6 +1405,9 @@
     if (tree == null) {
       return;
     }
+    if (filter != null) {
+      tree = tree.filtered(filter);
+    }
     for (var child in tree.root.children) {
       virtualTree.rows.add(
           new CodeCallTreeNodeRow(virtualTree, 0, profile, child));
@@ -1352,7 +1425,7 @@
   CpuProfile profile;
   TableTree codeTree;
   TableTree functionTree;
-  FunctionCallTreeNodeFilter functionFilter;
+  CallTreeNodeFilter functionFilter;
   @observable bool show = true;
 
   CpuProfileTreeElement.created() : super.created();
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.html b/runtime/observatory/lib/src/elements/cpu_profile.html
index 68eb99a..b5f2432 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile.html
+++ b/runtime/observatory/lib/src/elements/cpu_profile.html
@@ -113,53 +113,62 @@
     <style>
     .statusBox {
       height: 100%;
-      padding: 1em;
+      padding: 0.5em;
+    }
+    .row {
+      display: flex;
     }
     </style>
     <div class="content-centered-big">
       <template if="{{ show }}">
         <h2>Tree display</h2>
         <hr>
-        <div class="memberList">
-          <template if="{{ showModeSelector }}">
-            <div class="memberItem">
-              <div class="memberName">Mode</div>
-              <div class="memberValue">
-                <select value="{{modeSelector}}">
-                  <option value="Code">Code</option>
-                  <option value="Function">Function</option>
-                </select>
-              </div>
+        <div class="row">
+          <div>
+            <div class="memberList">
+              <template if="{{ showModeSelector }}">
+                <div class="memberItem">
+                  <div class="memberName">Mode</div>
+                  <div class="memberValue">
+                    <select value="{{modeSelector}}">
+                      <option value="Code">Code</option>
+                      <option value="Function">Function</option>
+                    </select>
+                  </div>
+                </div>
+              </template>
+              <template if="{{ showDirectionSelector }}">
+                <div class="memberItem">
+                  <div class="memberName">Call Tree Direction</div>
+                  <span class="memberValue">
+                    <select value="{{directionSelector}}">
+                      <option value="Down">Top down</option>
+                      <option value="Up">Bottom up</option>
+                    </select>
+                    <template if="{{ directionSelector == 'Down' }}">
+                      <span>
+                        Tree is rooted at "main". Child nodes are callees.
+                      </span>
+                    </template>
+                    <template if="{{ directionSelector == 'Up' }}">
+                      <span>
+                        Tree is rooted at executing function / code. Child nodes are callers.
+                      </span>
+                    </template>
+                  </span>
+                </div>
+              </template>
+              <template if="{{ showFilter }}">
+                <div class="memberItem">
+                  <div title="case-sensitive substring match" class="memberName">Call Tree Filter</div>
+                  <span class="memberValue">
+                    <input type="text" placeholder="Search filter" id="filterInput">
+                  </span>
+                </div>
+              </template>
             </div>
-          </template>
-          <template if="{{ showDirectionSelector }}">
-            <div class="memberItem">
-              <div class="memberName">Call Tree Direction</div>
-              <div class="memberValue">
-                <select value="{{directionSelector}}">
-                  <option value="Down">Top down</option>
-                  <option value="Up">Bottom up</option>
-                </select>
-              </div>
-            </div>
-          </template>
+          </div>
         </div>
-        <template if="{{ directionSelector == 'Down' }}">
-          <br>
-          <div class="statusBox shadow">
-            <div>Tree is rooted at main.</div>
-            <br>
-            <div>Child nodes are callees.</div>
-          </div>
-        </template>
-        <template if="{{ directionSelector == 'Up' }}">
-          <br>
-          <div class="statusBox shadow">
-            <div>Tree is rooted at executing function / code.</div>
-            <br>
-            <div>Child nodes are callers.</div>
-          </div>
-        </template>
       </template>
     </div>
   </template>
@@ -486,7 +495,7 @@
     <br>
     <stack-trace-tree-config id="stackTraceTreeConfig"></stack-trace-tree-config>
     <br>
-    <cpu-profile-virtual-tree class="shadow" id="cpuProfileVirtualTree"></cpu-profile-virtual-tree>
+    <cpu-profile-virtual-tree id="cpuProfileVirtualTree"></cpu-profile-virtual-tree>
   </template>
 </polymer-element>
 
diff --git a/runtime/observatory/lib/src/elements/instance_view.html b/runtime/observatory/lib/src/elements/instance_view.html
index 77e84f9..5e98824 100644
--- a/runtime/observatory/lib/src/elements/instance_view.html
+++ b/runtime/observatory/lib/src/elements/instance_view.html
@@ -323,6 +323,18 @@
                 <any-service-ref ref="{{ instance.externalTwoByteFunction }}"></any-service-ref>
               </div>
             </div>
+            <div class="memberItem">
+              <div class="memberName">oneByteBytecode</div>
+              <div class="memberValue">
+                <any-service-ref ref="{{ instance.oneByteBytecode }}"></any-service-ref>
+              </div>
+            </div>
+            <div class="memberItem">
+              <div class="memberName">twoByteBytecode</div>
+              <div class="memberValue">
+                <any-service-ref ref="{{ instance.twoByteBytecode }}"></any-service-ref>
+              </div>
+            </div>
           </div>
         </template>
 
diff --git a/runtime/observatory/lib/src/elements/timeline_page.dart b/runtime/observatory/lib/src/elements/timeline_page.dart
index cdcb1d7..cc66f9a 100644
--- a/runtime/observatory/lib/src/elements/timeline_page.dart
+++ b/runtime/observatory/lib/src/elements/timeline_page.dart
@@ -8,6 +8,7 @@
 import 'dart:convert';
 import 'dart:html';
 import 'observatory_element.dart';
+import 'package:observatory/elements.dart';
 import 'package:observatory/service_html.dart';
 import 'package:polymer/polymer.dart';
 
@@ -20,6 +21,9 @@
     super.attached();
     _resizeSubscription = window.onResize.listen((_) => _updateSize());
     _updateSize();
+    // Click refresh button.
+    NavRefreshElement refreshButton = $['refresh'];
+    refreshButton.buttonClick(null, null, null);
   }
 
   detached() {
diff --git a/runtime/observatory/lib/src/elements/timeline_page.html b/runtime/observatory/lib/src/elements/timeline_page.html
index d0a2bcd..d142088 100644
--- a/runtime/observatory/lib/src/elements/timeline_page.html
+++ b/runtime/observatory/lib/src/elements/timeline_page.html
@@ -11,7 +11,7 @@
       <top-nav-menu></top-nav-menu>
       <vm-nav-menu vm="{{ app.vm }}"></vm-nav-menu>
       <nav-menu link="{{ makeLink('/timeline') }}" anchor="timeline" last="{{ true }}"></nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-refresh id="refresh" callback="{{ refresh }}"></nav-refresh>
       <nav-refresh callback="{{ clear }}" label="Clear"></nav-refresh>
       <nav-refresh callback="{{ recordOn }}" label="Start recording"></nav-refresh>
       <nav-refresh callback="{{ recordOff }}" label="Stop recording"></nav-refresh>
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index f36683b..0797007 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -2323,6 +2323,8 @@
   @observable Function twoByteFunction;  // If a RegExp.
   @observable Function externalOneByteFunction;  // If a RegExp.
   @observable Function externalTwoByteFunction;  // If a RegExp.
+  @observable Instance oneByteBytecode;  // If a RegExp.
+  @observable Instance twoByteBytecode;  // If a RegExp.
   @observable bool isCaseSensitive;  // If a RegExp.
   @observable bool isMultiLine;  // If a RegExp.
 
@@ -2414,6 +2416,8 @@
     twoByteFunction = map['_twoByteFunction'];
     externalOneByteFunction = map['_externalOneByteFunction'];
     externalTwoByteFunction = map['_externalTwoByteFunction'];
+    oneByteBytecode = map['_oneByteBytecode'];
+    twoByteBytecode = map['_twoByteBytecode'];
 
     nativeFields = map['_nativeFields'];
     fields = map['fields'];
diff --git a/runtime/observatory/tests/service/evaluate_activation_in_method_class_other.dart b/runtime/observatory/tests/service/evaluate_activation_in_method_class_other.dart
new file mode 100644
index 0000000..6cc5879
--- /dev/null
+++ b/runtime/observatory/tests/service/evaluate_activation_in_method_class_other.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:developer';
+
+var topLevel = "OtherLibrary";
+
+class Superclass {
+  var _instVar = 'Superclass';
+  var instVar = 'Superclass';
+  method() => 'Superclass';
+  static staticMethod() => 'Superclass';
+}
+
+class Klass extends Superclass {
+  var _instVar = 'Klass';
+  var instVar = 'Klass';
+  method() => 'Klass';
+  static staticMethod() => 'Klass';
+
+  test() {
+    var _local = 'Klass';
+    debugger();
+  }
+}
diff --git a/runtime/observatory/tests/service/evaluate_activation_in_method_class_test.dart b/runtime/observatory/tests/service/evaluate_activation_in_method_class_test.dart
new file mode 100644
index 0000000..cfe4315
--- /dev/null
+++ b/runtime/observatory/tests/service/evaluate_activation_in_method_class_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+// Tests that expressions evaluated in a frame see the same scope as the
+// frame's method.
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+import 'evaluate_activation_in_method_class_other.dart';
+
+var topLevel = "TestLibrary";
+
+class Subclass extends Superclass with Klass {
+  var _instVar = 'Subclass';
+  var instVar = 'Subclass';
+  method() => 'Subclass';
+  static staticMethod() => 'Subclass';
+}
+
+testeeDo() {
+  var obj = new Subclass();
+  obj.test();
+}
+
+testerDo(Isolate isolate) async {
+  await hasStoppedAtBreakpoint(isolate);
+
+  // Make sure we are in the right place.
+  var stack = await isolate.getStack();
+  var topFrame = 0;
+  expect(stack.type, equals('Stack'));
+  expect(stack['frames'][topFrame].function.name, equals('test'));
+  expect(stack['frames'][topFrame].function.dartOwner.name, equals('Superclass&Klass'));
+
+  var result;
+
+  result = await isolate.evalFrame(topFrame, '_local');
+  print(result);
+  expect(result.valueAsString, equals('Klass'));
+
+  result = await isolate.evalFrame(topFrame, '_instVar');
+  print(result);
+  expect(result.valueAsString, equals('Klass'));
+
+  result = await isolate.evalFrame(topFrame, 'instVar');
+  print(result);
+  expect(result.valueAsString, equals('Subclass'));
+
+  result = await isolate.evalFrame(topFrame, 'method()');
+  print(result);
+  expect(result.valueAsString, equals('Subclass'));
+
+  result = await isolate.evalFrame(topFrame, 'super._instVar');
+  print(result);
+  expect(result.valueAsString, equals('Superclass'));
+
+  result = await isolate.evalFrame(topFrame, 'super.instVar');
+  print(result);
+  expect(result.valueAsString, equals('Superclass'));
+
+  result = await isolate.evalFrame(topFrame, 'super.method()');
+  print(result);
+  expect(result.valueAsString, equals('Superclass'));
+
+  result = await isolate.evalFrame(topFrame, 'staticMethod()');
+  print(result);
+  expect(result.valueAsString, equals('Klass'));
+  
+  // function.Owner verus function.Origin
+  // The mixin of Superclass is in _other.dart and the mixin
+  // application is in _test.dart.
+  result = await isolate.evalFrame(topFrame, 'topLevel');
+  print(result);
+  expect(result.valueAsString, equals('OtherLibrary'));
+}
+
+main(args) => runIsolateTests(args, [testerDo], testeeConcurrent:testeeDo);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 5c71adc..8003189 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -38,3 +38,6 @@
 # Service protocol is not supported when running a full application snapshot.
 [ ($runtime == dart_product) ]
 *: SkipByDesign
+
+[ $compiler == dart2analyzer ]
+evaluate_activation_in_method_class_test: CompileTimeError # Issue 24478
diff --git a/runtime/observatory/web/third_party/trace_viewer_full.html b/runtime/observatory/web/third_party/trace_viewer_full.html
index 930312b..7c0f430 100644
--- a/runtime/observatory/web/third_party/trace_viewer_full.html
+++ b/runtime/observatory/web/third_party/trace_viewer_full.html
@@ -100,99 +100,7 @@
       </overlay-frame>
     </overlay-vertical-centering-container>
   </overlay-mask>
-</template><polymer-element constructor="TracingAnalysisTabView" name="tr-ui-a-tab-view">
-  <template>
-    <style>
-      :host {
-        display: flex;
-        flex-flow: column nowrap;
-        overflow: hidden;
-        box-sizing: border-box;
-      }
-
-      tab-strip[tabs-hidden] {
-        display: none;
-      }
-
-      tab-strip {
-        background-color: rgb(236, 236, 236);
-        border-bottom: 1px solid #8e8e8e;
-        display: flex;
-        flex: 0 0 auto;
-        flex-flow: row;
-        overflow-x: auto;
-        padding: 0 10px 0 10px;
-        font-size: 12px;
-      }
-
-      tab-button {
-        display: block;
-        flex: 0 0 auto;
-        padding: 4px 15px 1px 15px;
-        margin-top: 2px;
-      }
-
-      tab-button[selected=true] {
-        background-color: white;
-        border: 1px solid rgb(163, 163, 163);
-        border-bottom: none;
-        padding: 3px 14px 1px 14px;
-      }
-
-      tabs-content-container {
-        display: flex;
-        flex: 1 1 auto;
-        overflow: auto;
-        width: 100%;
-      }
-
-      ::content > * {
-        flex: 1 1 auto;
-      }
-
-      ::content > *:not([selected]) {
-        display: none;
-      }
-
-      button-label {
-        display: inline;
-      }
-
-      tab-strip-heading {
-        display: block;
-        flex: 0 0 auto;
-        padding: 4px 15px 1px 15px;
-        margin-top: 2px;
-        margin-before: 20px;
-        margin-after: 10px;
-      }
-      #tsh {
-        display: inline;
-        font-weight: bold;
-      }
-    </style>
-
-    <tab-strip>
-      <tab-strip-heading id="tshh">
-        <span id="tsh"></span>
-      </tab-strip-heading>
-      <template repeat="{{tab in tabs_}}">
-        <tab-button button-id="{{ tab.id }}" on-click="{{ tabButtonSelectHandler_ }}" selected="{{ selectedTab_.id === tab.id }}">
-          <button-label>{{ tab.label ? tab.label : 'No Label'}}</button-label>
-        </tab-button>
-      </template>
-    </tab-strip>
-
-    <tabs-content-container id="content-container">
-        <content></content>
-    </tabs-content-container>
-
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-a-sub-view">
-  
-</polymer-element><style>
+</template><style>
 * /deep/ .labeled-checkbox {
   display: flex;
   white-space: nowrap;
@@ -372,7 +280,7 @@
   </template>
 
   
-</polymer-element><polymer-element name="tr-ui-u-scalar-span">
+</polymer-element><polymer-element name="tr-v-ui-scalar-span">
   <template>
     <style>
     :host {
@@ -405,10 +313,6 @@
     <span id="warning" style="display:none">âš </span>
   </template>
   
-</polymer-element><polymer-element extends="tr-ui-u-scalar-span" name="tr-ui-u-time-duration-span">
-  
-</polymer-element><polymer-element extends="tr-ui-u-scalar-span" name="tr-ui-u-time-stamp-span">
-  
 </polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-a-generic-object-view">
   <template>
     <style>
@@ -432,6 +336,491 @@
   </template>
 
   
+</polymer-element><polymer-element name="tr-ui-b-drag-handle">
+  <template>
+    <style>
+    :host {
+      -webkit-user-select: none;
+      box-sizing: border-box;
+      display: block;
+    }
+
+    :host(.horizontal-drag-handle) {
+      background-image: -webkit-gradient(linear,
+                                         0 0, 0 100%,
+                                         from(#E5E5E5),
+                                         to(#D1D1D1));
+      border-bottom: 1px solid #8e8e8e;
+      border-top: 1px solid white;
+      cursor: ns-resize;
+      flex: 0 0 auto;
+      height: 7px;
+      position: relative;
+      z-index: 10;
+    }
+
+    :host(.vertical-drag-handle) {
+      background-image: -webkit-gradient(linear,
+                                         0 0, 100% 0,
+                                         from(#E5E5E5),
+                                         to(#D1D1D1));
+      border-left: 1px solid white;
+      border-right: 1px solid #8e8e8e;
+      cursor: ew-resize;
+      flex: 0 0 auto;
+      position: relative;
+      width: 7px;
+      z-index: 10;
+    }
+    </style>
+  </template>
+  
+</polymer-element><polymer-element name="tv-ui-b-hotkey-controller">
+  
+</polymer-element><polymer-element is="HTMLDivElement" name="tr-ui-b-info-bar">
+  <template>
+    <style>
+    :host {
+      align-items: center;
+      flex: 0 0 auto;
+      background-color: rgb(252, 235, 162);
+      border-bottom: 1px solid #A3A3A3;
+      border-left: 1px solid white;
+      border-right: 1px solid #A3A3A3;
+      border-top: 1px solid white;
+      display: flex;
+      height: 26px;
+      padding: 0 3px 0 3px;
+    }
+
+    :host(.info-bar-hidden) {
+      display: none;
+    }
+
+    #message { flex: 1 1 auto; }
+    </style>
+
+    <span id="message"></span>
+    <span id="buttons"></span>
+  </template>
+
+  
+</polymer-element><style>
+* /deep/ .x-list-view{-webkit-user-select:none;display:block}* /deep/ .x-list-view:focus{outline:none}* /deep/ .x-list-view *{-webkit-user-select:none}* /deep/ .x-list-view>.list-item{padding:2px 4px 2px 4px}* /deep/ .x-list-view:focus>.list-item[selected]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ .x-list-view>.list-item[selected]{background-color:rgb(103,199,165)}
+</style><polymer-element name="tr-ui-b-mouse-mode-icon">
+  <template>
+    <style>
+    :host {
+      display: block;
+      background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=);
+      width: 27px;
+      height: 30px;
+    }
+    :host.active {
+      cursor: auto;
+    }
+    </style>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-b-mouse-mode-selector">
+  <template>
+    <style>
+    :host {
+
+      -webkit-user-drag: element;
+      -webkit-user-select: none;
+
+      background: #DDD;
+      border: 1px solid #BBB;
+      border-radius: 4px;
+      box-shadow: 0 1px 2px rgba(0,0,0,0.2);
+      left: calc(100% - 120px);
+      position: absolute;
+      top: 100px;
+      user-select: none;
+      width: 29px;
+      z-index: 20;
+    }
+
+    .drag-handle {
+      background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=) 2px 3px no-repeat;
+      background-repeat: no-repeat;
+      border-bottom: 1px solid #BCBCBC;
+      cursor: move;
+      display: block;
+      height: 13px;
+      width: 27px;
+    }
+
+    .tool-button {
+      background-position: center center;
+      background-repeat: no-repeat;
+      border-bottom: 1px solid #BCBCBC;
+      border-top: 1px solid #F1F1F1;
+      cursor: pointer;
+    }
+
+    .buttons > .tool-button:last-child {
+      border-bottom: none;
+    }
+
+    </style>
+    <div class="drag-handle"></div>
+    <div class="buttons">
+    </div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-e-chrome-cc-display-item-list-item">
+  <template>
+    <style>
+      :host {
+        border-bottom: 1px solid #555;
+        display: block;
+        font-size: 12px;
+        padding: 3px 5px;
+      }
+
+      :host(:hover) {
+        background-color: #f0f0f0;
+        cursor: pointer;
+      }
+
+      .header {
+        font-weight: bold;
+        margin: 2px 0;
+      }
+
+      .header > .extra {
+        background-color: #777;
+        border-radius: 4px;
+        color: white;
+        margin: 0 6px;
+        text-decoration: none;
+        padding: 2px 4px;
+      }
+
+      .raw-details {
+        white-space: pre-wrap;
+      }
+
+      .details > dl {
+        margin: 0;
+      }
+
+      :host(:not([selected])) .details {
+        display: none;
+      }
+    </style>
+    <div class="header">
+      {{name}}
+      <template if="{{richDetails &amp;&amp; richDetails.skp64}}">
+        <a class="extra" download="drawing.skp" href="data:application/octet-stream;base64,{{richDetails.skp64}}" on-click="{{stopPropagation}}">SKP</a>
+      </template>
+    </div>
+    <div class="details">
+      <template if="{{rawDetails}}">
+        <div class="raw-details">{{rawDetails}}</div>
+      </template>
+      <template bind="{{richDetails}}" if="{{richDetails}}">
+        <dl>
+          <template bind="{{cullRect}}" if="{{cullRect}}">
+            <dt>Cull rect</dt>
+            <dd>{{x}},{{y}} {{width}}×{{height}}</dd>
+          </template>
+          <template bind="{{visualRect}}" if="{{visualRect}}">
+            <dt>Visual rect</dt>
+            <dd>{{x}},{{y}} {{width}}×{{height}}</dd>
+          </template>
+        </dl>
+      </template>
+    </div>
+  </template>
+  
+</polymer-element><style>
+* * /deep/ tr-ui-e-chrome-cc-picture-ops-list-view{-webkit-flex-direction:column;border-top:1px solid grey;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view{-webkit-flex:1 1 auto;overflow:auto}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item{border-bottom:1px solid #555;font-size:small;font-weight:bold;padding-bottom:5px;padding-left:5px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item:hover{background-color:#f0f0f0;cursor:pointer}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>*{color:#777;font-size:x-small;font-weight:normal;margin-left:1em;max-width:300px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.elementInfo{color:purple;font-size:small;font-weight:bold}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.time{color:rgb(136,0,0)}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view:focus>.list-item[beforeSelection]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view>.list-item[beforeSelection]{background-color:rgb(103,199,165)}
+</style><template id="tr-ui-e-chrome-cc-display-item-debugger-template">
+  <style>
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger {
+    -webkit-flex: 1 1 auto;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel {
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+    min-width: 300px;
+    overflow-y: auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info {
+    -webkit-flex: 1 1 auto;
+    padding-top: 2px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info .title {
+    font-weight: bold;
+    margin-left: 5px;
+    margin-right: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info .export {
+    margin: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > tr-ui-b-drag-handle {
+    -webkit-flex: 0 0 auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel {
+    -webkit-flex: 1 1 auto;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+      display-item-info > header {
+    border-bottom: 1px solid #555;
+  }
+
+  /*************************************************/
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+      tr-ui-e-chrome-cc-picture-ops-list-view.hasPictureOps {
+    display: block;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        tr-ui-b-drag-handle.hasPictureOps {
+    display: block;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        tr-ui-e-chrome-cc-picture-ops-list-view {
+    display: none;
+    overflow-y: auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        tr-ui-b-drag-handle {
+    display: none;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger raster-area {
+    -webkit-flex: 1 1 auto;
+    background-color: #ddd;
+    min-height: 200px;
+    min-width: 200px;
+    overflow-y: auto;
+    padding-left: 5px;
+  }
+  </style>
+
+  <left-panel>
+    <display-item-info>
+      <header>
+        <span class="title">Display Item List</span>
+        <span class="size"></span>
+        <div class="export">
+          <input class="dlfilename" type="text" value="displayitemlist.json"/>
+          <button class="dlexport">Export display item list</button>
+        </div>
+        <div class="export">
+          <input class="skpfilename" type="text" value="skpicture.skp"/>
+          <button class="skpexport">Export list as SkPicture</button>
+        </div>
+      </header>
+    </display-item-info>
+  </left-panel>
+  <right-panel>
+    <raster-area><canvas></canvas></raster-area>
+  </right-panel>
+</template><style>
+* /deep/ .tr-ui-e-chrome-cc-display-item-list-view{-webkit-flex:1 1 auto!important;display:-webkit-flex}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-layer-picker{-webkit-flex-direction:column;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls{-webkit-flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;display:inline;font-size:14px;padding-left:2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls input[type='checkbox']{vertical-align:-2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>.x-list-view{-webkit-flex:1 1 auto;font-family:monospace;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view{-webkit-flex:0 0 auto;height:200px;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view *{-webkit-user-select:text!important;cursor:text}
+</style><style>
+* /deep/ quad-stack-view {
+  display: block;
+  float: left;
+  height: 100%;
+  overflow: hidden;
+  position: relative; /* For the absolute positioned mouse-mode-selector */
+  width: 100%;
+}
+
+* /deep/ quad-stack-view > #header {
+  position: absolute;
+  font-size: 70%;
+  top: 10px;
+  left: 10px;
+  width: 800px;
+}
+* /deep/ quad-stack-view > #stacking-distance-slider {
+  position: absolute;
+  font-size: 70%;
+  top: 10px;
+  right: 10px;
+}
+
+* /deep/ quad-stack-view > #chrome-left {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABICAYAAABC4+HLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyMmV/Pm9QAAIABJREFUeNrtvXmwXdd13vlbe9/7BgzEQAIcQAIEQYKjSAokLVlOW5Fk2nLKmqx0J2Wp0k652h13uiy5XYqdwU7sSnckpZ1yV3U75apU4kos27Elu9NlyRXZjiiRomSTIiWZs0hwHsABJIY33rPX6j/W2ueed3DvAyDKKoGFW0UCeO/ec/fZZ+29v7XWt74lAIuLi7tXV1f/raq+zcy2AogIZsbpvrqfMzNE5IS/1/fVn5sZKaUTrtX9/v7nT+fn9e/1e052X/3r1THWa3R/37+miKCq7c+mjW/a+F/P57vj6/45bayn+wzXs4n+794Q9nP8+PHdS0tL31LVmfpGVQU4YSInGUb/YfZvpn+zp/LQu4Y27X31d933nurkq+qaa08yotO55npG0v2O+r1/XZ9fb2FMWoD9Oe5+pju//e+fdP3u83+j2I+89NJLn11dXf1bdSCTJnnSSpz2+/VWZ/8m+w+g/zD616yT2P9733BOZ5f4dhbCevPQHet63zVtV3y9n1/v/k9nZ562SNY7Gd5o9iPPP//8qxVKrQdL+hOy3qqdNEnTjv1JA+vuRpMGvd7kn8oCqded9B2THuJ6u/Kk7+vuiNOgQH8OX+/np813/376O/CkU2EavDwVWPiGsp9nn33WJt3ItF2ne2xOe2jTHuTJMOS0He1UcG33791JmWQYkzB6dyfp7tynsktPG8/Jdv2TGcLpfH7Sc5m0EKZBsPV+tp4PMe39bwj7efrpp229G5u2O3WPplN1cE/XQZsENybtnNN2pv4x3N1Fpu2S/SO6j6fXgz6n4gRPGmMfR7/ez/cXd/1798Tsfr4PMU52Oq4Hp95I9jPor7ZJ+G7STlEnvN7gesfXpB2tH5lZzynrO07Txtb92aQTY9rv+3i1v4jqv5umOSEq0r9O3/iqEUx6MPXnqjpxrk73812oMQmP968zyUj68zPp+U1bxG80+5GnnnrKpkVxTiWUuN4q7+96/YFXp6pvANN8hD7MmRbF6O7200KR9ed9CDbpSF4v6jIJtnQjQdPGOylK9p34/HowaFL0Z73IUNex7Z5Gk3bkN6L9yBNPPGHdY3fayu3uSP0dqH62uyP0w4XrDWo957gPEfqf78e4p4U8+0Y86R6711pvAUyL3vTvd9ou238Q/Xn4dj4/Cd6d7BlMC532534S9OnO8xvVfuTxxx+39RJlk/DtpAGc6k6hquScp+7EkyIn0+LV60Ufpu2q05zN/sOYFIfvP8CT5VEmGWN/h5w0zm/38+sl7/r3drLntt58rzdXbyT7kccee8z6O2b3JnLO6zpjk47nkyVg1pu07muas9b3CaZh4f5uPMn4Sikn7Jj9RTEJMnQfVHdck4x3Wt5i0qL6dj8/6WQ5GcSYBiEn+STrhT/fqPYzmJYxrRcopax5eH18Oi38WI2ulLImYTPNMavv716z/93rRXUmOZXVgZ5kePX7+hPeN5xJTmx3MdXf9zHyM888w8LCwgn30IUQ0xzWSYvhVD4/LarTzpWBpOl+zqRQ9lqjE2DCtbH2x9MW3XA45JxzzmHnzp0njYp9r9jPoH75Gkekc8SZ2ZpjrH/Ez8wMSSmHMY4YjZp2MDnniVGT/sPvRhxmZ2fJOWHmxj0ajU7AtvV6k4727gSklMg5M4jdq6iyuro69bv799fNptYF0X3vJKjz8MMPMz+/gWuvuYatW7eScgIEwTADEwEUAZDkBgtuYONlCCJgAuZ/N5QkCcP8avFzUH8fsZgNEoJJLAakc+2TjENi90RQjGSCJm1/hwlmgmRFFIwEYoiNxyPxvYZ07gVKUzh8+DD333cfRZXLLrvsBLxfjbl76pyO/ZRS1thq325O137k4YcftvUSOf1Ufdco/uwLX+LOv7ibZ194EYBdF+zkB956C+98+99ARE64ue6XqyqDwaDdGZqm4Qtf/DK3f+UveO7QS2uu944f/IH2WpNwdp2U/oT8+W23c8dX7+K5GN9FF+zkb7zlZt71jh9cswNPw8uTsPU0h19VeeSRR7j55lvYumUzK6MCpqTs9p2AAiRLmChWBBIIiqZEMkVUMAQTJZtQSCCKkDE0/h+7twkKpCSYxrhVMTGyCYogohRLCGvHoYD0xyGKScIUpC5AVSQl/0ACaxeCkJJhakDCTJEEiKAmDMx8XSdAY6lZQjHmZoa89NLL3Pv1r3PVVVeesDH3T+FTtZ/uguhu8v3o36naj4ggjzzyiPXhwtRjOf6+tLjEP//4r3HOuRfw5psPsOeSXQA8+dQz3Pu1ezl2+BC//I9+jvn5uXWjDfW1uLjIr37y19m8/fzJ13vlBf75L/48c3Oza3aWadSP5eUVfuUT/2bd6/3yL/xvbNgwv2Y3qbtOF0J2MfN6ka7nnnuOvZfuZcfO8xitKnloFBXEBHGLc4MTQwVEDeIkyAqa/Pdh9z5vaqgkUuz8akYGVATEHOYYiCSUQtJqkCDJsJJIvXFYNRIzLGWQQqqLEiOhqKS6gnzhqJ9cJplsiiXBSnfBJF957TEoJBKYYskwFUSgWCKnBkmZp59+mpdfepmdO3eu2USn+V/r2c/JWAX9CN/J7KdNiD744IO2nqM0Cff+01/9P7js6gP8d29/C5detJNtmzYC8OrxBZ547kVu/+JfcPDBe/iXv/xPkCnkvHalm/HPTvV6v/SP25vs3mB3fKurI37pX36cfdesf73HHriH//2X/3Fr/NOSTZMyzn0n0sx47LHH+JEf+REWFhd8pzcliRtyBVbFYlcTN0bfpoWEYiaxENTtjOQwByOZ7+r+b/zacY5YICvH/iDmBurjmzQOKMlIWkPThpohkuN0iwWI+YrNGkdeQswwcbhlWEAzw8wXazZDJfsYMP84ghXzxSHip5rB/IY5/sv/+0dc96Y3rdmA2uz0YDA1EHIqDNv1KDAVvk2yn64vOujHlqdlJ+vv/+wLX2JuywVcfOkeXj2ywGtHn0C1Hov+uUsu3cNzzz/Hf7vtdm5959snRknq6wtfvOOUr/fnX7yDH37n29fccBdG5Zy57fYvs2HrqV7vdm59x9vXJeqtx6WqD+T555/nyiv3s7y8TMLhSgLMElkURx+KENi+7uzi0EgtIUCi+OmSwIpjmYTSAIN6uiSDkkAKQgp/IgON+yaGnxIBz/rjcPckj30LU5I5rCsJsiYsafgjCbXEUIwiiqq4e1J9FjVfNCioYMlPC/eJIFuisTiN0oBkhllBcmJlaYnL9+/n0KFD7Nixg5xza6hPP/00S0tLzM7Mho/lfpGicW/hyyCQAv75Nuw+UOwi/o7WmXLfClhYOMaWLVvZtWtXG7TpRibrMx/0V1j34XcdT4DBYMA933yQnRdeymhUOHZsCZFEqrurORRZHRV2XrCLr33jft596zsZjUbtiuzGqQeDAXd//T52Xrj3lK53zzce4G/d+k6WlpfXOF5jSAhf+8YD7DjF8d3zjQf50VvfRdM0LYzqv/pHcH9napqGF154gb/59rdz7PhxTPCdNSliisYuK5rjIRsWPyeJQyGhWhyNCEn9sbrPIGRJmBRfeCb+kEXQwDZG49AFIYmh4kvmhHGYISTEGl9YBimPoZypvx8VJA3R5IurMcdrSTrjLuGjGJCNpJnGlCwWp6CRMLIoMCBhFJPYIAxNxjVXX83v//7vs337dnLONE1DzpmXX36Zt73tB1g8fhwzh3OIObyrp60IWp9XNlBfRtkCPqWIM9T5x+GhDIQN8/O88srLfPWrX+WWW245IeLVPvvubt49biZRMTDj6MISGzdt9i81YTjIzM/OMjc7w3AwANwp27hpM0cWln0iOt9RowruSAlHFpZP43pLJxAB68lnZuSUOXJa41tCIuQ7jYBWf9fnP5kZo9GIlZUVLrzwQpaXVzxihGHJEE1ucdlIkgOwKMncj5Ds0SjfZd2R9re7AeWkGOFUhuOrrd+jFDPMEkJ1XGPhxdY+cRzZARPJfR9Jiqm/P2wONKHJwJRs6jt0Su5nWHJfQj2IYBQIp14xBkI47OE/BVyUFI6/KCk5zJOSGY1W2bFjB03TrOGtzQyHNKNRnTGQghWjWInxGI0phvtyNOZg0GAU86hmlMYw9c9qMYyCjgpHjx9ndmYD3//Wt3LPPfdM9FtUlYGqUko5IbzVdUi7WHw4M8vc3CxzczNsmnejq6HSphSWVlYBWF2ZY2Z2tt2tuwuw/ruUwszs6V2vuxi6TlYd48zM6V+vC8/qYqgnZT861Y+dP/bYo/zoj/4Yo3o8u1PgoVRJiPqJBRkRo6C+oxchSaGIxC5uJHEfwDdqN3xTg+wRKXd2EyRIBppjy/fLY02CWCzTxuHX91MAEfdPNJESqBopFcwyJurAqg3jWpx6DqkExVIiNwIDQa1BAWRAQiE5XExJ/URCyQgFIZlB9rk8cOAAt912G/v3728jiMOZGVQDEShoSUhuEM2U5CecFHWIGbAzlwZJghRDs0AJ2FVdu2wUMxI+XyqFpjF27drF0aNH2bRpU7txt455fcjVuCrE6Ds6DkdW2bF9C1lg49wsG+ZmOWfjHNu3bGL7lk1s2TjPpvlZNszOkMTYsW0LWvSEHbhraDu2nfr1ztu6haa3uLqn0qhpOO+0rncOTWcy+vmMesLVxVgXdimFpmligWbmZgZtLN8vFmFZbbBGHfdSwo9whxot8ZAdMydzTG9aUDGKGlZ8QaiGU6wGVtDSUChIY6j6gqOBTHPScZj5qVHUoAg0DaYlIIWhlj2qFUhBDUwLNH4tMCgKZqRSGMwO+PM//VOGgznPe2jDYGbIvfd8g5mZAapCMcEEv6cK8RpFLLFp06Z2Lqvt7dmzh4cfeRBTQ1E04GXBEG187pLSqNKYbyBm0IQda6MoDUbB1DwQUvyE1tJgKFqM1dJw6Z5Lefzxx1vb7B4EqbtSJjmmXYjVNIXrr7mCI68dZmaQmJ8dsu2cTezYtpkd2zaz9ZyNzM8OmRlkjr52mBuu2c/qaHRCZGcMSxpuuGb/qV/v2isYxfW6GdFqtE3TcMNpjq8mGbs+xyRSX520GhMvpfDC889z7XXXsdKsYMV8t7fA3ChYJmWgGKkIlh3SWeQEwJDkp0UJKKIioGNXW9R3PnKKEK+E32BYDlxvUMTQzEnHIREQSCQaMSRn9+dlvKOmMUr3aFRKcco43JIUicWU+G+3fYHf/c+/x6c+9R+ZGQ6ZmZ3jtz/1Kf7PX/vX3HPvvTHaQsYgKUnFo9C5oBirKytcdeVVvPjii+1zEBGOHTvGxk0bfXGabyxGQ1GHmaYB4YqRLDYIIXyw4vDQ/HoJQ61BTHyPKeZ3aMbxhQXm5+dPSDCaGamPt7pQZRJL8qYbrmP56KscPnwYEZgZJAbZ/5sZZMA4fPgVlo++yoEbrqXCtq4Bdv2bm9/8JpaPvXZq17v+2hNgTXcxN03DzQeuP+Xx3XLg+hNoGN1Togsxu4umnijPv/AC+6/YTxlZZIo1YJIf5yLmBpeFMhCwEg67J8QkVacyRe66eLg1aRtcUVFSgmzFsx3uWSKSkWIUibiSpcD1648DMU/ggTvP6r5PskhrmEMfRFEJKBcZfJPkjq4nQTA13vk338mHfuJDfOXOr/J7v/t7/M7v/A53fvlOfuqnfoqbbjhA8di1/2nZr5kU0YQlhz7XvukannrqqTW2snXrVpYXFrBmBH5+OBnA/CRxP0NJVjySZoo2DrLcbhu0eDTORONnxde3FUQLqoVmtMreS/fwzDPPnOBe5J/+6Z/+F/1dvZ9V7BqHiHDDtVdy51f/ktVRw9ZzNpMkMRo1HD16jAce/hbPPv0k/+N//941Wcr1CoNuvO4q7vjKetd7gr/3t98zkXJ8QpTJjBuuu5IvTxnf/Q9/i+effpIPf/DHJiqO9EPX/Yhd9UuWl5fZMD/ProsupJhDBEniOzaCWMakuNMsjp0znhzTSv0wRbL4yYCQyWgliJhTMzKZRty3cNhDJNgMY0ACz66H333ScRSHVSnCrZbdfzFpc4okFLHsvkEkBE0E6YSPfXxQrHDF/suZnZ3jttu+wHPPPcv73vdefuiHfpiVZrlNbLYJy4Hfm9uSn4jaFF47coScUuvnbd26lccOPsa27eehxXd/JO7LQAZgJRZ84+epZM8JeYwtIaKIRZpGxXNFLTvMIuye2LRxE48++ig7d+5c48/KPffcY5O4+11nvOsj1N/Pz2/ggYe/xaNPPUcTGHc4GLBvz0Vcc8U+VlZXpkrgTCrPrNf71pPPnnC9a6+8gqWlxTUOUx1T/VmfGbphw0buf+gRHn3yudavaMe3/3JWVpZPYOXW+6vX7CYcu9GUpmm47777+OAHP+h4NxYlSdr8gOGOY45TwCpIsRQwxkjqxi7iECCJY3MBj91L8viXKSlFrN7iG6SyrOp1OaVxEAlB1EPFyTzSVCkjmgSp2XGNPALBO2kMy0JW8YhW8VNpODvLp//g03zjG/diCDfeeAN/+8c/yOrqClgOLpZgA8NGKU6vOI0QhMzK8iL/9fOf58orr2QwGJBz5v777+etb/l+jh096rAzCNApbhMqRItTRVKHGBmcF6CYkSUjWlr+pNNrIodiwlNPP8WuXbvWJKoHXew+GAwYjUYnxPS78d9q3EtLi+zfdym3HLiBuVlP1qyurPLakSMsryxPrNfuhnL7hLKFhePs33cpN9/4Jubm58BgeWWFI0eOsLBwfM3i7BrytLrlhYXjXL1/H993043MzsyAwMrKKseOHWNxcWEq6a3PzO0nSFWV0WjE7OwsMzOzLC8teagTQ5w8FVljZ8B6bD/Ig2YkUaz4I1Tx06Sh+E4cxuIZcHdAU8Ak0+T2ihtWzYSj1NThScfhYM4dbne6fVcV8bCx5zpicanvvO2qix+bepSrFMgizM7O8h8/9Z/46p1f4f0f+HEA/ugP/5CVpRU+/KEPsTxa8XAxhpRUM6C+IFViDgqbNp3Tnso153HhhRfyyuGXyGmGOjtJxfliqYbFPX+hpiQKWIoNB1CFQYrTsqGIRLTKT+xk0ChA4Yr9+3ng/vvZu3dvaw+D7mmxsrLCYDBY44TWf3eNsJsPeeWVV9aVdekvvm7Uql88tLq6yksvvzy1sH+aSkh9NU3T+k0iwuLiIouLi+0J2K8zmERP7+Z2qvPdz3EcOnSI6667jtXVZTQZ0pgf81KZrNWgAuNWrlJSSolEWPL9WqWGOt2eJSlaguJhvusnEc/yV0ygRkkpiH+QRSnCScfhnCl1smM44BVIdVnBnnFOEfpMiBVUnMxYeWFZ3FP6/z77x9x5x528//0f4F3vfAdigpbCZ/7wM1yyezdveetbnL8lCbNC5cAUJ7d4SFoSS6Nlrrnmap555ll27tzJcDjk3HPP5eDBg1x2+RU0qytgQol5dNaDopactoLFCVyQLKhCSua+hQTzWD33YwKpcUaA/8ztbBRRs/bk6OPsLkTRoHj3C/Yn1Rv0/ZJJBSarq6troEr3c/XPmvnuQ7FJmfu+sMAkI+/WpPQTndMURGqCr8/6rD8/dOgQ73nPezh27HhEYzzk6Md6pX8bFbAIhonDJKhoxWLXTwFp1NdPY8EgFzT8Dv+AOwbOrjWPgKXKbfLo1CmNo15HPHFmUhgTVQh+lOOWLM641aCFWEtbj+cgyo/+yLvZtnUb3//Wt7G6OkIwfviHb2Xnzgu48c3Xs7K86idNzTGUoLlLxUdOiMwI1159NX/5l3exbdu29jkuLi4yPzvL8dUVSoNDtDjJLKBRI0YmkqXOcEQSFI2cShKkLowSSUlLkU+CZMbi4iLnbt/O8vIyMzMzbkt33nmnTaqK6lZx1aOuX7vcx+yTanq7MKpbfNR1quvu3F8wfQp5d7ev4+v6Al3o0/eX1hMHm1aLPEl8YWFhgZWVZd7+gz/IatOEPzDwya8bdXLoQwnqglR6OBFNcqhDOLbq22dEIiM513iUR8woyZ32XJ3sFDukuPtSKhnxFMbRJgZjx0ymIIM2CWkBO6xS4FNk7cVQC1jia6UNh1rOfgKotgnLFGOWDkFRTZyuUmodSaX1BNoYCF+548vMDGeYn59nZmYGVeXwK4fZef4FqFkEH2owISElnil+X77Ak/PQLBYzYNKQbNDys2rEziJQkFDO2bKVu+6+i71797q9dxNp/d247yfUnMC00Gw3kdNNltXPTitb7VZ91YRQn6zY/96+L1TDq30nvY6l+2fNldSxdU/Mfji3C+1WVlZ45JFHeOtb3sZodTWIbL4raTAKa8UFxTlOTlfxZJRU34DkcXuLRG6p4VdAszu+QZZTBSkOY6zu/MUJWaYRTTuNcfhxlaIOQ+Ik8ARhqZBNPOyMJFLkFDTGX0wpJUCYiI+ztaHY7ASsGRuemS+iZCCqEbiKMKv6ovRxKbccuIWDBw+2lBIR4YVDLzAzHJLQCF1bhzZSPKnZEjiDvqLmi5sCyfMeJpU640466uPT5Pe4PFohDTLD4dARQ3e3rYbdzRB3F0mfqj0pD9CFL12sXiM+1ZDrd9WfdSejv+C6pMWukXezmv3/uhCpe63uoqvjrYuq6WHOetp1v3N+fp65+TnMMpTShjOt3QE9ROvYPI5/83oKlRL1FIrzNSRyAJXFamBNLexzjJ78mqq+YFJxACZ4dvB0xqFBFycpUMhmlBw0k6CxWnJDdlqKnwR+gezcrmD+WkR+tN1/jUJARRM/tSg+1mSU8K80KCGkgiEeoFAfkqkyt2kD8/PzLVlVVbn22mu57YtfYLUUNm7cgBYfmgUb2BduHJfFKBRnAqRIXBZnKIuCNMWTirFo0eKUEwEdGcuLy2MbuP32260LfU6m0zRNm3Q9XdZazDIajRgOh+2C6Auk9X2e9dQpJtU+96HSYDA4IYk5TVh4Te1w+Br9U+PFF1/kyquuYu/eS50KkiQoHtLmCHJEhGosnRrPD6IgOaIl5rAJ8YSYJoWSUSnk5Bwqq5gjJUyLR4tybhm8vkA4rXFIMmiEkqSlswseyclSTxL3XzyRCGLF5QaiZLZSw2t+JuHObaJuAuo8KLF6i/V/Dgu1pk+C1hEOcRLP8D/1zFM89NBDnH/++QyHQy91Hgx44IEHKKUwPz9PaZq4txpVq5WINZIXLoJGwZa4RyZtrNzvQVGSed3LzOwsKQm7du0aEw+7jmyfaDiJRtENuU2Td+z/vMvd6i6++u8uhOpHlyoEqousr3LXvYd+sq7eU9c3miSjWRdJ9WO6i7DuYIcOHeLHP/B+ji0skSWyA6kWKKU2x13LUn3HcuydUoSjgk6NJqwUkNziYMtK1hTwSONKvggk+WJJgbFNGswyScopj6MN+yZjkEAbQwYNlMwwfKKSPN8S9u9JNcmIRj1HkByliEfGRoKm5KzxONMkxpCjTEDw7L1FWUESpWgIX2SLkoKoGMzC/iuu4Mtf/jI7duxobWJ5eZnLLrusjXh2Swb69tO3iYpQuqWw1fftRkyHw+GaIM2gL0ZQv7juntN0nLoZ9a5D3GXdttTfyHr2F0QdcH8xdk+P6kt0F0w3RNyv0OtH37rXn8TA7YsorK6unlBPXEphYWGByy+7jMWlZa+YK8kd5sDqKejfRkNmgBaPubvwgNKUQYxRIZnvxil2VC3+WREnFOILysSDrKoCNAgShU/J687l9MeRygCNYqriTA7PyquzcX0z953fiIRMtnEJbQ7elnrQQHMhaaIBp8cHLPOKkUqV0VYvQsy8ZiVqQ8Tpu2OonmBlZYX9+/dz5MgRtmzZsqaMtm8bw+FwzabaZ23X1+zs7Bok008kT5JYSl0j74ZtR6PRGojV3fFreLOLxfs+S5f+XXfe6mtMKputi6DrVPfpIX1fon5n15/o+g2T9GHrOJaXl9fkbUoprTJJHWddwE3T8MQTT/COH3oXpSmRqnP6tyexvKRUUMQG7luY1GgqiSF5UDynkSzwdZSamkQxj4dXsyWyQE7uvFrUwWrKEIVPOqgV36c/Do3TS6VGsiLWr2PlkAxYKo5zaiYcozHncGlAGEsgJUUdObhn4ZAmp2Acx2JHpBO50tZvMrE2ny1RHKXA277/bRw8eHCNXX237Sd1C4e6cKceMd2sdI3ydJ31SYXsdYDd1djdyfuwqgt3BoPBCSJjNRFZrzccDtes+vWUUvqJwvr+4XC4Jsxcd4+6+6SUGI1GHD16lAcffJD/4e/8HZaPL3nVWXCSPLTpLB1LbqopZGsQT4aliB5pyaTAtwWQQfAhtJCDqaqRlCtBabBhwnKJIiOLTDfQSOQrTn8czsNIHhUL6J0HOGwzJxUWEZJKsDIEy4ZJ9ipDrUojGg67JwuCKxwejuc1LIfJB8YXEY9WRZGXImQN1i+GpuSnWTGWV5b48Ic/zNfvvZejR4+uQTffLfuR27/0pdhCiAL6MUmM4J7Uyq5WmiU0kmqEo2oj1Z9JyLVU3GqRFfU5Cp+ge52uDx+7UJ3kVgFJWPO++pska+Vqqq+FdcbT+S4i4tJqRdXQUCSU3JeTljM1HA64+qorWS4N2VJ8jQYBLpMoQUWHAUKDix9U+ptj/cBI4nymAEvxQBwe+XXjHlJBtdIQ05hwh6JZSPo6xtFm68f3i4IFnZycQhBhnJF3H1yD4hIlsCpjxq6M6+NpqTIhAySKFKfiD5K11A93xI0qFlRTqV42HLkhEyQJDz74wASxD9pn1SGutQteqM+acRBhLBI2wZ7Hw2+t6/lDh2woQhG8drkaazUUBI00ewpqDClR1EXGqiZRq2IR0jE5HM+avZWITzsTMqInEb2oC0BDoCxJ8IoiopCCy+OsS6c1iPiR7xFFI6dQvqhiCjHlLfwQN6Lx/Xssp5iQrBpK5JJbdqrXSYiF1kegDM8ZBDkvplIl5igHLSMoH9XZFIOSa2WdeXVbZGpdWMfxuVRHH39fLFvPVai87nH4JsDaZ6WG5SBFVl6X1PmHsV5QhEQcCZcsAAAWiUlEQVTN/3S+VfIipBosE0FLzWRnf1Z4Vtp9J/WAXcpRvBVUrprIi/vGxpG2yOWf5FkJRdx+Bh6DeN32nCRKFyV2No1Yd12ViguMpZRiB/AEVor4u0VM2+LYN/Hj2LO6cXhGFVjoVDjetnqsBMUnDuVURS1IpOw7TqP12K8Lw5Nm7vA5dUDVs8MSnl8hwpKhzKfqIgWu3RScHgtjSw4l6s6SgtWKuhqHU9OkzbYWMyx1ggPm7FZJyZ1UBIsyToschguG+HcXxZN+kdmuQVdNJRJw1jlVtS2W+k6MQ8W8bDcMMhWjSfgmY8Vza6o+P8Hd0wjFWlQG1mNc8OfqGWev2WgipKzqBuf+T4kyFB9f0TzOktdEqLoWlpl4HQaN86LsVJ+VeaTvO2jPg6B6erRDIIdR13oD/02s+uQTSJvrdfwpUTBjA2sTR9IINlCkyWiuzM/sD0DMSS0mTkqzhKbiANpo2aClEXLc2LhYP7Kfgb/rSSvWtMk2y7G7hbSHVUigtcjIKMUX60iEQQOWa/DU0BIs2ahRdqLOd2aOihZee+UwRYsbQ3a2qmbIxb1hC1U3oQ1ZjRm7GnkFEXKLIYmEn4zRRYp6kXofFYIEydHLB4OK0RmHf5eChOYVY2q81edWhdrCc3B4GBC3as3Fs0rFoaDXllQYowEVfcMiiJh10Yt2TqzkTGE/GeS7OkeDFD5CSfFnOFxSAjRKwKIUxklGvC4TGRSk8aIXk8bLO1NyxuQgao6roYaRWlSEWZhiIlFaAw+tpMANKeHx8Ip5Ww5NPDj1YnpPPDmFuoqMWRz1VfAMgvgnhpVwxIrn5Er2IqEkvjMnySjFT6SUnX/0HZij44tHWVkdccnu3Zx9fe+/Btr4DuvUBW1hjiTfL1IpNAKDyNiqFefN+Kbv8Wp1LaVKoSdi89Iq7/lRlc0jKJqsfW9JNi7cJ3mMPRwlrUzTtoYldokorjZxcKniO4e6DIWvfMVLSXODufU7wcE8yVZq2FDHO3xj1SeSVr0jWUE1ofL65shILC6tsG/fZW3M/ezre/uVkBJVZo5HCacxyDruuJkTzqzSHrK4WFqFKWLkyOWk6kTWLHllZhYP3UXZekRliFj4uHorBSFMzOPdFllaB8w4F0Y8sqJVXdzEaxnCaTXxMkpxBVn/uqSh9FcimuEOutQQRUrOdkU8vBo+kNcCvP45SiI0zejswjiTFodLODaUCJ21YbzgpKSICnn9rbSliCYRprOE5OTOoLg2kJHIUQYq2aMKOVVpRtpoeKoymVLpy0FbSA66UjinxRLJ7RfLGUWcyyMOzCLC6pg4uUaTmKDZa4fropFU2miNk3BaXgdSwqlLige1amVdcvr2654j9zfOvs4gWEVxVW2rNc2iHg7P7qiJiDujppTqtBSw1CDmcXRWidqA8LOtuAYTTlOQKOUZkwIrv8ZFugbqWqzSOulxZBQNOU+HLSkcNi3GAEHzyIPDGkxRF0cKCqpiKaT7i7rwWBX6ipNINbtoQHJGJjmFbEsVFNOWkWq8zjkadRzDs68zBVa5wQ2DgpAkObOsRFSiCsdJxdgZyKHm4OFbBhG4SZW373FzHUR7lKBGWIT2UieLOtTIaUQtmvsblT7txDUlkzRXIqUnk5LnHyQWBknIqDvFklxVQ2sCLBYdCcmGWnJJTvFQoRYhDYKBKhGxyQRPKLVhz29njlxMwDVaObs2zjBYFUmdxqzF3yI1l5DaTKSiaEkgrhhHEmaGmc2bNjM7mHF4o5HOi2qvXEJu3/DC/uAQEU53FokkWxDGUtVX9TLHpDkUx+tWPBYTm8kDl6jJngjy/GotAfUQclRTen11VMah47BdUUgpBJ6DFaCUEAwzJGVmN8yxYdM8m+Y3QM7Vg4kkkTE7nJ06R5VHZHEAnV0bZxysiqysefioiDCIWmQstbyYZMllKkMndX5mA//3b/w//MnnPsett97K//qz/wuriwbZd+IaXUo11m8pdFIjc12MJJGbiOIUzFzvtR1P01bOEUS9lDOPPPQQr7z6Kju2n8cVV1zuSStxaUxyiCfXa5iHgEuQ5VxCMORhUE/IVapQUGFTSqwsL/E7v/uf+eY3v86RI0eYGQ65/PLLee973su1N1xPWVnh2OICn/+jz/P+D3wgAgedOTJXRS8mDCIjXSkjZ19nCqyKrKMUT+J5mt4CK9MamAZRKhnMzczyG//2N3jowQe56aab+PrX7yUxJCWLCJLDnMoZwlwNIqc4naQySR1Mlcp5CQl8SSn8F2lT+W5YnpRqSmHvnktJOfHoY4+ShkFYyzkSSNYqjbcyXuKEEq1Z+6iuz4RAcpw6szNz/Pmf/lf+3k/+JN969GG2bd/Gvn37uPiSSzh+fIGPf/IT/Itf+iWOHDvGRz/yc+Q8OHGOYuJUPNTbWGkTY2dfZ9DiKADFG5aIppYe4KJi2qrsIQ2iwuzcLP/+t/4D9993H9u2bUO1cPPNN6Ml5F5qWNZLgl260Wruo6qMp7arllrxgFHtHyFgxeVUUggwN5W8KL7INm3eiKJs2LQRBQ5+63FyErSx4PxUiFfpGR4CdqFwRTUFT6j4Yo6SycEg8cd//F/49Gf+kBuuvx5B2LZ1G9deey2X7N5N0YZ9+/axuLTEz/7sz7Jnz+4WgnbnyKNmrhiokS23s7DqzINViaalbZQcNGXR0AbKThxIgllhbm6WT/32b3P3XXezY8cOzIwtW7byD3/mH7K4shzdiYxG8IRfKzwfLMiiYeAaxfnFI0ollMilbY4HRaNqLXnmXDJWCkVgzyWX8sSTjzOcmWPzhs0cOX6EJ558kt2790TysJCCJtBUVTypQoBGyRp98ELmrHgTl8OHD/MHf/Bp9u3bx2g04qMf/Qh7du9meWWZLENKafh3/+Hf8/xzz3HFFVcE6zeoJDFHLvDhVBlVF1FGcoSlzxrcmeVz2ABSoYTSRAlYoCl7D4eggc8Mh3zmM3/A7bffwfnnnw/Azp07+djHPkajDefMDUNhI1rwBllNVVlcWvRdNFid3quCwP7aGo5ZioYr3gekcnA8cqWklMMHSly+7woee+IgOQ3YumULh189zLPPPsPFF+9qWxRr66iH6oc60SxriBCrO82ShJQGfPozf8TevXs5duwYv/iLv8imTedw7PhxhEQjixxfXOa+b/4V5+04b1xGGwVHqXK7teZSSnTZqnUTejaSe+YtDu82mkU6HYEyYh5gFVNSHvC5P/kTPv/5P+Oiiy5sDeOhhx7i3e9+d0igyLgntYybtm/cuJFf/79+nXM2nxPKEwnJ2tJKUu0BIerZZIWmKdx11x1ITuOWXLjgGSHfLyS2bN3Cls3nUFTZunUbrx0+zPPPvsCFF1zoY8rR6kqcqGgaogiR6fYwrUfWBnOzPPLwg2zffi6X7buM7du2szJaDSq28OLLr/LRj3yEiy++mKNHj3p8S4RmtQkWLeHZV3GxqvAXGFNbZvnZ15myOEwsIq+1j0EmpdKqSKDG7Pw8n/7MZ9izZ8+a6r9zzz2X8847b90vKKXhi1/8Eu99z4+5+28lEhgS7EpXscgpuzyKKK+8dIiLd+9hkMQ1YtMIs2FIygS1pOo6hR9hZLZu386hFw6x6+JdjJrGe3lHEZEnxx37ayTzarPHJmU2JGNpyWVZLrrgQlaa1SBOehRr1wUX8NnPfg60RPbeN4Dl0QrLxxfbXuKo530oNm4qGYIHdhZXnWGLwxVhnJEq4lDDosREjZShrK5y1VVXsbS0dNpfsLo6YveuXWhxDySJdy8ySSRV1LIr1WlpT565jZs5fuwIaWbW9Y0sk5JGHsPFYES974KKMDDH+0X9NGmaEs0nvejHlFbqsu19h4euNdiBRYW5uVnX2F1aIqsXz2jxSpOl0SrLr7ziaRJlXAVnRm6VA6tgW/FkYuuE51pOefZ1Ri0OCrkMKGmsnySB2ZNAo0JZXuEjH/kon/zkJ9bUY59//vlcffVV3tpM2sLTtrZPzNiydQs33ngTy6tLkSj0uolkng/IOHFPa2mjGlu3biJnf2+tx0gdSYFg/XPs+AJZ1DsUkVhZXuDSSy9DKYg5M9ijYt4FqaiQcnFNpWxYyd5ZVYSiDeeffz5NU7j77rv50E98iIWlBVqhm5JdtsYysxtmKKPG+wCKK3VX9JSTM38tNFqrOksKn+fs68x5ydPPPF116sPochSF+C5emyFIRGQ+8YmPt7W8zz77HH//7/8kb37zAe+akw1TbwxZBbUV7yCkVW81HOycDG0kmh5KW8stVVM1VUHxCO9aFMvgnKnXXn2Nlw4dYtu554IVFldX2Lt7D6Vx/ydngvIuURIqQYyM8leSJzsju52ScMcdt/OlL93O4uIiBw68mb/7d3+C5ZXlqGly3+uVl17iV37lV7nxxhv4n/7B/8xoZTWKZizyi937SO6UR4vjFw49z00HbjprdWdKnsOakFUxjQ6exYnehdDmHtdooIWPfexjlJDc2bXrIn7zN3+Tv/rmN5zuPYrrFHXcrRaG6Ht+MYNSEFXKyHMSpp4LMNShkXmyT83afm+VKFi1/I6+eoRnn3uGrdu3oRiLSyvsufgSmlGlo9decNCkWn9hjKJGo4QAcqNOFUmmFFPe8a53ISJs3ryZ2277Iv/q4/+Kl156iY0bNoHC5z77x/yjX/gFzr/gfP7irr9kNg+pnQHaA7VoKwEKhjVB3bez2fEz7uR48qknLJNbdQ9LtaC4qkDUckZvmSXJM9Sf/OQnWxmUgwcP8lu/9VssLi4g5CASWtCVkq+TWmgURfFAiHpVXaZg9YpHtCza9bbyjeIwaSYP+NrXv8auCy6ClFg8vsieS/d4F9bIp2RxkWLNtLXX0Zpi3M8uKPBaO8DEybi0uMSv/ZtfY252luXlZR5//HEWFhYYDAZccsklbN++nYWFBd73vvdx0803U7Q5YY6INsaVGZ+Sy8+8+PwhDhw4cNbqzqSTo2BRqFOiFtuL8FMIFFA0+jQ03p8tZX7+536e5RWP7uw4b4d/Pqjpg2gmoqqIGk2IhlkqFINGjSZOBFXvEJpKQa2BQqhIBPtcFGu8GaIUb86+aX4TBeP48aPs3rMbbUY0USCF+omgRKticzHjohpL1JeHJqUpTl+36HmtpmyY38A/+6f/hAsvuojRaMT+/fu5+aabuf6GG5ifn2eQB/zMz/wDvu+W76OUZuIcWaijazFUCqWRXlHX2dcZcXI88eTjZpJoJYTa5iJjwYFKwo7MhwscZKGMCnd/7S7edMONbJyb94hTkii2DwVwAaxBZNCWt0rkARSviZBilARZw1hTLcgfh4UsKvEkpPEXFo6zcdNm12K1VjmrrfKr2lOefmg1WECdS+b6JjZuqFgpLHhgYn7DPMeOH+eRRx7m6NGjzM7NcsnFl7D3sr0cO7rg2XCxqXOU1JuqJFwsLQ0yh154nptuOutznDmL44knDPHqORt4Ew/VHPUXIeyg4pSLUK3TkHMPcaiqTeFwJVH14d2g1ZyqHmL1Xq0aelUaurBZooVCrdgLmJNrfTmtTlGKL9boA6HiDUwkh8SPiod9XUCD1EQ31VSbqsQCiSYsYhJtvdplBGY0SRhaFc2JTqbqQoGCYqc4RzUhmtOAF188C6vOLFhFzYr7jq5BIdeooZBUQg3PXD+1lOiyGBhe3dFurGqQatvpE6JKLjXeQ6HVEKoOdpwQxXMY3qXHG40UDGk80lTEe+URkvtaqScWPSrCnyBgVJXsMUtobtqGj973O8iUNCGr0zj3KciNqr7gBhqkkLZ3hYXBW0uzP5U5MhOn47SaT2dfZ8zi0Ej21cahRLzes9niESh1yEEJdZCIHCW1tr2UiF+H6Nmg0RWxrbQTV6zTKmxEkPQ6X1xlHNUKAwnZzuR1TqUEEz3V0m9DdeCD01Atz3jVYTSalOLYvwRd3YoLOlSVESxakdnIGzhqRJWiM5IFrUXR1z1HVb3x7OsMSgIGEhmTG6L/AsGXkoznMGosn+QVdC01PYWyRwqZ+mjxS9u1xHddBMvFdYdLaRuyCDky8jXWFO1QrLiUTklRo+Rqikkt1MktZEejM1UIK9RbkFQV1r1iRC17UZVEaxcpURUYcEqhiPsz0nj0rKr6IfK650gH5ezaONNODqnE1xAIIKIsVVXDosmIR1b94edsnUIoGxtRLm1OoVXwVWtVDnNTF03VeM1eUpqsbdjYRKKvsg0zDmUkKSKlI1Zcuw+NW+VWX8ePIRdSbheLjFwNBD8NBiWa1BOOe/gG5rMShUoBM78Dc+Slv+msxZ1RPkfoQbmYQY3qgI4E1QYzx+Zq3uAU9SyzVawfjd2LetMUxXtEW/SK8B50OT4T6iMaHY5QShVIEPH6h+TizVWlRIMoWFTRIjTi/kkJyCYWbFtTirijXlXNVUucHrX/t2vrWiNOlykuueNhZ1opTO/zEi20NNqhvc450qawYX4Df3XffWsoOGdf38PRqscOPmYpFG1ShlSyc5kyUQvurXSlNBGFicBU1F20WlPquk2VLlLFvzUUsVPrRIdvUCKqU6nudY83acNg1tK9MySvIHRIpeTk6iWErGfkMaM/orcPQ1rdbvdtShrXkVeyjCilqrkXVzqR6NtXhcorn+t1z1HxnNIrr77KyspS9LUIXtkayFUZPbV1g7WdWaPXfCsKYViwVySawXTeYIzJjq3av7Tq7bWPNxEKr+OQWrIs2p6I1umjN+011oSvrSfCyOrvpBaGhSp7R4e3+px0tXbbga+9le/WHMljjx70pHg4qSqCyMhLSU1c87XqzVpoCIbUjSuXgKYQcDbI4vKZskauvmrcgmhGJSRzglflSt/RtsBcMsc0t4TDksbibN4ZKSrwxJCiHnatRVFt96DIrkdttySX1K+ZE4v0dTXmFCdUFonmMcEOiJyMiLbq79+xOZJOo4ToAe6+j7WLX6r5mDe7SUGt8QaQHgk0Fd94skb9irR+XKp6KTIOr0t0lR1InKhrxkGba5LiRNRstZeGz1OTooePpjVtjMfPKuar6kNXKqq6ovugfVZEi4BoU2AaWsUhB0vQ1uJ5EJWX3605annVIkKREp1Ds3cBjRZZIeCHiIuU1V3FzBscinn72kQJ/K2RSIwFIJVHFUVNRNutCN820SvDdbAij5E1yIdGrhQMIWTjSyvCTU7MRqjUhZ4tdi6NZF9oZsVNSLZxf47sLYNTZMyl+hrRMyKpRueMyHN8p+coKqBU1GnuGCWVttNq7R8jql6LbnGaRu9AojamCm1HcUtUZDZutBqSQeoVj2hBtbgGcJETx4GXAljxZ+bs6WjtXIxRSLYq6gvDAqKGwkpSIoEM0gQnwSo1SZgp3tO8RBsJgnemMVduG+NnpbUeJ/Fdn6OBVme0hmKJTp9tljlk4iWq8qLfRirxuTJuQqPRJqgemVrPqugYlELbqf62WHSASuIdf1o2cNDMq9+SQqbexp2anKBo0fsiGMSR3EvW0ERfDRkYTSPef1oEHakLrJVEoYE09Aw+CVd/tKCwZ3IqSBn4Qygh+fnXNEeSBt8T4zj7rMZzNPjKV75KbbLT9idogVhIeNZjrdvaqsrsmESuo9Mjq6NCMq61DvwvXdzr35GihUBtKmNRm60hNh05OMfHMZQkqdN2rYtvg9LRJiSqhm0kO10BoZUBSiYtDBtLhNSuFFVwOnlo+K9xjhLfG+M4+6zGc/T/A8/G/snZpSWJAAAAAElFTkSuQmCC);
+  display: none;
+}
+
+* /deep/ quad-stack-view > #chrome-mid {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAABICAYAAADRa1RpAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFycE5v9iFQAAAQtJREFUOMvtkjGSWzEMQx/0eYrM3v8k3vgqycalSwlI8Ufyl3OBFMtGIgUCIEd6PB6RBEASqvfONSrJXrDNbNkQ8ywA2y/SmayW+ZIESTsiyQsxo40xmMS2aUmYbheHpCVd0+UqJGGMsey3mUyldoUvlY3D9rIN0K7Wbe/WbZ+y1yWtaVtrp3VJzAEX6ZVjc2p7b2mtnYhNdl6m05rwtfV/ltx7XypJTpXeO7Y5juOlchzHaWxyrJmuhLapqgIJONv05+srThBgiQpBTSRwGOr3rwccgWHUhJ7P5/YNlbd/2XiL78L/WajP240AQUihfnx84EDJjCHKHjTAbkimQDgBjAJ1/3kHAgEk/gL71AHEWVXPGQAAAABJRU5ErkJggg==);
+  display: none;
+}
+
+* /deep/ quad-stack-view > #chrome-right {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAABICAYAAACaw4eEAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyghKmOqnQAADE1JREFUaN6dmsuyZsdRhb/M2uf07bREYDykPeIleAMibNx92i9BgEPBgyB5xlvgtgI8VDNBI41xhGkpQowERgqw3H0ue1cuBlm1T/3Vu4XNiWj9l12XrMyVK1fWL/v6668lCXdHEt/1Z2YnnyUhCTPbX8dn45pmRkR81z7/XUr59Pz8/K8ePnz47/bVV19pnDhu0t+Pmx0Z+Pv8zWv1/eZnZ2dntw8ePPizZXw4bj5/P3vq6G/eePZiX9fd9/Xng6/reg78/dInzxPG9+/auH83GjEbPUahj6m1Hoa6v1/X9c+XPrlP7INqrfuru7+10WzUkUHvOtTojPF1mPdHSzdqPPXo5vm046bdq0fhGr+bvXZk6OgAM2OZBx7hZD7hnCzbtp149Wid0YOjx+eE6t8tMzb659Ebkg5PPY8ZvXpEQWNCzck2M4H3BWeM1Fr31/6+GziPmTefM3tcYzQoIt4a3+cso2EzhsYTzAAdw9M9M3rviPv683dl/Oi9pdZKKeVk4piVRyDu1NI3mCtARFBKeWeGbtt2yHV9HXdnGUMyGjSfZq4K42ajYbPXx836XjO+jsj3rawcFx5dPgK8bzJ6eGbzI8yO3j4yaMToiWF98fl0c4bNSXBEJ/Ozd1HSEY8BLGOIxlONeCqlnHyWtGNoxteRMX38uP44fkyyPnfpp58zqy/s7jsGj0rOEcvPVaMD/sj4I/zWWllmMB/VviOwHumv+dkRGc9EOtOUu6fHZteOGBtDN/+NeJwPNRsxl54RU3PIO4x827a3wNwfdr45kib92WhAf9+fHem1I7FZa31rr+WIr45kzrjZsixvZWHHYcfqXFHGctM9ta7ridcigmVZWNf1DvyllN2wkatmHIxCby7kYzbPOD2qFCN39efrut55rE8YM3I+8VENHPFVa2VZlkOSdXe2bTuhmHdl+W5ox8T8YCbD/l2t9YQqRiNGjx8l1JEamVXKri56doyTuzfGhWd+OyLJjsNRlo+eHaX63Iy8ldnjQn3hbmA/yagGusfG7JwrxZytcxMyjpnH77VyPEEP65iVs5tntp4ldp8zlrG+x8z2Y9L1f91Jy+zeccGZn0Zv9nFHTH500BGbM6HOojMiWEZQf1cN7Aut68qyLCdeGFN+xuRYJ7tXu5fetU9EZCiPOp8xm8bTzLqpe2jkoDnzxjCOa8/VZByzzG7t8gQ4eT+GdO4Be0kZDTgq5kea/0g0RgS+rushNkbg93o6aqeejUeNR/fcUWmaqWLbtn39MdGWGcRHUrcb17E1jhszq3tvxNCsJuaE6VGZMbeMKTrL6LGelVL2k41jx6zuRbknSS9BI7WMdDRTxLi3z+VkDl3/7vb29oS3xhoZESdZOm4whrW/7/NHT83UtNze3u6c1I06Ozs7wdjc7PaQzsV8JNSOp7k97IDvtDPDYTdsvts6Pz8/MXCsm2PD2g/Tm+Vx0bHZHTNvjMyRyh2pajk/P0cIZEAHLLgXQLg5ckDCAFsKCwtIeHHAQGAmSnEkMAyZMBkin4lc3jBEM4a7MZgo7mBGhLD/+M1/qiCqDJflIjICYbknjlEtQEl81cBDYIaUi3aDwoEQ7mABuFMjcHOMQHLMRLSDhhlFQk4+k9IhLggZBREeVLN+NNwNCAhRwjGMimGyPJlA3owyIwiKEltWjTBHNchIGpLleIS5ITNKQHVDYRiBGUQI/83X/0XUyorhm2EKAsvT1IqFgwusgglCWARV3SuGmdNchwgiRHWQagcHIqCNJ7whJ6AI20AeUJ3A0ilP/vQJ33zzDdvNDbWkO91oAwphrah7wVGG1cHMqSHkggiwDJthmAcgjIIVg5rfWc1h2AZ7AgBLpMElMpQCUyOSX/3rr/j+9/+EGoEQTgKxKnDADRROmCiWySJBeILbMCxENVhwBISCnldm4EBEeiQRk1AJs/Y5ER2q7BX03v17SQnumDeXRqXgDaSA1cSdIExQDM+UgtoArTyMIjABJUPt4S2hRHEIgbdstV5LI4OusDvDMgMNqw3sHqi0HPcMotyRNqp5ArnmRrkLuBm4kHmjDAeEDMICk2PFMwomqjI2xYSHsJIUUnxoeBO7rdQUJ2qeJk8SLfdLGtgWCouEVzFUG7NXMAXVG1YqyDdMhSDgFuTpabUEiUguUw3AiAafbhoR4EtmpJknKArgytMaBHBmIozEIQ41M1dK7ySGEvxQ8NoI1w2WFh0XlsUaFYilJ5zhpuGKwBxXeygIqxlrE6Ih1wKPgi8L799/QGcJo4M5o9oYDfcKUZJmEFdX12zrikh2xwwrQA2KOeqETRlCGaKaUFXLpjQwy5Elu4dzflb4uw8/5MXP/wEsE6ORVX8hbVRzTVcN4ic/ec4HH3zA7XaTC1sQtZUXAm98Z7I7uvjii8+5ePw4pUiwu7TXuogM3cX7j/jhX/yIJz948gf/NPjll1/yy1/+E//z299RCGrL+AxI8krQfhk5Ab+6LmrGyDA1dvfkqOvXNzy7fMonn7w8umjafabmsDuowPPnz3nz5joLiN9VCwIqJDGHweixV59/weNHF4itZSMJbGq61kg3h3N2fs7D9x7jIdTwIzw3tCxrZo560U5U8frNFdu6URWJS8RmRukto3smv07uxwJrMa9uLDJCG1ZKI87AWJBvhEOsG9WEhSVcWBtu1A615da2kboiPaRW4hSRcBGEClhg0cTDycWdJR1XgUdkrN2hRqslGapydo+fffgRL37+Ir1opzrrJHZDAiB49vySv/3gp9zcRiqLCpsrjSLrnpQ27KH8/ItXPHz4PtRbRMoTajrBw6Hk4o8vLvjhj/6SH/w/wf/xx//I629/u9fPjkxLIZfVwmLwWBhQqUqgU1NZlCrkQVRwGW9urrl89pRPXr78gw27vHzO9dVVI2cIOYVIGHkrYXVDUQaPvXrFo4tHbFV7dnkjzGT+5BjXwnK/cPHovcRLI9hME3ZeM2+HtRwQAVdXb1ivr6ldzfYC3sSnPFAUZHW+HE7WtqamZL07avrcnYgKKtR6m/VKQTR9n0JQjZj7KqD2LCLY2h4quqsKNUWA5BQPatjAY1hTpuAO2iqlGLV1EQJ8C87vnfOzjz7ixS8+5vf93y+sFeZnl5f89K//htttw1bAW5d05rAK90awjOD//BUPHtynblmInXStyUHJR3jw3sV7/PjpU548eXJArvZ/gv/Fx7/g9bfftug4NfVKa7byd8pN9ZT5I9rFSM/wSPFXrOn5Tby5vubp0x/z8uU/t1Jx5/H9v3b3/q4YGJfPLrl+c0Pde8lgEWxN0znG1jG6e+zfXnHvwQNETdmMINqlSEeZJ1Dvn93j4uJiL+6jv8TQO9L6lya9f/fta26228wodVwZboFU2gLbqbqglZLarzTbdpvBEhWxNJI1bq5uuV6/SRCHt35AyAwPo5aKZzlIHRb5SqTR1nRSnitQtC4phNlyqvlTppRUlmZEQJizhCErbYSa57J8SNkLRm3s7RV54AHymjK9cYjUyg+wqV8XRCtfdzea+IZiFIoSsFKBEm1SE26SpXZCeDh7g9P64R4SrU2ZkC1btea5TMDsqCJ5UfUuZwO1BlnZ6tkgrWWWqjOgqhJmsLWa2dowsKZK0nuKlMWokWWBoBIeiJpZF6CqhtnMdHSHW6PdZLfijjISu2HX11dEjURrTza3BtymzaLV5NZwEGQYW4ekaLdCkXSDRCkidr2n/XKGUlOKjxc6oXZN0H4ZefXrVxQ3atTsjD1lkJpIDNEwlSCRZ53rp4zViNiQtqwEStHT1YoUOaclSY1MmmjXCelNz2Q1T5L/7LPPYDEePXqYNa0ENHnd7xeKKUFiAO2HBM97DZMoS1prMmQLrqCE8uZHIgVDNAFpFEW7BnGKWQtnYJ6GOmL54+99D0JEzfT1alRzikHtda+1/4nsxk/VqQZmlXXzJMUiqFu7nrJMe8v2LhteteuAvEcrVqk1m+Owdn9h7ZYSE6WAIrkjPCVIFua8s0jhWHfhZ5YZZ6rZNxoplZp3clg2uUSKAcmwYpgqUs1iFI5Z4rr3mliq3IVqVDbwM9CGkao1rN1IR6F4xepCEFht1wAhIKjRNH0Dv6ym5lHrEQw8JSlUtapghHJ+qiK13OyZ6yyf/sunSYqyVuPavVVq3bvSgrKxcKVGU7/s1U5ovXz1W5v9ftPVet68cbSehRo65ZNfUuB/AWHLchVUWJtFAAAAAElFTkSuQmCC);
+  display: none;
+}
+</style><template id="quad-stack-view-template">
+  <div id="header"></div>
+  <input id="stacking-distance-slider" max="400" min="1" step="1" type="range"/>
+  
+  <canvas id="canvas"></canvas>
+  <img id="chrome-left"/>
+  <img id="chrome-mid"/>
+  <img id="chrome-right"/>
+</template><style>
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view {
+  position: relative;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > top-controls {
+  -webkit-flex: 0 0 auto;
+  background-image: -webkit-gradient(linear,
+                                     0 0, 100% 0,
+                                     from(#E5E5E5),
+                                     to(#D1D1D1));
+  border-bottom: 1px solid #8e8e8e;
+  border-top: 1px solid white;
+  display: flex;
+  flex-flow: row wrap;
+  flex-direction: row;
+  font-size:  14px;
+  padding-left: 2px;
+  overflow: hidden;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view >
+      top-controls input[type='checkbox'] {
+  vertical-align: -2px;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > .what-rasterized {
+  color: -webkit-link;
+  cursor: pointer;
+  text-decoration: underline;
+  position: absolute;
+  bottom: 10px;
+  left: 10px;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > #input-event {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMnwAADJ8BPja39wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAyNSURBVHic7Z1PTCPXHcc/4wWWVbJN2cJSLVqiQJuGpoIGEVWReoBNIlIF5RCRSysOK9EbksUeOHLIIQcULbLEEYk7oqduD6gSRoqUEyK7dCOabOHghCiAE/JntQtesHt4fuM3z2+MZzy2x8ZfaTTjN+Px4/fh9/7Pb6xMJkND4VGk2hloyKkGkJCpASRkagAJmRpAQqYGkJCpASRkaqp2BvzKsizf3w1z38sKc+ZUaQCuAFeB57P7q4AF/Kxsj4GnLrfL+6PDYofQAskCaAJ6gJeB6+QAFOvZpwgwPwOHwCNgN5uu/+H252raJHRALMu6ggDwCtALNAf8E88QUL5AAHqSTVcNUTU4oQBiWVYzMIiA0E3lGhtp4CsEnPtACgFDGqXiYKoKxLKsCPAaMIwojlzV1tZGV1cXHR0ddHR00N7ebh93dHQAcHh4aG/JZNI+3tvb4+jo6LzsPAY+QYA5Ix9KBsoPpmpALMt6BXgTaHe7pre3l5GREUZGRujv7/fdsspkMmxtbRGPx4nH4+zs7BS6/HtgHfgvOW9xeE05bVZxIJZldQNvATf1c5FIhMHBQYaHh7l16xbd3d1lyUMikWBtbY319XU2NzdJp9Omy74B1oAEAoa8yIZTDttVDIhlWZeB94Dfm86Pjo4SjUbLBsFNiUSCWCzG6uqq2yVfAv9CNKHTlNlbKgLEsqxrwF+BX+nnhoaGuHPnDv39/WXPRyFtbW1x9+5dNjY2TKePgBXgOwQUFUyg3lJ2IJZl9QAfAK1qek9PD9PT04yMjJT1970qHo8zPz/P7u6ufuoE+CewQw6Kw2OCsGVZgViW9SdgFNGLBqC1tZWZmRnGx8eJRMI5lJZOp1lZWWFubo7j42P1VAZR4W8gWmJn5KBAAEVYWYBkm7PvIvoWtjo7O1lYWKCvry/w3yyHtre3mZqaYn9/Xz/1EPg3ot+iQslQIpTAgWRh/A0x5GFrYGCAWCxGe7trKzeUSiaTRKNRHjx4oJ/6CvgHoigLDEo5yox30WCMjY2xtLRUczAA2tvbWVpaYmxsTD91E3gbMbTTBFxCFM0WYPntMwXqIdk64x3lM9FolMnJycB+o5paXFwkFovplfcniDrlNLvJXr4vTwnMQ7KtqVE1rZ5gAExOThKNRvXkPyMGQaWXlOQpgQDJ9jM+QGlNjY2N1RUMqcnJSb34shClwnVE8aVCAY9QSi6ysj3wv6N0+gYGBlhaWqKlpaWke4dVqVSK27dv6xX9j8AyYpDyGaL4svsqxdo5CA95DwVGZ2cnsVisbmEAtLS0EIvF6OzsVJNfQIzRlVTJlwQkO1Boj021traysLBQk60pr2pvb2dhYYHWVscAxEuI1pcKJYIHKKV6yFvqh5mZmZrp9AWhvr4+ZmZm9OQ3MAMpSr6BZOcz7CH0np4exsfH/d6uZjU+Pk5Pj6PbdR34LT69xBeQbG/8TTVteno6tGNT5VQkEmF6elpPfh24TK7VFaFIKH4t+BrKTN/Q0FDoRm0rqZGREYaGhtSkXyDqVs9Fl2cg2QUJw2ranTt3vN6m7mSwwR8R68dULzm31eXHQwZRFiSMjo5WfXIpDOrv72d01DFQcQXoQ3hI0V7iB8gr9pcjEdNQwoVVNBrV69EXcanccfEST0Cyi9jsSe/BwcGKz4GHWd3d3QwOOqaAOoDnMFfuRnn1kJfV7wwPD3v8ev1Ls4mF+Ac2FVsW5C8aLxpI9ou/U9Nu3brlOcP1LoNNbuJej+R5ihcPaQJ+Iz/09vY2iiuDuru76e3tVZN+jeiTyFHggsWWFyA9KAufL3K/4zxptrkE3MClYkcDUxQQU3HVAOIug226yHlIXvNXrUe8eEiHPGhra2v0PQqov7+ftrY2NekFzEVWSXWI3Rns6uoq6ZGyepdlWXR1dalJrRTwEFVegFyVB3L5f0Pu0mzUirC1CsPoJcUCuYLyGFkDyPnSbBQhB8VUZNm99nOBZC+8qqZdhBnBUmWw0RXMQHx5iOPpprB5yMbGBp999lm1s+GQwUZXKFBUSRULxOEhYQNy//59Hj58WO1sOOQCpGAfBOoESBhVwENMm61in/cOXRt3f3+f09NTAH766SdaWlrY29sDoLm5mevXr1cze25y9QypYoH8rH44PDwsIU/B6KOPPrLzcXBwQCQS4dNPPwXgxo0bfPzxx9XMnslGJ7h7hkX2GZOaBRKLxezjxcVFLl++zMTERBVz5JTBRseGy3zXIaEDEna5eAgENIX7WP2QTCaL/NrFlcFG0kMKLvIttsh6ilg83ATh85D3338/dGNrmo3SiAXYuvLgeImX9Rj4peHHqq5r165VOwt50mx0gjkqhJT92cvgol2P7O3thSa+VBiVyWTsJnhWsv4wBrZR5QWIjfzo6IitrS0vebxQ2tra0oPdPCbfQ4ze4gXII/VDPB73k9cLIYNtDnACUJ9td8gLkF2UiqkBxF2abc6AJOboD3lQzgWi1BWnCCgA7OzskEgk/Oa5bpVIJPTwT9+RCymoe4jvIkt+8Qs1cW1tzVem61kGm8jiKk1+gIE8eV25+Ihc3CjW19c9fr3+pdkkgwCiwsiL+oDyUKhXIE8QISUA2NzcbBRbihKJBJubm2rSD4h4KLLuOMMQRUiVn9XvdrGVTqcdg3wXXbFYTI9Op3qHuqlQHCoKSNadJNH7KGNbq6urjT4Jou+hRaVLIUoTE4zA6hD5Q5+oCXfv3vVxm/qSwQY7iG6C9BAZByWv6auOevgBIr3ke5mwsbFxofsl8XhcDw34BPgaYXg1KI0p6JlDRQPRiq0zRGQ1W/Pz827RPeta6XSa+fl5Pfl/5LxC3QrCAP9P4WYQcW2/kQm7u7usrKz4vF3tamVlRY/P+CPwLTlvcANiDN/kCYjiJXLv6AXNzc2xvb3t5ZY1re3tbebm5vRk2Vc7JReExgTDqFI8JIMIMvylTDw+PmZqaupCzCgmk0mmpqb0IJkHiLpV9Ypn5MA4oJimMDwD0eqSDCLIsD3WvL+/TzQaJZVKeb11zSiVShGNRvXgmE+Az8kVU8+UrSjvgNKCz8jxmaeIIMNyEoYHDx4wOztbwq3DrdnZWT1W1imi5XmCE0YKlyLLbYLPFxDlZhLKd4ggw/aJe/fusbi46Of2odbi4iL37t1TkzLAfxAzqmc4PcPkIQVVqofIfRrREVpXL4jFYnUFRQbB1PQIMZsqYaSUraiWlaqSQvxlV3rIFd2XEIsm/gL8Qb1ubGyMDz/8sGajzKVSKWZnZ3XPANHs/xxh+BSiyDrObifkirCiiisIDogK5TIwjvY6ijoMpHwEbCJAPCMHQIWhxl4sKmxsEEEwwQmlCQHlbeBV9do6CjX+DbBNDobqHSYYRQfCLDnimKEZfJbN0CpiENLOxf7+PhMTEywvL4d6mCWdTrO8vMzExIQOI4Pod31OPowTzHWHpz80kMjWyqpB6SXSU5oRQYbfARwVSA2+ruIU0ZrSK/ATnEBky8oxqlusnQMLNa4VXRa5Sr4JEYdwDPG8tkM18kKXJ+TmgWQ/Q3qDDsNTJa4r6NjvkA/lEsJTnkdEMX3J9N0Qv/LoAFFEyRaTbFFJGPK4ZBhQntdVgDuUZkTr6w2E1zgUspeC/YjoY3yPczgkZdhk568kGFC+F7qAE4qsU2S90owIpfo6ImCkUVV6bd4TxHzGtzgnmNThEN0rHK0pSngFUtleeeQCRa1XmhHN41eBAcRDka6qwIslU4jRhq/Jn8tQh0HUitttWtb3YvRyv4MKck8MyUeCZRGmeosMGPkiIshNpR72yCCW6hwgFiTI1pE0tDS6abDQ87BIMarEW9rAGUFNNot1MHL/HCIs3k1E8K9LAWfpDDEYepDd5Lopdc5b9Qx9r14nx/EgABhQASCQ109RizAdjApH9vhvIOJNvYCIFyJjhhSjNLlm6WMEgCS5tbbqAjbTlKsKwwTCHmCtmfcY2j/khCL3auwPNXyRGqOwifzQRq2IYk7dwDl8cYwwpjoqrRrSDYYKpdCaqpLrC5Oq8S5c+xCzx+hwTJtbEBdT3aMbUBpVXWvrtsnz+op1CNArVFXlbdEu3mICowJS9+cBsR/Exx2IaQG0af1tHggI1itUVft96vahsi/kOabPxQCRe93IaW3TAVQMhFRVgdiZMIORexOgQiDkXv3DdAObPMYIgAqBkAoFECmtJ+4Gp9Ax2rEORe51w+sQ7OOK17FhAqLKBY567AbBTSY4rsfVsktogagqACfvUpd0tz/SkR4GW9QEEFVBhtAI499ec0DqXf8H8f4X10jf2YAAAAAASUVORK5CYII=);
+  display: none;
+}
+</style><template id="tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template">
+  <img id="input-event"/>
+</template><style>
+* /deep/ tr-ui-e-chrome-cc-layer-view{-webkit-flex-direction:column;display:-webkit-flex;left:0;position:relative;top:0}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-tree-quad-stack-view{-webkit-flex:1 1 100%;-webkit-flex-direction:column;min-height:0;display:-webkit-flex;width:100%}* /deep/tr-ui-e-chrome-cc- layer-view>tr-ui-e-chrome-cc-layer-view-analysis{height:150px;overflow-y:auto}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-view-analysis *{-webkit-user-select:text}
+</style><style>
+* /deep/ .tr-ui-e-chrome-cc-lthi-s-view{-webkit-flex:1 1 auto!important;-webkit-flex-direction:row;display:-webkit-flex}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-e-chrome-cc-layer-picker{-webkit-flex:1 1 auto}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-b-drag-handle{-webkit-flex:0 0 auto}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view{-webkit-flex:0 0 auto;font-size:0;margin:0;min-height:200px;min-width:200px;overflow:hidden;padding:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view.hidden{display:none}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view{display:block;height:180px;margin:0;padding:0;position:relative}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view>.use-percentile-scale{left:0;position:absolute;top:0}
+</style><template id="tr-ui-e-chrome-cc-picture-debugger-template">
+  <style>
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger {
+    -webkit-flex: 1 1 auto;
+    -webkit-flex-direction: row;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-a-generic-object-view {
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+    width: 400px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel {
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+    min-width: 300px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel > picture-info {
+    -webkit-flex: 0 0 auto;
+    padding-top: 2px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel >
+        picture-info .title {
+    font-weight: bold;
+    margin-left: 5px;
+    margin-right: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-b-drag-handle {
+    -webkit-flex: 0 0 auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger .filename {
+    -webkit-user-select: text;
+    margin-left: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel {
+    -webkit-flex: 1 1 auto;
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel >
+        tr-ui-e-chrome-cc-picture-ops-chart-view {
+    min-height: 150px;
+    min-width : 0;
+    overflow-x: auto;
+    overflow-y: hidden;
+  }
+
+  /*************************************************/
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger raster-area {
+    background-color: #ddd;
+    min-height: 200px;
+    min-width: 200px;
+    overflow-y: auto;
+    padding-left: 5px;
+  }
+  </style>
+
+  <left-panel>
+    <picture-info>
+      <div>
+        <span class="title">Skia Picture</span>
+        <span class="size"></span>
+      </div>
+      <div>
+        <input class="filename" type="text" value="skpicture.skp"/>
+        <button class="export">Export</button>
+      </div>
+    </picture-info>
+  </left-panel>
+  <right-panel>
+    <tr-ui-e-chrome-cc-picture-ops-chart-view>
+    </tr-ui-e-chrome-cc-picture-ops-chart-view>
+    <raster-area><canvas></canvas></raster-area>
+  </right-panel>
+</template><style>
+* /deep/ .tr-ui-e-chrome-cc-picture-snapshot-view{-webkit-flex:0 1 auto!important;display:-webkit-flex}
+</style><polymer-element name="tr-ui-a-sub-view">
+  
 </polymer-element><polymer-element name="tr-ui-a-stack-frame">
   <template>
     <style>
@@ -460,502 +849,166 @@
     </tr-ui-b-table>
   </template>
   
-</polymer-element><polymer-element name="tr-ui-a-related-events">
+</polymer-element><polymer-element name="tr-ui-e-chrome-cc-raster-task-view">
   <template>
     <style>
     :host {
       display: flex;
       flex-direction: column;
     }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: row;
-    }
-    #events {
-      display: flex;
-      flex-direction: column;
-    }
-
-    </style>
-    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
-    <div id="events">
-      <tr-ui-a-related-events id="relatedEvents">
-      </tr-ui-a-related-events>
-    </div>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-a-selection-summary-table">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
-    
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-multi-event-summary-table">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
-    
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-multi-event-details-table">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-
-    #titletable {
-      font-weight: bold;
-    }
-
-    #title-info {
-      font-size: 12px;
-    }
-    </style>
-    <tr-ui-b-table id="titletable">
-    </tr-ui-b-table>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-event-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      overflow: auto;
-    }
-    #content {
-      display: flex;
-      flex-direction: column;
-      flex: 0 1 auto;
-      align-self: stretch;
-    }
-    #content > * {
+    #heading {
       flex: 0 0 auto;
-      align-self: stretch;
-    }
-    tr-ui-a-multi-event-summary-table {
-      border-bottom: 1px solid #aaa;
-    }
-
-    tr-ui-a-selection-summary-table  {
-      margin-top: 1.25em;
-      border-top: 1px solid #aaa;
-      background-color: #eee;
-      font-weight: bold;
-      margin-bottom: 1.25em;
-      border-bottom: 1px solid #aaa;
     }
     </style>
-    <div id="content"></div>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #content {
-      display: flex;
-      flex: 1 1 auto;
-    }
-    #content > tr-ui-a-related-events {
-      margin-left: 8px;
-      flex: 0 1 200px;
-    }
-    </style>
-    <div id="content"></div>
-  </template>
 
-  
-</polymer-element><polymer-element extends="tr-ui-a-single-event-sub-view" name="tr-ui-a-single-async-slice-sub-view">
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-async-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    </style>
-    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-cpu-slice-sub-view">
-  <template>
-    <style>
-    table {
-      border-collapse: collapse;
-      border-width: 0;
-      margin-bottom: 25px;
-      width: 100%;
-    }
-
-    table tr > td:first-child {
-      padding-left: 2px;
-    }
-
-    table tr > td {
-      padding: 2px 4px 2px 4px;
-      vertical-align: text-top;
-      width: 150px;
-    }
-
-    table td td {
-      padding: 0 0 0 0;
-      width: auto;
-    }
-    tr {
-      vertical-align: top;
-    }
-
-    tr:nth-child(2n+0) {
-      background-color: #e2e2e2;
-    }
-    </style>
-    <table>
-      <tbody><tr>
-        <td>Running process:</td><td id="process-name"></td>
-      </tr>
-      <tr>
-        <td>Running thread:</td><td id="thread-name"></td>
-      </tr>
-      <tr>
-        <td>Start:</td>
-        <td>
-          <tr-ui-u-time-stamp-span id="start">
-          </tr-ui-u-time-stamp-span>
-        </td>
-      </tr>
-      <tr>
-        <td>Duration:</td>
-        <td>
-          <tr-ui-u-time-duration-span id="duration">
-          </tr-ui-u-time-duration-span>
-        </td>
-      </tr>
-      <tr>
-        <td>Active slices:</td><td id="running-thread"></td>
-      </tr>
-      <tr>
-        <td>Args:</td>
-        <td>
-          <tr-ui-a-generic-object-view id="args">
-          </tr-ui-a-generic-object-view>
-        </td>
-      </tr>
-    </tbody></table>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-cpu-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #content {
-      flex: 1 1 auto;
-    }
-    </style>
-    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-time-slice-sub-view">
-  <template>
-    <style>
-    table {
-      border-collapse: collapse;
-      border-width: 0;
-      margin-bottom: 25px;
-      width: 100%;
-    }
-
-    table tr > td:first-child {
-      padding-left: 2px;
-    }
-
-    table tr > td {
-      padding: 2px 4px 2px 4px;
-      vertical-align: text-top;
-      width: 150px;
-    }
-
-    table td td {
-      padding: 0 0 0 0;
-      width: auto;
-    }
-    tr {
-      vertical-align: top;
-    }
-
-    tr:nth-child(2n+0) {
-      background-color: #e2e2e2;
-    }
-    </style>
-    <table>
-      <tbody><tr>
-        <td>Running process:</td><td id="process-name"></td>
-      </tr>
-      <tr>
-        <td>Running thread:</td><td id="thread-name"></td>
-      </tr>
-      <tr>
-        <td>State:</td>
-        <td><b><span id="state"></span></b></td>
-      </tr>
-      <tr>
-        <td>Start:</td>
-        <td>
-          <tr-ui-u-time-stamp-span id="start">
-          </tr-ui-u-time-stamp-span>
-        </td>
-      </tr>
-      <tr>
-        <td>Duration:</td>
-        <td>
-          <tr-ui-u-time-duration-span id="duration">
-          </tr-ui-u-time-duration-span>
-        </td>
-      </tr>
-
-      <tr>
-        <td>On CPU:</td><td id="on-cpu"></td>
-      </tr>
-
-      <tr>
-        <td>Running instead:</td><td id="running-instead"></td>
-      </tr>
-
-      <tr>
-        <td>Args:</td><td id="args"></td>
-      </tr>
-    </tbody></table>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-time-slice-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    #content {
-      flex: 1 1 auto;
-    }
-    </style>
-    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-instant-event-sub-view">
-  <template>
-    <style>
-    :host {
-      display: block;
-    }
-    </style>
-    <div id="content"></div>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-instant-event-sub-view">
-  <template>
-    <style>
-    :host {
-      display: block;
-    }
-    </style>
-    <div id="content"></div>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-counter-sample-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-    </style>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-</polymer-element><polymer-element extends="tr-ui-a-single-event-sub-view" name="tr-ui-a-single-flow-event-sub-view">
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-flow-event-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    </style>
-    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
-  </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-instance-sub-view">
-  <template>
-    <style>
-    :host {
-      display: block;
-    }
-
-    #snapshots > * {
-      display: block;
-    }
-
-    :host {
-      overflow: auto;
-      display: block;
-    }
-
-    * {
-      -webkit-user-select: text;
-    }
-
-    .title {
-      border-bottom: 1px solid rgb(128, 128, 128);
-      font-size: 110%;
-      font-weight: bold;
-    }
-
-    td, th {
-      font-family: monospace;
-      vertical-align: top;
-    }
-    </style>
-    <div id="content"></div>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-snapshot-sub-view">
-  <template>
-    <style>
-    #args {
-      white-space: pre;
-    }
-
-    :host {
-      overflow: auto;
-      display: flex;
-    }
-
-    ::content * {
-      -webkit-user-select: text;
-    }
-
-    ::content .title {
-      border-bottom: 1px solid rgb(128, 128, 128);
-      font-size: 110%;
-      font-weight: bold;
-    }
-
-    ::content td, th {
-      font-family: monospace;
-      vertical-align: top;
-    }
-    </style>
-    <content></content>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-object-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-    }
-    </style>
+    <div id="heading">
+      Rasterization costs in
+      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
+    </div>
     <tr-ui-b-table id="content"></tr-ui-b-table>
   </template>
+
   
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-sample-sub-view">
+</polymer-element><style>
+.tr-ui-e-chrome-gpu-state-snapshot-view{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAEwATABMYqp3KAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90JCQsBMCH7ZqYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAUElEQVRYw+3WwQkAIAiF4Vc0hTO5/wiuURvYIcQOv1cRPhDlDXffSsrMsrYiQi/zU80FAACAVX3nt3lWAABA/x+ovnPyAAAA5AHyAAAA3wMOd34Xd+lsglgAAAAASUVORK5CYII=);display:-webkit-flex;overflow:auto}.tr-ui-e-chrome-gpu-state-snapshot-view img{display:block;margin:16px auto 16px auto}
+</style><style>
+  * /deep/ .chart-base #title {
+    font-size: 16pt;
+  }
+
+  * /deep/ .chart-base {
+    font-size: 12pt;
+    -webkit-user-select: none;
+    cursor: default;
+  }
+
+  * /deep/ .chart-base .axis path,
+  * /deep/ .chart-base .axis line {
+    fill: none;
+    shape-rendering: crispEdges;
+    stroke: #000;
+  }
+</style><template id="chart-base-template">
+  <svg> 
+    <g id="chart-area" xmlns="http://www.w3.org/2000/svg">
+      <g class="x axis"></g>
+      <g class="y axis"></g>
+      <text id="title"></text>
+    </g>
+  </svg>
+</template><style>
+  * /deep/ .chart-base-2d.updating-brushing-state #brushes > * {
+    fill: rgb(103, 199, 165)
+  }
+
+  * /deep/ .chart-base-2d #brushes {
+    fill: rgb(213, 236, 229)
+  }
+</style><style>
+* /deep/ .line-chart .line{fill:none;stroke-width:1.5px}* /deep/ .line-chart #brushes>rect{fill:rgb(192,192,192)}
+</style><polymer-element name="tr-ui-side-panel">
+  
+</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-input-latency-side-panel">
   <template>
     <style>
     :host {
+      flex-direction: column;
       display: flex;
     }
-    </style>
-    <tr-ui-b-table id="content"></tr-ui-b-table>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-sample-sub-view">
-  <template>
-    <style>
-    :host { display: block; }
-    #control {
-      background-color: #e6e6e6;
-      background-image: -webkit-gradient(linear, 0 0, 0 100%,
-                                         from(#E5E5E5), to(#D1D1D1));
+    toolbar {
       flex: 0 0 auto;
-      overflow-x: auto;
-    }
-    #control::-webkit-scrollbar { height: 0px; }
-    #control {
-      font-size: 12px;
+      border-bottom: 1px solid black;
       display: flex;
-      flex-direction: row;
-      align-items: stretch;
-      margin: 1px;
-      margin-right: 2px;
+    }
+    result-area {
+      flex: 1 1 auto;
+      display: block;
+      min-height: 0;
+      overflow-y: auto;
     }
     </style>
-    <div id="control">
-      Sample View Option
-      <select id="view_selector">
-        <option value="TOPDOWNVIEW">Tree (Top Down)</option>
-        <option value="BOTTOMUPVIEW">Heavy (Bottom Up)</option>
-      </select>
-    </div>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
+
+    <toolbar id="toolbar"></toolbar>
+    <result-area id="result_area"></result-area>
   </template>
 
   
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-interaction-record-sub-view">
+</polymer-element><style>
+* /deep/ .pie-chart .arc-text{font-size:8pt}* /deep/ .pie-chart .label{font-size:10pt}* /deep/ .pie-chart polyline{fill:none;stroke:black}
+</style><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-time-summary-side-panel">
+  <template>
+    <style>
+    :host {
+      flex-direction: column;
+      display: flex;
+    }
+    toolbar {
+      flex: 0 0 auto;
+      border-bottom: 1px solid black;
+      display: flex;
+    }
+    result-area {
+      flex: 1 1 auto;
+      display: block;
+      min-height: 0;
+      overflow-y: auto;
+    }
+    </style>
+
+    <toolbar id="toolbar"></toolbar>
+    <result-area id="result_area"></result-area>
+  </template>
+
   
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-interaction-record-sub-view">
+</polymer-element><style>
+.tr-ui-e-system-stats-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-system-stats-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-system-stats-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}
+</style><polymer-element name="tr-ui-heading">
+  <template>
+    <style>
+    :host {
+      background-color: rgb(243, 245, 247);
+      border-right: 1px solid #8e8e8e;
+      display: block;
+      height: 100%;
+      margin: 0;
+      padding: 0 5px 0 0;
+    }
+
+    heading {
+      display: block;
+      overflow-x: hidden;
+      text-align: left;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+
+    #arrow {
+      -webkit-flex: 0 0 auto;
+      font-family: sans-serif;
+      margin-left: 5px;
+      margin-right: 5px;
+      width: 8px;
+    }
+
+    #link, #heading_content {
+      display: none;
+    }
+    </style>
+    <heading id="heading" on-click="{{onHeadingDivClicked_}}">
+      <span id="arrow"></span>
+      <span id="heading_content"></span>
+      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
+    </heading>
+  </template>
+
   
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-alert-sub-view">
+</polymer-element><style>
+.track-button{background-color:rgba(255,255,255,0.5);border:1px solid rgba(0,0,0,0.1);color:rgba(0,0,0,0.2);font-size:10px;height:12px;text-align:center;width:12px}.track-button:hover{background-color:rgba(255,255,255,1.0);border:1px solid rgba(0,0,0,0.5);box-shadow:0 0 .05em rgba(0,0,0,0.4);color:rgba(0,0,0,1)}.track-close-button{left:2px;position:absolute;top:2px}.track-collapse-button{left:3px;position:absolute;top:2px}
+</style><style>
+.object-instance-track{height:18px}
+</style><style>
+.tr-ui-e-system-stats-instance-track{height:500px}.tr-ui-e-system-stats-instance-track ul{list-style:none;list-style-position:outside;margin:0;overflow:hidden}
+</style><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-alert-sub-view">
   <template>
     <style>
     :host {
@@ -971,24 +1024,6 @@
     </tr-ui-b-table>
   </template>
   
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-frame-sub-view">
-  <template>
-    <style>
-    :host {
-      display: flex;
-      flex-direction: column;
-    }
-    #asv {
-      flex: 0 0 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-a-alert-sub-view id="asv">
-    </tr-ui-a-alert-sub-view>
-  </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-frame-sub-view">
-  
 </polymer-element><polymer-element name="tr-ui-a-stacked-pane">
   
 </polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-heap-details-pane">
@@ -1051,6 +1086,8 @@
       </div>
     </div>
     <div id="contents">
+      <tr-ui-b-info-bar class="info-bar-hidden" id="info_bar">
+      </tr-ui-b-info-bar>
       <div id="info_text">No heap dump selected</div>
       <tr-ui-b-table id="table"></tr-ui-b-table>
     </div>
@@ -1263,6 +1300,209 @@
   <template>
     <div id="content"></div>
   </template>
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-counter-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-layout-tree-sub-view">
+  <template>
+    <div id="content"></div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-a-selection-summary-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+    
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-a-multi-event-summary-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+    
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-a-multi-event-details-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+
+    #titletable {
+      font-weight: bold;
+    }
+
+    #title-info {
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="titletable">
+    </tr-ui-b-table>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      overflow: auto;
+    }
+    #content {
+      display: flex;
+      flex-direction: column;
+      flex: 0 1 auto;
+      align-self: stretch;
+    }
+    #content > * {
+      flex: 0 0 auto;
+      align-self: stretch;
+    }
+    tr-ui-a-multi-event-summary-table {
+      border-bottom: 1px solid #aaa;
+    }
+
+    tr-ui-a-selection-summary-table  {
+      margin-top: 1.25em;
+      border-top: 1px solid #aaa;
+      background-color: #eee;
+      font-weight: bold;
+      margin-bottom: 1.25em;
+      border-bottom: 1px solid #aaa;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-a-related-events">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-async-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #container {
+      display: flex;
+      flex: 1 1 auto;
+    }
+    #events {
+      margin-left: 8px;
+      flex: 0 1 200px;
+    }
+    </style>
+    <div id="container">
+      <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+      <div id="events">
+        <tr-ui-a-related-events id="relatedEvents"></tr-ui-a-related-events>
+      </div>
+    </div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-cpu-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      flex: 1 1 auto;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-flow-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-frame-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-instant-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-object-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-a-frame-power-usage-chart">
+  <template>
+    <div id="content"></div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-a-power-sample-summary-table">
+  <template>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+  
 </polymer-element><polymer-element name="tr-ui-a-power-sample-table">
   <template>
     <style>
@@ -1272,60 +1512,6 @@
     </style>
     <tr-ui-b-table id="table"></tr-ui-b-table>
   </template>
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-power-sample-sub-view">
-  <template>
-    <style>
-    :host { display: block; }
-    </style>
-    <tr-ui-a-power-sample-table id="samplesTable">
-    </tr-ui-a-power-sample-table>
-  </template>
-
-  
-</polymer-element><style>
-  * /deep/ .chart-base #title {
-    font-size: 16pt;
-  }
-
-  * /deep/ .chart-base {
-    font-size: 12pt;
-    -webkit-user-select: none;
-    cursor: default;
-  }
-
-  * /deep/ .chart-base .axis path,
-  * /deep/ .chart-base .axis line {
-    fill: none;
-    shape-rendering: crispEdges;
-    stroke: #000;
-  }
-</style><template id="chart-base-template">
-  <svg> 
-    <g id="chart-area" xmlns="http://www.w3.org/2000/svg">
-      <g class="x axis"></g>
-      <g class="y axis"></g>
-      <text id="title"></text>
-    </g>
-  </svg>
-</template><style>
-  * /deep/ .chart-base-2d.updating-brushing-state #brushes > * {
-    fill: rgb(103, 199, 165)
-  }
-
-  * /deep/ .chart-base-2d #brushes {
-    fill: rgb(213, 236, 229)
-  }
-</style><style>
-* /deep/ .line-chart .line{fill:none;stroke-width:1.5px}* /deep/ .line-chart #brushes>rect{fill:rgb(192,192,192)}
-</style><polymer-element name="tr-ui-a-frame-power-usage-chart">
-  <template>
-    <div id="content"></div>
-  </template>
-</polymer-element><polymer-element name="tr-ui-a-power-sample-summary-table">
-  <template>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-  
 </polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-power-sample-sub-view">
   <template>
     <style>
@@ -1351,6 +1537,455 @@
     <tr-ui-a-frame-power-usage-chart id="chart">
     </tr-ui-a-frame-power-usage-chart>
   </template>
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-sample-sub-view">
+  <template>
+    <style>
+    :host { display: block; }
+    #control {
+      background-color: #e6e6e6;
+      background-image: -webkit-gradient(linear, 0 0, 0 100%,
+                                         from(#E5E5E5), to(#D1D1D1));
+      flex: 0 0 auto;
+      overflow-x: auto;
+    }
+    #control::-webkit-scrollbar { height: 0px; }
+    #control {
+      font-size: 12px;
+      display: flex;
+      flex-direction: row;
+      align-items: stretch;
+      margin: 1px;
+      margin-right: 2px;
+    }
+    </style>
+    <div id="control">
+      Sample View Option
+    </div>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      display: flex;
+      flex: 1 1 auto;
+    }
+    #content > tr-ui-a-related-events {
+      margin-left: 8px;
+      flex: 0 1 200px;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-time-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      flex: 1 1 auto;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-user-expectation-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-async-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #events {
+      display:flex;
+      flex-direction: column;
+    }
+    </style>
+    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
+    <div id="events">
+      <tr-ui-a-related-events id="relatedEvents"></tr-ui-a-related-events>
+    </div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-cpu-slice-sub-view">
+  <template>
+    <style>
+    table {
+      border-collapse: collapse;
+      border-width: 0;
+      margin-bottom: 25px;
+      width: 100%;
+    }
+
+    table tr > td:first-child {
+      padding-left: 2px;
+    }
+
+    table tr > td {
+      padding: 2px 4px 2px 4px;
+      vertical-align: text-top;
+      width: 150px;
+    }
+
+    table td td {
+      padding: 0 0 0 0;
+      width: auto;
+    }
+    tr {
+      vertical-align: top;
+    }
+
+    tr:nth-child(2n+0) {
+      background-color: #e2e2e2;
+    }
+    </style>
+    <table>
+      <tbody><tr>
+        <td>Running process:</td><td id="process-name"></td>
+      </tr>
+      <tr>
+        <td>Running thread:</td><td id="thread-name"></td>
+      </tr>
+      <tr>
+        <td>Start:</td>
+        <td>
+          <tr-v-ui-scalar-span id="start">
+          </tr-v-ui-scalar-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Duration:</td>
+        <td>
+          <tr-v-ui-scalar-span id="duration">
+          </tr-v-ui-scalar-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Active slices:</td><td id="running-thread"></td>
+      </tr>
+      <tr>
+        <td>Args:</td>
+        <td>
+          <tr-ui-a-generic-object-view id="args">
+          </tr-ui-a-generic-object-view>
+        </td>
+      </tr>
+    </tbody></table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-single-event-sub-view" name="tr-ui-a-single-flow-event-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-frame-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #asv {
+      flex: 0 0 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-a-alert-sub-view id="asv">
+    </tr-ui-a-alert-sub-view>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-instant-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-instance-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+
+    #snapshots > * {
+      display: block;
+    }
+
+    :host {
+      overflow: auto;
+      display: block;
+    }
+
+    * {
+      -webkit-user-select: text;
+    }
+
+    .title {
+      border-bottom: 1px solid rgb(128, 128, 128);
+      font-size: 110%;
+      font-weight: bold;
+    }
+
+    td, th {
+      font-family: monospace;
+      vertical-align: top;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-snapshot-sub-view">
+  <template>
+    <style>
+    #args {
+      white-space: pre;
+    }
+
+    :host {
+      overflow: auto;
+      display: flex;
+    }
+
+    ::content * {
+      -webkit-user-select: text;
+    }
+
+    ::content .title {
+      border-bottom: 1px solid rgb(128, 128, 128);
+      font-size: 110%;
+      font-weight: bold;
+    }
+
+    ::content td, th {
+      font-family: monospace;
+      vertical-align: top;
+    }
+    </style>
+    <content></content>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-power-sample-sub-view">
+  <template>
+    <style>
+    :host { display: block; }
+    </style>
+    <tr-ui-a-power-sample-table id="samplesTable">
+    </tr-ui-a-power-sample-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #events {
+      display: flex;
+      flex-direction: column;
+    }
+
+    </style>
+    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
+    <div id="events">
+      <tr-ui-a-related-events id="relatedEvents">
+      </tr-ui-a-related-events>
+    </div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-time-slice-sub-view">
+  <template>
+    <style>
+    table {
+      border-collapse: collapse;
+      border-width: 0;
+      margin-bottom: 25px;
+      width: 100%;
+    }
+
+    table tr > td:first-child {
+      padding-left: 2px;
+    }
+
+    table tr > td {
+      padding: 2px 4px 2px 4px;
+      vertical-align: text-top;
+      width: 150px;
+    }
+
+    table td td {
+      padding: 0 0 0 0;
+      width: auto;
+    }
+    tr {
+      vertical-align: top;
+    }
+
+    tr:nth-child(2n+0) {
+      background-color: #e2e2e2;
+    }
+    </style>
+    <table>
+      <tbody><tr>
+        <td>Running process:</td><td id="process-name"></td>
+      </tr>
+      <tr>
+        <td>Running thread:</td><td id="thread-name"></td>
+      </tr>
+      <tr>
+        <td>State:</td>
+        <td><b><span id="state"></span></b></td>
+      </tr>
+      <tr>
+        <td>Start:</td>
+        <td>
+          <tr-v-ui-scalar-span id="start">
+          </tr-v-ui-scalar-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Duration:</td>
+        <td>
+          <tr-v-ui-scalar-span id="duration">
+          </tr-v-ui-scalar-span>
+        </td>
+      </tr>
+
+      <tr>
+        <td>On CPU:</td><td id="on-cpu"></td>
+      </tr>
+
+      <tr>
+        <td>Running instead:</td><td id="running-instead"></td>
+      </tr>
+
+      <tr>
+        <td>Args:</td><td id="args"></td>
+      </tr>
+    </tbody></table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-user-expectation-sub-view">
+  
+</polymer-element><polymer-element constructor="TracingAnalysisTabView" name="tr-ui-a-tab-view">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-flow: column nowrap;
+        overflow: hidden;
+        box-sizing: border-box;
+      }
+
+      tab-strip[tabs-hidden] {
+        display: none;
+      }
+
+      tab-strip {
+        background-color: rgb(236, 236, 236);
+        border-bottom: 1px solid #8e8e8e;
+        display: flex;
+        flex: 0 0 auto;
+        flex-flow: row;
+        overflow-x: auto;
+        padding: 0 10px 0 10px;
+        font-size: 12px;
+      }
+
+      tab-button {
+        display: block;
+        flex: 0 0 auto;
+        padding: 4px 15px 1px 15px;
+        margin-top: 2px;
+      }
+
+      tab-button[selected=true] {
+        background-color: white;
+        border: 1px solid rgb(163, 163, 163);
+        border-bottom: none;
+        padding: 3px 14px 1px 14px;
+      }
+
+      tabs-content-container {
+        display: flex;
+        flex: 1 1 auto;
+        overflow: auto;
+        width: 100%;
+      }
+
+      ::content > * {
+        flex: 1 1 auto;
+      }
+
+      ::content > *:not([selected]) {
+        display: none;
+      }
+
+      button-label {
+        display: inline;
+      }
+
+      tab-strip-heading {
+        display: block;
+        flex: 0 0 auto;
+        padding: 4px 15px 1px 15px;
+        margin-top: 2px;
+        margin-before: 20px;
+        margin-after: 10px;
+      }
+      #tsh {
+        display: inline;
+        font-weight: bold;
+      }
+    </style>
+
+    <tab-strip>
+      <tab-strip-heading id="tshh">
+        <span id="tsh"></span>
+      </tab-strip-heading>
+      <template repeat="{{tab in tabs_}}">
+        <tab-button button-id="{{ tab.id }}" on-click="{{ tabButtonSelectHandler_ }}" selected="{{ selectedTab_.id === tab.id }}">
+          <button-label>{{ tab.label ? tab.label : 'No Label'}}</button-label>
+        </tab-button>
+      </template>
+    </tab-strip>
+
+    <tabs-content-container id="content-container">
+        <content></content>
+    </tabs-content-container>
+
+  </template>
+
+  
 </polymer-element><polymer-element name="tr-ui-a-analysis-view">
   <template>
     <style>
@@ -1373,9 +2008,7 @@
     <content></content>
   </template>
   
-</polymer-element><style>
-* /deep/ x-drag-handle{-webkit-user-select:none;box-sizing:border-box;display:block}* /deep/ x-drag-handle.horizontal-drag-handle{background-image:-webkit-gradient(linear,0 0,0 100%,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;cursor:ns-resize;height:7px;position:relative;z-index:10}* /deep/ x-drag-handle.vertical-drag-handle{background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-left:1px solid white;border-right:1px solid #8e8e8e;cursor:ew-resize;position:relative;width:7px;z-index:10}
-</style><polymer-element name="tr-ui-b-dropdown">
+</polymer-element><polymer-element name="tr-ui-b-dropdown">
   <template>
     <style>
     :host {
@@ -1435,36 +2068,6 @@
     </dialog>
   </template>
   
-</polymer-element><polymer-element name="tv-ui-b-hotkey-controller">
-  
-</polymer-element><polymer-element is="HTMLDivElement" name="tr-ui-b-info-bar">
-  <template>
-    <style>
-    :host {
-      align-items: center;
-      flex: 0 0 auto;
-      background-color: rgb(252, 235, 162);
-      border-bottom: 1px solid #A3A3A3;
-      border-left: 1px solid white;
-      border-right: 1px solid #A3A3A3;
-      border-top: 1px solid white;
-      display: flex;
-      height: 26px;
-      padding: 0 3px 0 3px;
-    }
-
-    :host(.info-bar-hidden) {
-      display: none;
-    }
-
-    #message { flex: 1 1 auto; }
-    </style>
-
-    <span id="message"></span>
-    <span id="buttons"></span>
-  </template>
-
-  
 </polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-b-info-bar-group">
   <template>
     <style>
@@ -1508,113 +2111,9 @@
       <content></content>
     </div>
   </template>
-</polymer-element><polymer-element name="tr-ui-b-mouse-mode-icon">
-  <template>
-    <style>
-    :host {
-      display: block;
-      background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=);
-      width: 27px;
-      height: 30px;
-    }
-    :host.active {
-      cursor: auto;
-    }
-    </style>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-mouse-mode-selector">
-  <template>
-    <style>
-    :host {
-
-      -webkit-user-drag: element;
-      -webkit-user-select: none;
-
-      background: #DDD;
-      border: 1px solid #BBB;
-      border-radius: 4px;
-      box-shadow: 0 1px 2px rgba(0,0,0,0.2);
-      left: calc(100% - 120px);
-      position: absolute;
-      top: 100px;
-      user-select: none;
-      width: 29px;
-      z-index: 20;
-    }
-
-    .drag-handle {
-      background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=) 2px 3px no-repeat;
-      background-repeat: no-repeat;
-      border-bottom: 1px solid #BCBCBC;
-      cursor: move;
-      display: block;
-      height: 13px;
-      width: 27px;
-    }
-
-    .tool-button {
-      background-position: center center;
-      background-repeat: no-repeat;
-      border-bottom: 1px solid #BCBCBC;
-      border-top: 1px solid #F1F1F1;
-      cursor: pointer;
-    }
-
-    .buttons > .tool-button:last-child {
-      border-bottom: none;
-    }
-
-    </style>
-    <div class="drag-handle"></div>
-    <div class="buttons">
-    </div>
-  </template>
 </polymer-element><style>
-.track-button{background-color:rgba(255,255,255,0.5);border:1px solid rgba(0,0,0,0.1);color:rgba(0,0,0,0.2);font-size:10px;height:12px;text-align:center;width:12px}.track-button:hover{background-color:rgba(255,255,255,1.0);border:1px solid rgba(0,0,0,0.5);box-shadow:0 0 .05em rgba(0,0,0,0.4);color:rgba(0,0,0,1)}.track-close-button{left:2px;position:absolute;top:2px}.track-collapse-button{left:3px;position:absolute;top:2px}
-</style><style>
 .drawing-container{-webkit-box-flex:1;display:inline;overflow:auto;overflow-x:hidden;position:relative}.drawing-container-canvas{-webkit-box-flex:1;display:block;pointer-events:none;position:absolute;top:0}
-</style><polymer-element name="tr-ui-heading">
-  <template>
-    <style>
-    :host {
-      background-color: rgb(243, 245, 247);
-      border-right: 1px solid #8e8e8e;
-      display: block;
-      height: 100%;
-      margin: 0;
-      padding: 0 5px 0 0;
-    }
-
-    heading {
-      display: block;
-      overflow-x: hidden;
-      text-align: left;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
-
-    #arrow {
-      -webkit-flex: 0 0 auto;
-      font-family: sans-serif;
-      margin-left: 5px;
-      margin-right: 5px;
-      width: 8px;
-    }
-
-    #link, #heading_content {
-      display: none;
-    }
-    </style>
-    <heading id="heading" on-click="{{onHeadingDivClicked_}}">
-      <span id="arrow"></span>
-      <span id="heading_content"></span>
-      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
-    </heading>
-  </template>
-
-  
-</polymer-element><style>
+</style><style>
 .letter-dot-track {
   height: 18px;
 }
@@ -1630,8 +2129,6 @@
 </style><style>
 .spacing-track{height:4px}
 </style><style>
-.object-instance-track{height:18px}
-</style><style>
 .rect-track{height:18px}
 </style><style>
 .thread-track{-webkit-box-orient:vertical;display:-webkit-box;position:relative}
@@ -1804,13 +2301,11 @@
 
     <div class="root hidden" id="root" on-focus="{{ onConsoleFocus }}" tabindex="0">
       <div id="history"></div>
-      <div id="prompt" on-blur="{{ onConsoleBlur }}" on-keydown="{{ promptKeyDown }}" on-keypress="{{ promptKeyPress }}">
-  
+      <div id="prompt" on-blur="{{ onConsoleBlur }}" on-keydown="{{ promptKeyDown }}" on-keypress="{{ promptKeyPress }}"></div>
+    </div>
+  </template>
 
   
-
-</div></div></template></polymer-element><polymer-element name="tr-ui-side-panel">
-  
 </polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-side-panel-container">
   <template>
     <style>
@@ -1976,6 +2471,11 @@
       </div>
 
       <div class="pair">
+        <div class="command"><span class="mod"></span>-click/drag</div>
+        <div class="action">Add events to the current selection</div>
+      </div>
+
+      <div class="pair">
         <div class="command">double click</div>
         <div class="action">Select all events with same title</div>
       </div>
@@ -2031,11 +2531,6 @@
       </div>
 
       <div class="pair">
-        <div class="command"><span class="mod"></span></div>
-        <div class="action">Hold for temporary zoom</div>
-      </div>
-
-      <div class="pair">
         <div class="command">/</div>
         <div class="action">Search</div>
       </div>
@@ -2088,11 +2583,11 @@
   </template>
 
   
-</polymer-element><polymer-element name="tr-ui-u-array-of-numbers-span">
+</polymer-element><polymer-element name="tr-v-ui-array-of-numbers-span">
   <template>
   </template>
   
-</polymer-element><polymer-element name="tr-ui-u-generic-table-view">
+</polymer-element><polymer-element name="tr-v-ui-generic-table-view">
   <template>
     <style>
     :host {
@@ -2114,11 +2609,11 @@
       overflow: auto;
     }
     </style>
-    <tr-ui-u-generic-table-view id="gtv"></tr-ui-u-generic-table-view>
+    <tr-v-ui-generic-table-view id="gtv"></tr-v-ui-generic-table-view>
   </template>
 
   
-</polymer-element><polymer-element name="tr-ui-u-preferred-display-unit">
+</polymer-element><polymer-element name="tr-v-ui-preferred-display-unit">
   
 </polymer-element><polymer-element name="tr-ui-timeline-view">
   <template>
@@ -2184,7 +2679,7 @@
 
     middle-container ::content track-view-container > * { flex: 1 1 auto; }
     middle-container > x-timeline-view-side-panel-container { flex: 0 0 auto; }
-    x-drag-handle { flex: 0 0 auto; }
+    tr-ui-b-drag-handle { flex: 0 0 auto; }
     tr-ui-a-analysis-view { flex: 0 0 auto; }
     </style>
 
@@ -2217,460 +2712,110 @@
       <tr-ui-side-panel-container id="side_panel_container">
       </tr-ui-side-panel-container>
     </middle-container>
-    <x-drag-handle id="drag_handle"></x-drag-handle>
+    <tr-ui-b-drag-handle id="drag_handle"></tr-ui-b-drag-handle>
     <tr-ui-a-analysis-view id="analysis"></tr-ui-a-analysis-view>
 
-    <tr-ui-u-preferred-display-unit id="display_unit">
-    </tr-ui-u-preferred-display-unit>
+    <tr-v-ui-preferred-display-unit id="display_unit">
+    </tr-v-ui-preferred-display-unit>
   </template>
 
   
-</polymer-element><style>
-* /deep/ .x-list-view{-webkit-user-select:none;display:block}* /deep/ .x-list-view:focus{outline:none}* /deep/ .x-list-view *{-webkit-user-select:none}* /deep/ .x-list-view>.list-item{padding:2px 4px 2px 4px}* /deep/ .x-list-view:focus>.list-item[selected]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ .x-list-view>.list-item[selected]{background-color:rgb(103,199,165)}
-</style><style>
-* * /deep/ tr-ui-e-chrome-cc-picture-ops-list-view{-webkit-flex-direction:column;border-top:1px solid grey;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view{-webkit-flex:1 1 auto;overflow:auto}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item{border-bottom:1px solid #555;font-size:small;font-weight:bold;padding-bottom:5px;padding-left:5px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item:hover{background-color:#f0f0f0;cursor:pointer}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>*{color:#777;font-size:x-small;font-weight:normal;margin-left:1em;max-width:300px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.elementInfo{color:purple;font-size:small;font-weight:bold}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.time{color:rgb(136,0,0)}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view:focus>.list-item[beforeSelection]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view>.list-item[beforeSelection]{background-color:rgb(103,199,165)}
-</style><template id="tr-ui-e-chrome-cc-display-item-debugger-template">
-  <style>
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger {
-    -webkit-flex: 1 1 auto;
-    display: -webkit-flex;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel {
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-    min-width: 300px;
-    overflow-y: auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-        display-item-info {
-    -webkit-flex: 1 1 auto;
-    padding-top: 2px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-        display-item-info .title {
-    font-weight: bold;
-    margin-left: 5px;
-    margin-right: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-        display-item-info .export {
-    margin: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > x-drag-handle {
-    -webkit-flex: 0 0 auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel {
-    -webkit-flex: 1 1 auto;
-    display: -webkit-flex;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-      display-item-info > header {
-    border-bottom: 1px solid #555;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-      display-item-info > .x-list-view > div {
-    border-bottom: 1px solid #555;
-    padding-top: 3px;
-    padding-bottom: 3px;
-    padding-left: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-      display-item-info > .x-list-view > div:hover {
-    background-color: #f0f0f0;
-    cursor: pointer;
-  }
-
-  /*************************************************/
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-      tr-ui-e-chrome-cc-picture-ops-list-view.hasPictureOps {
-    display: block;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-        x-drag-handle.hasPictureOps {
-    display: block;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-        tr-ui-e-chrome-cc-picture-ops-list-view {
-    display: none;
-    overflow-y: auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-        x-drag-handle {
-    display: none;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger raster-area {
-    -webkit-flex: 1 1 auto;
-    background-color: #ddd;
-    min-height: 200px;
-    min-width: 200px;
-    overflow-y: auto;
-    padding-left: 5px;
-  }
-  </style>
-
-  <left-panel>
-    <display-item-info>
-      <header>
-        <span class="title">Display Item List</span>
-        <span class="size"></span>
-        <div class="export">
-          <input class="dlfilename" type="text" value="displayitemlist.json"/>
-          <button class="dlexport">Export display item list</button>
-        </div>
-        <div class="export">
-          <input class="skpfilename" type="text" value="skpicture.skp"/>
-          <button class="skpexport">Export list as SkPicture</button>
-        </div>
-      </header>
-    </display-item-info>
-  </left-panel>
-  <right-panel>
-    <raster-area><canvas></canvas></raster-area>
-  </right-panel>
-</template><style>
-* /deep/ .tr-ui-e-chrome-cc-display-item-list-view{-webkit-flex:1 1 auto!important;display:-webkit-flex}
-</style><style>
-* /deep/ tr-ui-e-chrome-cc-layer-picker{-webkit-flex-direction:column;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls{-webkit-flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;display:inline;font-size:14px;padding-left:2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls input[type='checkbox']{vertical-align:-2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>.x-list-view{-webkit-flex:1 1 auto;font-family:monospace;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view{-webkit-flex:0 0 auto;height:200px;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view *{-webkit-user-select:text!important;cursor:text}
-</style><style>
-* /deep/ quad-stack-view {
-  display: block;
-  float: left;
-  height: 100%;
-  overflow: hidden;
-  position: relative; /* For the absolute positioned mouse-mode-selector */
-  width: 100%;
-}
-
-* /deep/ quad-stack-view > #header {
-  position: absolute;
-  font-size: 70%;
-  top: 10px;
-  left: 10px;
-  width: 800px;
-}
-* /deep/ quad-stack-view > #stacking-distance-slider {
-  position: absolute;
-  font-size: 70%;
-  top: 10px;
-  right: 10px;
-}
-
-* /deep/ quad-stack-view > #chrome-left {
-  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABICAYAAABC4+HLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyMmV/Pm9QAAIABJREFUeNrtvXmwXdd13vlbe9/7BgzEQAIcQAIEQYKjSAokLVlOW5Fk2nLKmqx0J2Wp0k652h13uiy5XYqdwU7sSnckpZ1yV3U75apU4kos27Elu9NlyRXZjiiRomSTIiWZs0hwHsABJIY33rPX6j/W2ueed3DvAyDKKoGFW0UCeO/ec/fZZ+29v7XWt74lAIuLi7tXV1f/raq+zcy2AogIZsbpvrqfMzNE5IS/1/fVn5sZKaUTrtX9/v7nT+fn9e/1e052X/3r1THWa3R/37+miKCq7c+mjW/a+F/P57vj6/45bayn+wzXs4n+794Q9nP8+PHdS0tL31LVmfpGVQU4YSInGUb/YfZvpn+zp/LQu4Y27X31d933nurkq+qaa08yotO55npG0v2O+r1/XZ9fb2FMWoD9Oe5+pju//e+fdP3u83+j2I+89NJLn11dXf1bdSCTJnnSSpz2+/VWZ/8m+w+g/zD616yT2P9733BOZ5f4dhbCevPQHet63zVtV3y9n1/v/k9nZ562SNY7Gd5o9iPPP//8qxVKrQdL+hOy3qqdNEnTjv1JA+vuRpMGvd7kn8oCqded9B2THuJ6u/Kk7+vuiNOgQH8OX+/np813/376O/CkU2EavDwVWPiGsp9nn33WJt3ItF2ne2xOe2jTHuTJMOS0He1UcG33791JmWQYkzB6dyfp7tynsktPG8/Jdv2TGcLpfH7Sc5m0EKZBsPV+tp4PMe39bwj7efrpp229G5u2O3WPplN1cE/XQZsENybtnNN2pv4x3N1Fpu2S/SO6j6fXgz6n4gRPGmMfR7/ez/cXd/1798Tsfr4PMU52Oq4Hp95I9jPor7ZJ+G7STlEnvN7gesfXpB2tH5lZzynrO07Txtb92aQTY9rv+3i1v4jqv5umOSEq0r9O3/iqEUx6MPXnqjpxrk73812oMQmP968zyUj68zPp+U1bxG80+5GnnnrKpkVxTiWUuN4q7+96/YFXp6pvANN8hD7MmRbF6O7200KR9ed9CDbpSF4v6jIJtnQjQdPGOylK9p34/HowaFL0Z73IUNex7Z5Gk3bkN6L9yBNPPGHdY3fayu3uSP0dqH62uyP0w4XrDWo957gPEfqf78e4p4U8+0Y86R6711pvAUyL3vTvd9ou238Q/Xn4dj4/Cd6d7BlMC532534S9OnO8xvVfuTxxx+39RJlk/DtpAGc6k6hquScp+7EkyIn0+LV60Ufpu2q05zN/sOYFIfvP8CT5VEmGWN/h5w0zm/38+sl7/r3drLntt58rzdXbyT7kccee8z6O2b3JnLO6zpjk47nkyVg1pu07muas9b3CaZh4f5uPMn4Sikn7Jj9RTEJMnQfVHdck4x3Wt5i0qL6dj8/6WQ5GcSYBiEn+STrhT/fqPYzmJYxrRcopax5eH18Oi38WI2ulLImYTPNMavv716z/93rRXUmOZXVgZ5kePX7+hPeN5xJTmx3MdXf9zHyM888w8LCwgn30IUQ0xzWSYvhVD4/LarTzpWBpOl+zqRQ9lqjE2DCtbH2x9MW3XA45JxzzmHnzp0njYp9r9jPoH75Gkekc8SZ2ZpjrH/Ez8wMSSmHMY4YjZp2MDnniVGT/sPvRhxmZ2fJOWHmxj0ajU7AtvV6k4727gSklMg5M4jdq6iyuro69bv799fNptYF0X3vJKjz8MMPMz+/gWuvuYatW7eScgIEwTADEwEUAZDkBgtuYONlCCJgAuZ/N5QkCcP8avFzUH8fsZgNEoJJLAakc+2TjENi90RQjGSCJm1/hwlmgmRFFIwEYoiNxyPxvYZ07gVKUzh8+DD333cfRZXLLrvsBLxfjbl76pyO/ZRS1thq325O137k4YcftvUSOf1Ufdco/uwLX+LOv7ibZ194EYBdF+zkB956C+98+99ARE64ue6XqyqDwaDdGZqm4Qtf/DK3f+UveO7QS2uu944f/IH2WpNwdp2U/oT8+W23c8dX7+K5GN9FF+zkb7zlZt71jh9cswNPw8uTsPU0h19VeeSRR7j55lvYumUzK6MCpqTs9p2AAiRLmChWBBIIiqZEMkVUMAQTJZtQSCCKkDE0/h+7twkKpCSYxrhVMTGyCYogohRLCGvHoYD0xyGKScIUpC5AVSQl/0ACaxeCkJJhakDCTJEEiKAmDMx8XSdAY6lZQjHmZoa89NLL3Pv1r3PVVVeesDH3T+FTtZ/uguhu8v3o36naj4ggjzzyiPXhwtRjOf6+tLjEP//4r3HOuRfw5psPsOeSXQA8+dQz3Pu1ezl2+BC//I9+jvn5uXWjDfW1uLjIr37y19m8/fzJ13vlBf75L/48c3Oza3aWadSP5eUVfuUT/2bd6/3yL/xvbNgwv2Y3qbtOF0J2MfN6ka7nnnuOvZfuZcfO8xitKnloFBXEBHGLc4MTQwVEDeIkyAqa/Pdh9z5vaqgkUuz8akYGVATEHOYYiCSUQtJqkCDJsJJIvXFYNRIzLGWQQqqLEiOhqKS6gnzhqJ9cJplsiiXBSnfBJF957TEoJBKYYskwFUSgWCKnBkmZp59+mpdfepmdO3eu2USn+V/r2c/JWAX9CN/J7KdNiD744IO2nqM0Cff+01/9P7js6gP8d29/C5detJNtmzYC8OrxBZ547kVu/+JfcPDBe/iXv/xPkCnkvHalm/HPTvV6v/SP25vs3mB3fKurI37pX36cfdesf73HHriH//2X/3Fr/NOSTZMyzn0n0sx47LHH+JEf+REWFhd8pzcliRtyBVbFYlcTN0bfpoWEYiaxENTtjOQwByOZ7+r+b/zacY5YICvH/iDmBurjmzQOKMlIWkPThpohkuN0iwWI+YrNGkdeQswwcbhlWEAzw8wXazZDJfsYMP84ghXzxSHip5rB/IY5/sv/+0dc96Y3rdmA2uz0YDA1EHIqDNv1KDAVvk2yn64vOujHlqdlJ+vv/+wLX2JuywVcfOkeXj2ywGtHn0C1Hov+uUsu3cNzzz/Hf7vtdm5959snRknq6wtfvOOUr/fnX7yDH37n29fccBdG5Zy57fYvs2HrqV7vdm59x9vXJeqtx6WqD+T555/nyiv3s7y8TMLhSgLMElkURx+KENi+7uzi0EgtIUCi+OmSwIpjmYTSAIN6uiSDkkAKQgp/IgON+yaGnxIBz/rjcPckj30LU5I5rCsJsiYsafgjCbXEUIwiiqq4e1J9FjVfNCioYMlPC/eJIFuisTiN0oBkhllBcmJlaYnL9+/n0KFD7Nixg5xza6hPP/00S0tLzM7Mho/lfpGicW/hyyCQAv75Nuw+UOwi/o7WmXLfClhYOMaWLVvZtWtXG7TpRibrMx/0V1j34XcdT4DBYMA933yQnRdeymhUOHZsCZFEqrurORRZHRV2XrCLr33jft596zsZjUbtiuzGqQeDAXd//T52Xrj3lK53zzce4G/d+k6WlpfXOF5jSAhf+8YD7DjF8d3zjQf50VvfRdM0LYzqv/pHcH9napqGF154gb/59rdz7PhxTPCdNSliisYuK5rjIRsWPyeJQyGhWhyNCEn9sbrPIGRJmBRfeCb+kEXQwDZG49AFIYmh4kvmhHGYISTEGl9YBimPoZypvx8VJA3R5IurMcdrSTrjLuGjGJCNpJnGlCwWp6CRMLIoMCBhFJPYIAxNxjVXX83v//7vs337dnLONE1DzpmXX36Zt73tB1g8fhwzh3OIObyrp60IWp9XNlBfRtkCPqWIM9T5x+GhDIQN8/O88srLfPWrX+WWW245IeLVPvvubt49biZRMTDj6MISGzdt9i81YTjIzM/OMjc7w3AwANwp27hpM0cWln0iOt9RowruSAlHFpZP43pLJxAB68lnZuSUOXJa41tCIuQ7jYBWf9fnP5kZo9GIlZUVLrzwQpaXVzxihGHJEE1ucdlIkgOwKMncj5Ds0SjfZd2R9re7AeWkGOFUhuOrrd+jFDPMEkJ1XGPhxdY+cRzZARPJfR9Jiqm/P2wONKHJwJRs6jt0Su5nWHJfQj2IYBQIp14xBkI47OE/BVyUFI6/KCk5zJOSGY1W2bFjB03TrOGtzQyHNKNRnTGQghWjWInxGI0phvtyNOZg0GAU86hmlMYw9c9qMYyCjgpHjx9ndmYD3//Wt3LPPfdM9FtUlYGqUko5IbzVdUi7WHw4M8vc3CxzczNsmnejq6HSphSWVlYBWF2ZY2Z2tt2tuwuw/ruUwszs6V2vuxi6TlYd48zM6V+vC8/qYqgnZT861Y+dP/bYo/zoj/4Yo3o8u1PgoVRJiPqJBRkRo6C+oxchSaGIxC5uJHEfwDdqN3xTg+wRKXd2EyRIBppjy/fLY02CWCzTxuHX91MAEfdPNJESqBopFcwyJurAqg3jWpx6DqkExVIiNwIDQa1BAWRAQiE5XExJ/URCyQgFIZlB9rk8cOAAt912G/v3728jiMOZGVQDEShoSUhuEM2U5CecFHWIGbAzlwZJghRDs0AJ2FVdu2wUMxI+XyqFpjF27drF0aNH2bRpU7txt455fcjVuCrE6Ds6DkdW2bF9C1lg49wsG+ZmOWfjHNu3bGL7lk1s2TjPpvlZNszOkMTYsW0LWvSEHbhraDu2nfr1ztu6haa3uLqn0qhpOO+0rncOTWcy+vmMesLVxVgXdimFpmligWbmZgZtLN8vFmFZbbBGHfdSwo9whxot8ZAdMydzTG9aUDGKGlZ8QaiGU6wGVtDSUChIY6j6gqOBTHPScZj5qVHUoAg0DaYlIIWhlj2qFUhBDUwLNH4tMCgKZqRSGMwO+PM//VOGgznPe2jDYGbIvfd8g5mZAapCMcEEv6cK8RpFLLFp06Z2Lqvt7dmzh4cfeRBTQ1E04GXBEG187pLSqNKYbyBm0IQda6MoDUbB1DwQUvyE1tJgKFqM1dJw6Z5Lefzxx1vb7B4EqbtSJjmmXYjVNIXrr7mCI68dZmaQmJ8dsu2cTezYtpkd2zaz9ZyNzM8OmRlkjr52mBuu2c/qaHRCZGcMSxpuuGb/qV/v2isYxfW6GdFqtE3TcMNpjq8mGbs+xyRSX520GhMvpfDC889z7XXXsdKsYMV8t7fA3ChYJmWgGKkIlh3SWeQEwJDkp0UJKKIioGNXW9R3PnKKEK+E32BYDlxvUMTQzEnHIREQSCQaMSRn9+dlvKOmMUr3aFRKcco43JIUicWU+G+3fYHf/c+/x6c+9R+ZGQ6ZmZ3jtz/1Kf7PX/vX3HPvvTHaQsYgKUnFo9C5oBirKytcdeVVvPjii+1zEBGOHTvGxk0bfXGabyxGQ1GHmaYB4YqRLDYIIXyw4vDQ/HoJQ61BTHyPKeZ3aMbxhQXm5+dPSDCaGamPt7pQZRJL8qYbrmP56KscPnwYEZgZJAbZ/5sZZMA4fPgVlo++yoEbrqXCtq4Bdv2bm9/8JpaPvXZq17v+2hNgTXcxN03DzQeuP+Xx3XLg+hNoGN1Togsxu4umnijPv/AC+6/YTxlZZIo1YJIf5yLmBpeFMhCwEg67J8QkVacyRe66eLg1aRtcUVFSgmzFsx3uWSKSkWIUibiSpcD1648DMU/ggTvP6r5PskhrmEMfRFEJKBcZfJPkjq4nQTA13vk338mHfuJDfOXOr/J7v/t7/M7v/A53fvlOfuqnfoqbbjhA8di1/2nZr5kU0YQlhz7XvukannrqqTW2snXrVpYXFrBmBH5+OBnA/CRxP0NJVjySZoo2DrLcbhu0eDTORONnxde3FUQLqoVmtMreS/fwzDPPnOBe5J/+6Z/+F/1dvZ9V7BqHiHDDtVdy51f/ktVRw9ZzNpMkMRo1HD16jAce/hbPPv0k/+N//941Wcr1CoNuvO4q7vjKetd7gr/3t98zkXJ8QpTJjBuuu5IvTxnf/Q9/i+effpIPf/DHJiqO9EPX/Yhd9UuWl5fZMD/ProsupJhDBEniOzaCWMakuNMsjp0znhzTSv0wRbL4yYCQyWgliJhTMzKZRty3cNhDJNgMY0ACz66H333ScRSHVSnCrZbdfzFpc4okFLHsvkEkBE0E6YSPfXxQrHDF/suZnZ3jttu+wHPPPcv73vdefuiHfpiVZrlNbLYJy4Hfm9uSn4jaFF47coScUuvnbd26lccOPsa27eehxXd/JO7LQAZgJRZ84+epZM8JeYwtIaKIRZpGxXNFLTvMIuye2LRxE48++ig7d+5c48/KPffcY5O4+11nvOsj1N/Pz2/ggYe/xaNPPUcTGHc4GLBvz0Vcc8U+VlZXpkrgTCrPrNf71pPPnnC9a6+8gqWlxTUOUx1T/VmfGbphw0buf+gRHn3yudavaMe3/3JWVpZPYOXW+6vX7CYcu9GUpmm47777+OAHP+h4NxYlSdr8gOGOY45TwCpIsRQwxkjqxi7iECCJY3MBj91L8viXKSlFrN7iG6SyrOp1OaVxEAlB1EPFyTzSVCkjmgSp2XGNPALBO2kMy0JW8YhW8VNpODvLp//g03zjG/diCDfeeAN/+8c/yOrqClgOLpZgA8NGKU6vOI0QhMzK8iL/9fOf58orr2QwGJBz5v777+etb/l+jh096rAzCNApbhMqRItTRVKHGBmcF6CYkSUjWlr+pNNrIodiwlNPP8WuXbvWJKoHXew+GAwYjUYnxPS78d9q3EtLi+zfdym3HLiBuVlP1qyurPLakSMsryxPrNfuhnL7hLKFhePs33cpN9/4Jubm58BgeWWFI0eOsLBwfM3i7BrytLrlhYXjXL1/H993043MzsyAwMrKKseOHWNxcWEq6a3PzO0nSFWV0WjE7OwsMzOzLC8teagTQ5w8FVljZ8B6bD/Ig2YkUaz4I1Tx06Sh+E4cxuIZcHdAU8Ak0+T2ihtWzYSj1NThScfhYM4dbne6fVcV8bCx5zpicanvvO2qix+bepSrFMgizM7O8h8/9Z/46p1f4f0f+HEA/ugP/5CVpRU+/KEPsTxa8XAxhpRUM6C+IFViDgqbNp3Tnso153HhhRfyyuGXyGmGOjtJxfliqYbFPX+hpiQKWIoNB1CFQYrTsqGIRLTKT+xk0ChA4Yr9+3ng/vvZu3dvaw+D7mmxsrLCYDBY44TWf3eNsJsPeeWVV9aVdekvvm7Uql88tLq6yksvvzy1sH+aSkh9NU3T+k0iwuLiIouLi+0J2K8zmERP7+Z2qvPdz3EcOnSI6667jtXVZTQZ0pgf81KZrNWgAuNWrlJSSolEWPL9WqWGOt2eJSlaguJhvusnEc/yV0ygRkkpiH+QRSnCScfhnCl1smM44BVIdVnBnnFOEfpMiBVUnMxYeWFZ3FP6/z77x9x5x528//0f4F3vfAdigpbCZ/7wM1yyezdveetbnL8lCbNC5cAUJ7d4SFoSS6Nlrrnmap555ll27tzJcDjk3HPP5eDBg1x2+RU0qytgQol5dNaDopactoLFCVyQLKhCSua+hQTzWD33YwKpcUaA/8ztbBRRs/bk6OPsLkTRoHj3C/Yn1Rv0/ZJJBSarq6troEr3c/XPmvnuQ7FJmfu+sMAkI+/WpPQTndMURGqCr8/6rD8/dOgQ73nPezh27HhEYzzk6Md6pX8bFbAIhonDJKhoxWLXTwFp1NdPY8EgFzT8Dv+AOwbOrjWPgKXKbfLo1CmNo15HPHFmUhgTVQh+lOOWLM641aCFWEtbj+cgyo/+yLvZtnUb3//Wt7G6OkIwfviHb2Xnzgu48c3Xs7K86idNzTGUoLlLxUdOiMwI1159NX/5l3exbdu29jkuLi4yPzvL8dUVSoNDtDjJLKBRI0YmkqXOcEQSFI2cShKkLowSSUlLkU+CZMbi4iLnbt/O8vIyMzMzbkt33nmnTaqK6lZx1aOuX7vcx+yTanq7MKpbfNR1quvu3F8wfQp5d7ev4+v6Al3o0/eX1hMHm1aLPEl8YWFhgZWVZd7+gz/IatOEPzDwya8bdXLoQwnqglR6OBFNcqhDOLbq22dEIiM513iUR8woyZ32XJ3sFDukuPtSKhnxFMbRJgZjx0ymIIM2CWkBO6xS4FNk7cVQC1jia6UNh1rOfgKotgnLFGOWDkFRTZyuUmodSaX1BNoYCF+548vMDGeYn59nZmYGVeXwK4fZef4FqFkEH2owISElnil+X77Ak/PQLBYzYNKQbNDys2rEziJQkFDO2bKVu+6+i71797q9dxNp/d247yfUnMC00Gw3kdNNltXPTitb7VZ91YRQn6zY/96+L1TDq30nvY6l+2fNldSxdU/Mfji3C+1WVlZ45JFHeOtb3sZodTWIbL4raTAKa8UFxTlOTlfxZJRU34DkcXuLRG6p4VdAszu+QZZTBSkOY6zu/MUJWaYRTTuNcfhxlaIOQ+Ik8ARhqZBNPOyMJFLkFDTGX0wpJUCYiI+ztaHY7ASsGRuemS+iZCCqEbiKMKv6ovRxKbccuIWDBw+2lBIR4YVDLzAzHJLQCF1bhzZSPKnZEjiDvqLmi5sCyfMeJpU640466uPT5Pe4PFohDTLD4dARQ3e3rYbdzRB3F0mfqj0pD9CFL12sXiM+1ZDrd9WfdSejv+C6pMWukXezmv3/uhCpe63uoqvjrYuq6WHOetp1v3N+fp65+TnMMpTShjOt3QE9ROvYPI5/83oKlRL1FIrzNSRyAJXFamBNLexzjJ78mqq+YFJxACZ4dvB0xqFBFycpUMhmlBw0k6CxWnJDdlqKnwR+gezcrmD+WkR+tN1/jUJARRM/tSg+1mSU8K80KCGkgiEeoFAfkqkyt2kD8/PzLVlVVbn22mu57YtfYLUUNm7cgBYfmgUb2BduHJfFKBRnAqRIXBZnKIuCNMWTirFo0eKUEwEdGcuLy2MbuP32260LfU6m0zRNm3Q9XdZazDIajRgOh+2C6Auk9X2e9dQpJtU+96HSYDA4IYk5TVh4Te1w+Br9U+PFF1/kyquuYu/eS50KkiQoHtLmCHJEhGosnRrPD6IgOaIl5rAJ8YSYJoWSUSnk5Bwqq5gjJUyLR4tybhm8vkA4rXFIMmiEkqSlswseyclSTxL3XzyRCGLF5QaiZLZSw2t+JuHObaJuAuo8KLF6i/V/Dgu1pk+C1hEOcRLP8D/1zFM89NBDnH/++QyHQy91Hgx44IEHKKUwPz9PaZq4txpVq5WINZIXLoJGwZa4RyZtrNzvQVGSed3LzOwsKQm7du0aEw+7jmyfaDiJRtENuU2Td+z/vMvd6i6++u8uhOpHlyoEqousr3LXvYd+sq7eU9c3miSjWRdJ9WO6i7DuYIcOHeLHP/B+ji0skSWyA6kWKKU2x13LUn3HcuydUoSjgk6NJqwUkNziYMtK1hTwSONKvggk+WJJgbFNGswyScopj6MN+yZjkEAbQwYNlMwwfKKSPN8S9u9JNcmIRj1HkByliEfGRoKm5KzxONMkxpCjTEDw7L1FWUESpWgIX2SLkoKoGMzC/iuu4Mtf/jI7duxobWJ5eZnLLrusjXh2Swb69tO3iYpQuqWw1fftRkyHw+GaIM2gL0ZQv7juntN0nLoZ9a5D3GXdttTfyHr2F0QdcH8xdk+P6kt0F0w3RNyv0OtH37rXn8TA7YsorK6unlBPXEphYWGByy+7jMWlZa+YK8kd5sDqKejfRkNmgBaPubvwgNKUQYxRIZnvxil2VC3+WREnFOILysSDrKoCNAgShU/J687l9MeRygCNYqriTA7PyquzcX0z953fiIRMtnEJbQ7elnrQQHMhaaIBp8cHLPOKkUqV0VYvQsy8ZiVqQ8Tpu2OonmBlZYX9+/dz5MgRtmzZsqaMtm8bw+FwzabaZ23X1+zs7Bok008kT5JYSl0j74ZtR6PRGojV3fFreLOLxfs+S5f+XXfe6mtMKputi6DrVPfpIX1fon5n15/o+g2T9GHrOJaXl9fkbUoprTJJHWddwE3T8MQTT/COH3oXpSmRqnP6tyexvKRUUMQG7luY1GgqiSF5UDynkSzwdZSamkQxj4dXsyWyQE7uvFrUwWrKEIVPOqgV36c/Do3TS6VGsiLWr2PlkAxYKo5zaiYcozHncGlAGEsgJUUdObhn4ZAmp2Acx2JHpBO50tZvMrE2ny1RHKXA277/bRw8eHCNXX237Sd1C4e6cKceMd2sdI3ydJ31SYXsdYDd1djdyfuwqgt3BoPBCSJjNRFZrzccDtes+vWUUvqJwvr+4XC4Jsxcd4+6+6SUGI1GHD16lAcffJD/4e/8HZaPL3nVWXCSPLTpLB1LbqopZGsQT4aliB5pyaTAtwWQQfAhtJCDqaqRlCtBabBhwnKJIiOLTDfQSOQrTn8czsNIHhUL6J0HOGwzJxUWEZJKsDIEy4ZJ9ipDrUojGg67JwuCKxwejuc1LIfJB8YXEY9WRZGXImQN1i+GpuSnWTGWV5b48Ic/zNfvvZejR4+uQTffLfuR27/0pdhCiAL6MUmM4J7Uyq5WmiU0kmqEo2oj1Z9JyLVU3GqRFfU5Cp+ge52uDx+7UJ3kVgFJWPO++pska+Vqqq+FdcbT+S4i4tJqRdXQUCSU3JeTljM1HA64+qorWS4N2VJ8jQYBLpMoQUWHAUKDix9U+ptj/cBI4nymAEvxQBwe+XXjHlJBtdIQ05hwh6JZSPo6xtFm68f3i4IFnZycQhBhnJF3H1yD4hIlsCpjxq6M6+NpqTIhAySKFKfiD5K11A93xI0qFlRTqV42HLkhEyQJDz74wASxD9pn1SGutQteqM+acRBhLBI2wZ7Hw2+t6/lDh2woQhG8drkaazUUBI00ewpqDClR1EXGqiZRq2IR0jE5HM+avZWITzsTMqInEb2oC0BDoCxJ8IoiopCCy+OsS6c1iPiR7xFFI6dQvqhiCjHlLfwQN6Lx/Xssp5iQrBpK5JJbdqrXSYiF1kegDM8ZBDkvplIl5igHLSMoH9XZFIOSa2WdeXVbZGpdWMfxuVRHH39fLFvPVai87nH4JsDaZ6WG5SBFVl6X1PmHsV5QhEQcCZcsAAAWiUlEQVTN/3S+VfIipBosE0FLzWRnf1Z4Vtp9J/WAXcpRvBVUrprIi/vGxpG2yOWf5FkJRdx+Bh6DeN32nCRKFyV2No1Yd12ViguMpZRiB/AEVor4u0VM2+LYN/Hj2LO6cXhGFVjoVDjetnqsBMUnDuVURS1IpOw7TqP12K8Lw5Nm7vA5dUDVs8MSnl8hwpKhzKfqIgWu3RScHgtjSw4l6s6SgtWKuhqHU9OkzbYWMyx1ggPm7FZJyZ1UBIsyToschguG+HcXxZN+kdmuQVdNJRJw1jlVtS2W+k6MQ8W8bDcMMhWjSfgmY8Vza6o+P8Hd0wjFWlQG1mNc8OfqGWev2WgipKzqBuf+T4kyFB9f0TzOktdEqLoWlpl4HQaN86LsVJ+VeaTvO2jPg6B6erRDIIdR13oD/02s+uQTSJvrdfwpUTBjA2sTR9IINlCkyWiuzM/sD0DMSS0mTkqzhKbiANpo2aClEXLc2LhYP7Kfgb/rSSvWtMk2y7G7hbSHVUigtcjIKMUX60iEQQOWa/DU0BIs2ahRdqLOd2aOihZee+UwRYsbQ3a2qmbIxb1hC1U3oQ1ZjRm7GnkFEXKLIYmEn4zRRYp6kXofFYIEydHLB4OK0RmHf5eChOYVY2q81edWhdrCc3B4GBC3as3Fs0rFoaDXllQYowEVfcMiiJh10Yt2TqzkTGE/GeS7OkeDFD5CSfFnOFxSAjRKwKIUxklGvC4TGRSk8aIXk8bLO1NyxuQgao6roYaRWlSEWZhiIlFaAw+tpMANKeHx8Ip5Ww5NPDj1YnpPPDmFuoqMWRz1VfAMgvgnhpVwxIrn5Er2IqEkvjMnySjFT6SUnX/0HZij44tHWVkdccnu3Zx9fe+/Btr4DuvUBW1hjiTfL1IpNAKDyNiqFefN+Kbv8Wp1LaVKoSdi89Iq7/lRlc0jKJqsfW9JNi7cJ3mMPRwlrUzTtoYldokorjZxcKniO4e6DIWvfMVLSXODufU7wcE8yVZq2FDHO3xj1SeSVr0jWUE1ofL65shILC6tsG/fZW3M/ezre/uVkBJVZo5HCacxyDruuJkTzqzSHrK4WFqFKWLkyOWk6kTWLHllZhYP3UXZekRliFj4uHorBSFMzOPdFllaB8w4F0Y8sqJVXdzEaxnCaTXxMkpxBVn/uqSh9FcimuEOutQQRUrOdkU8vBo+kNcCvP45SiI0zejswjiTFodLODaUCJ21YbzgpKSICnn9rbSliCYRprOE5OTOoLg2kJHIUQYq2aMKOVVpRtpoeKoymVLpy0FbSA66UjinxRLJ7RfLGUWcyyMOzCLC6pg4uUaTmKDZa4fropFU2miNk3BaXgdSwqlLige1amVdcvr2654j9zfOvs4gWEVxVW2rNc2iHg7P7qiJiDujppTqtBSw1CDmcXRWidqA8LOtuAYTTlOQKOUZkwIrv8ZFugbqWqzSOulxZBQNOU+HLSkcNi3GAEHzyIPDGkxRF0cKCqpiKaT7i7rwWBX6ipNINbtoQHJGJjmFbEsVFNOWkWq8zjkadRzDs68zBVa5wQ2DgpAkObOsRFSiCsdJxdgZyKHm4OFbBhG4SZW373FzHUR7lKBGWIT2UieLOtTIaUQtmvsblT7txDUlkzRXIqUnk5LnHyQWBknIqDvFklxVQ2sCLBYdCcmGWnJJTvFQoRYhDYKBKhGxyQRPKLVhz29njlxMwDVaObs2zjBYFUmdxqzF3yI1l5DaTKSiaEkgrhhHEmaGmc2bNjM7mHF4o5HOi2qvXEJu3/DC/uAQEU53FokkWxDGUtVX9TLHpDkUx+tWPBYTm8kDl6jJngjy/GotAfUQclRTen11VMah47BdUUgpBJ6DFaCUEAwzJGVmN8yxYdM8m+Y3QM7Vg4kkkTE7nJ06R5VHZHEAnV0bZxysiqysefioiDCIWmQstbyYZMllKkMndX5mA//3b/w//MnnPsett97K//qz/wuriwbZd+IaXUo11m8pdFIjc12MJJGbiOIUzFzvtR1P01bOEUS9lDOPPPQQr7z6Kju2n8cVV1zuSStxaUxyiCfXa5iHgEuQ5VxCMORhUE/IVapQUGFTSqwsL/E7v/uf+eY3v86RI0eYGQ65/PLLee973su1N1xPWVnh2OICn/+jz/P+D3wgAgedOTJXRS8mDCIjXSkjZ19nCqyKrKMUT+J5mt4CK9MamAZRKhnMzczyG//2N3jowQe56aab+PrX7yUxJCWLCJLDnMoZwlwNIqc4naQySR1Mlcp5CQl8SSn8F2lT+W5YnpRqSmHvnktJOfHoY4+ShkFYyzkSSNYqjbcyXuKEEq1Z+6iuz4RAcpw6szNz/Pmf/lf+3k/+JN969GG2bd/Gvn37uPiSSzh+fIGPf/IT/Itf+iWOHDvGRz/yc+Q8OHGOYuJUPNTbWGkTY2dfZ9DiKADFG5aIppYe4KJi2qrsIQ2iwuzcLP/+t/4D9993H9u2bUO1cPPNN6Ml5F5qWNZLgl260Wruo6qMp7arllrxgFHtHyFgxeVUUggwN5W8KL7INm3eiKJs2LQRBQ5+63FyErSx4PxUiFfpGR4CdqFwRTUFT6j4Yo6SycEg8cd//F/49Gf+kBuuvx5B2LZ1G9deey2X7N5N0YZ9+/axuLTEz/7sz7Jnz+4WgnbnyKNmrhiokS23s7DqzINViaalbZQcNGXR0AbKThxIgllhbm6WT/32b3P3XXezY8cOzIwtW7byD3/mH7K4shzdiYxG8IRfKzwfLMiiYeAaxfnFI0ollMilbY4HRaNqLXnmXDJWCkVgzyWX8sSTjzOcmWPzhs0cOX6EJ558kt2790TysJCCJtBUVTypQoBGyRp98ELmrHgTl8OHD/MHf/Bp9u3bx2g04qMf/Qh7du9meWWZLENKafh3/+Hf8/xzz3HFFVcE6zeoJDFHLvDhVBlVF1FGcoSlzxrcmeVz2ABSoYTSRAlYoCl7D4eggc8Mh3zmM3/A7bffwfnnnw/Azp07+djHPkajDefMDUNhI1rwBllNVVlcWvRdNFid3quCwP7aGo5ZioYr3gekcnA8cqWklMMHSly+7woee+IgOQ3YumULh189zLPPPsPFF+9qWxRr66iH6oc60SxriBCrO82ShJQGfPozf8TevXs5duwYv/iLv8imTedw7PhxhEQjixxfXOa+b/4V5+04b1xGGwVHqXK7teZSSnTZqnUTejaSe+YtDu82mkU6HYEyYh5gFVNSHvC5P/kTPv/5P+Oiiy5sDeOhhx7i3e9+d0igyLgntYybtm/cuJFf/79+nXM2nxPKEwnJ2tJKUu0BIerZZIWmKdx11x1ITuOWXLjgGSHfLyS2bN3Cls3nUFTZunUbrx0+zPPPvsCFF1zoY8rR6kqcqGgaogiR6fYwrUfWBnOzPPLwg2zffi6X7buM7du2szJaDSq28OLLr/LRj3yEiy++mKNHj3p8S4RmtQkWLeHZV3GxqvAXGFNbZvnZ15myOEwsIq+1j0EmpdKqSKDG7Pw8n/7MZ9izZ8+a6r9zzz2X8847b90vKKXhi1/8Eu99z4+5+28lEhgS7EpXscgpuzyKKK+8dIiLd+9hkMQ1YtMIs2FIygS1pOo6hR9hZLZu386hFw6x6+JdjJrGe3lHEZEnxx37ayTzarPHJmU2JGNpyWVZLrrgQlaa1SBOehRr1wUX8NnPfg60RPbeN4Dl0QrLxxfbXuKo530oNm4qGYIHdhZXnWGLwxVhnJEq4lDDosREjZShrK5y1VVXsbS0dNpfsLo6YveuXWhxDySJdy8ySSRV1LIr1WlpT565jZs5fuwIaWbW9Y0sk5JGHsPFYES974KKMDDH+0X9NGmaEs0nvejHlFbqsu19h4euNdiBRYW5uVnX2F1aIqsXz2jxSpOl0SrLr7ziaRJlXAVnRm6VA6tgW/FkYuuE51pOefZ1Ri0OCrkMKGmsnySB2ZNAo0JZXuEjH/kon/zkJ9bUY59//vlcffVV3tpM2sLTtrZPzNiydQs33ngTy6tLkSj0uolkng/IOHFPa2mjGlu3biJnf2+tx0gdSYFg/XPs+AJZ1DsUkVhZXuDSSy9DKYg5M9ijYt4FqaiQcnFNpWxYyd5ZVYSiDeeffz5NU7j77rv50E98iIWlBVqhm5JdtsYysxtmKKPG+wCKK3VX9JSTM38tNFqrOksKn+fs68x5ydPPPF116sPochSF+C5emyFIRGQ+8YmPt7W8zz77HH//7/8kb37zAe+akw1TbwxZBbUV7yCkVW81HOycDG0kmh5KW8stVVM1VUHxCO9aFMvgnKnXXn2Nlw4dYtu554IVFldX2Lt7D6Vx/ydngvIuURIqQYyM8leSJzsju52ScMcdt/OlL93O4uIiBw68mb/7d3+C5ZXlqGly3+uVl17iV37lV7nxxhv4n/7B/8xoZTWKZizyi937SO6UR4vjFw49z00HbjprdWdKnsOakFUxjQ6exYnehdDmHtdooIWPfexjlJDc2bXrIn7zN3+Tv/rmN5zuPYrrFHXcrRaG6Ht+MYNSEFXKyHMSpp4LMNShkXmyT83afm+VKFi1/I6+eoRnn3uGrdu3oRiLSyvsufgSmlGlo9decNCkWn9hjKJGo4QAcqNOFUmmFFPe8a53ISJs3ryZ2277Iv/q4/+Kl156iY0bNoHC5z77x/yjX/gFzr/gfP7irr9kNg+pnQHaA7VoKwEKhjVB3bez2fEz7uR48qknLJNbdQ9LtaC4qkDUckZvmSXJM9Sf/OQnWxmUgwcP8lu/9VssLi4g5CASWtCVkq+TWmgURfFAiHpVXaZg9YpHtCza9bbyjeIwaSYP+NrXv8auCy6ClFg8vsieS/d4F9bIp2RxkWLNtLXX0Zpi3M8uKPBaO8DEybi0uMSv/ZtfY252luXlZR5//HEWFhYYDAZccsklbN++nYWFBd73vvdx0803U7Q5YY6INsaVGZ+Sy8+8+PwhDhw4cNbqzqSTo2BRqFOiFtuL8FMIFFA0+jQ03p8tZX7+536e5RWP7uw4b4d/Pqjpg2gmoqqIGk2IhlkqFINGjSZOBFXvEJpKQa2BQqhIBPtcFGu8GaIUb86+aX4TBeP48aPs3rMbbUY0USCF+omgRKticzHjohpL1JeHJqUpTl+36HmtpmyY38A/+6f/hAsvuojRaMT+/fu5+aabuf6GG5ifn2eQB/zMz/wDvu+W76OUZuIcWaijazFUCqWRXlHX2dcZcXI88eTjZpJoJYTa5iJjwYFKwo7MhwscZKGMCnd/7S7edMONbJyb94hTkii2DwVwAaxBZNCWt0rkARSviZBilARZw1hTLcgfh4UsKvEkpPEXFo6zcdNm12K1VjmrrfKr2lOefmg1WECdS+b6JjZuqFgpLHhgYn7DPMeOH+eRRx7m6NGjzM7NcsnFl7D3sr0cO7rg2XCxqXOU1JuqJFwsLQ0yh154nptuOutznDmL44knDPHqORt4Ew/VHPUXIeyg4pSLUK3TkHMPcaiqTeFwJVH14d2g1ZyqHmL1Xq0aelUaurBZooVCrdgLmJNrfTmtTlGKL9boA6HiDUwkh8SPiod9XUCD1EQ31VSbqsQCiSYsYhJtvdplBGY0SRhaFc2JTqbqQoGCYqc4RzUhmtOAF188C6vOLFhFzYr7jq5BIdeooZBUQg3PXD+1lOiyGBhe3dFurGqQatvpE6JKLjXeQ6HVEKoOdpwQxXMY3qXHG40UDGk80lTEe+URkvtaqScWPSrCnyBgVJXsMUtobtqGj973O8iUNCGr0zj3KciNqr7gBhqkkLZ3hYXBW0uzP5U5MhOn47SaT2dfZ8zi0Ej21cahRLzes9niESh1yEEJdZCIHCW1tr2UiF+H6Nmg0RWxrbQTV6zTKmxEkPQ6X1xlHNUKAwnZzuR1TqUEEz3V0m9DdeCD01Atz3jVYTSalOLYvwRd3YoLOlSVESxakdnIGzhqRJWiM5IFrUXR1z1HVb3x7OsMSgIGEhmTG6L/AsGXkoznMGosn+QVdC01PYWyRwqZ+mjxS9u1xHddBMvFdYdLaRuyCDky8jXWFO1QrLiUTklRo+Rqikkt1MktZEejM1UIK9RbkFQV1r1iRC17UZVEaxcpURUYcEqhiPsz0nj0rKr6IfK650gH5ezaONNODqnE1xAIIKIsVVXDosmIR1b94edsnUIoGxtRLm1OoVXwVWtVDnNTF03VeM1eUpqsbdjYRKKvsg0zDmUkKSKlI1Zcuw+NW+VWX8ePIRdSbheLjFwNBD8NBiWa1BOOe/gG5rMShUoBM78Dc+Slv+msxZ1RPkfoQbmYQY3qgI4E1QYzx+Zq3uAU9SyzVawfjd2LetMUxXtEW/SK8B50OT4T6iMaHY5QShVIEPH6h+TizVWlRIMoWFTRIjTi/kkJyCYWbFtTirijXlXNVUucHrX/t2vrWiNOlykuueNhZ1opTO/zEi20NNqhvc450qawYX4Df3XffWsoOGdf38PRqscOPmYpFG1ShlSyc5kyUQvurXSlNBGFicBU1F20WlPquk2VLlLFvzUUsVPrRIdvUCKqU6nudY83acNg1tK9MySvIHRIpeTk6iWErGfkMaM/orcPQ1rdbvdtShrXkVeyjCilqrkXVzqR6NtXhcorn+t1z1HxnNIrr77KyspS9LUIXtkayFUZPbV1g7WdWaPXfCsKYViwVySawXTeYIzJjq3av7Tq7bWPNxEKr+OQWrIs2p6I1umjN+011oSvrSfCyOrvpBaGhSp7R4e3+px0tXbbga+9le/WHMljjx70pHg4qSqCyMhLSU1c87XqzVpoCIbUjSuXgKYQcDbI4vKZskauvmrcgmhGJSRzglflSt/RtsBcMsc0t4TDksbibN4ZKSrwxJCiHnatRVFt96DIrkdttySX1K+ZE4v0dTXmFCdUFonmMcEOiJyMiLbq79+xOZJOo4ToAe6+j7WLX6r5mDe7SUGt8QaQHgk0Fd94skb9irR+XKp6KTIOr0t0lR1InKhrxkGba5LiRNRstZeGz1OTooePpjVtjMfPKuar6kNXKqq6ovugfVZEi4BoU2AaWsUhB0vQ1uJ5EJWX3605annVIkKREp1Ds3cBjRZZIeCHiIuU1V3FzBscinn72kQJ/K2RSIwFIJVHFUVNRNutCN820SvDdbAij5E1yIdGrhQMIWTjSyvCTU7MRqjUhZ4tdi6NZF9oZsVNSLZxf47sLYNTZMyl+hrRMyKpRueMyHN8p+coKqBU1GnuGCWVttNq7R8jql6LbnGaRu9AojamCm1HcUtUZDZutBqSQeoVj2hBtbgGcJETx4GXAljxZ+bs6WjtXIxRSLYq6gvDAqKGwkpSIoEM0gQnwSo1SZgp3tO8RBsJgnemMVduG+NnpbUeJ/Fdn6OBVme0hmKJTp9tljlk4iWq8qLfRirxuTJuQqPRJqgemVrPqugYlELbqf62WHSASuIdf1o2cNDMq9+SQqbexp2anKBo0fsiGMSR3EvW0ERfDRkYTSPef1oEHakLrJVEoYE09Aw+CVd/tKCwZ3IqSBn4Qygh+fnXNEeSBt8T4zj7rMZzNPjKV75KbbLT9idogVhIeNZjrdvaqsrsmESuo9Mjq6NCMq61DvwvXdzr35GihUBtKmNRm60hNh05OMfHMZQkqdN2rYtvg9LRJiSqhm0kO10BoZUBSiYtDBtLhNSuFFVwOnlo+K9xjhLfG+M4+6zGc/T/A8/G/snZpSWJAAAAAElFTkSuQmCC);
-  display: none;
-}
-
-* /deep/ quad-stack-view > #chrome-mid {
-  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAABICAYAAADRa1RpAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFycE5v9iFQAAAQtJREFUOMvtkjGSWzEMQx/0eYrM3v8k3vgqycalSwlI8Ufyl3OBFMtGIgUCIEd6PB6RBEASqvfONSrJXrDNbNkQ8ywA2y/SmayW+ZIESTsiyQsxo40xmMS2aUmYbheHpCVd0+UqJGGMsey3mUyldoUvlY3D9rIN0K7Wbe/WbZ+y1yWtaVtrp3VJzAEX6ZVjc2p7b2mtnYhNdl6m05rwtfV/ltx7XypJTpXeO7Y5juOlchzHaWxyrJmuhLapqgIJONv05+srThBgiQpBTSRwGOr3rwccgWHUhJ7P5/YNlbd/2XiL78L/WajP240AQUihfnx84EDJjCHKHjTAbkimQDgBjAJ1/3kHAgEk/gL71AHEWVXPGQAAAABJRU5ErkJggg==);
-  display: none;
-}
-
-* /deep/ quad-stack-view > #chrome-right {
-  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAABICAYAAACaw4eEAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyghKmOqnQAADE1JREFUaN6dmsuyZsdRhb/M2uf07bREYDykPeIleAMibNx92i9BgEPBgyB5xlvgtgI8VDNBI41xhGkpQowERgqw3H0ue1cuBlm1T/3Vu4XNiWj9l12XrMyVK1fWL/v6668lCXdHEt/1Z2YnnyUhCTPbX8dn45pmRkR81z7/XUr59Pz8/K8ePnz47/bVV19pnDhu0t+Pmx0Z+Pv8zWv1/eZnZ2dntw8ePPizZXw4bj5/P3vq6G/eePZiX9fd9/Xng6/reg78/dInzxPG9+/auH83GjEbPUahj6m1Hoa6v1/X9c+XPrlP7INqrfuru7+10WzUkUHvOtTojPF1mPdHSzdqPPXo5vm046bdq0fhGr+bvXZk6OgAM2OZBx7hZD7hnCzbtp149Wid0YOjx+eE6t8tMzb659Ebkg5PPY8ZvXpEQWNCzck2M4H3BWeM1Fr31/6+GziPmTefM3tcYzQoIt4a3+cso2EzhsYTzAAdw9M9M3rviPv683dl/Oi9pdZKKeVk4piVRyDu1NI3mCtARFBKeWeGbtt2yHV9HXdnGUMyGjSfZq4K42ajYbPXx836XjO+jsj3rawcFx5dPgK8bzJ6eGbzI8yO3j4yaMToiWF98fl0c4bNSXBEJ/Ozd1HSEY8BLGOIxlONeCqlnHyWtGNoxteRMX38uP44fkyyPnfpp58zqy/s7jsGj0rOEcvPVaMD/sj4I/zWWllmMB/VviOwHumv+dkRGc9EOtOUu6fHZteOGBtDN/+NeJwPNRsxl54RU3PIO4x827a3wNwfdr45kib92WhAf9+fHem1I7FZa31rr+WIr45kzrjZsixvZWHHYcfqXFHGctM9ta7ridcigmVZWNf1DvyllN2wkatmHIxCby7kYzbPOD2qFCN39efrut55rE8YM3I+8VENHPFVa2VZlkOSdXe2bTuhmHdl+W5ox8T8YCbD/l2t9YQqRiNGjx8l1JEamVXKri56doyTuzfGhWd+OyLJjsNRlo+eHaX63Iy8ldnjQn3hbmA/yagGusfG7JwrxZytcxMyjpnH77VyPEEP65iVs5tntp4ldp8zlrG+x8z2Y9L1f91Jy+zeccGZn0Zv9nFHTH500BGbM6HOojMiWEZQf1cN7Aut68qyLCdeGFN+xuRYJ7tXu5fetU9EZCiPOp8xm8bTzLqpe2jkoDnzxjCOa8/VZByzzG7t8gQ4eT+GdO4Be0kZDTgq5kea/0g0RgS+rushNkbg93o6aqeejUeNR/fcUWmaqWLbtn39MdGWGcRHUrcb17E1jhszq3tvxNCsJuaE6VGZMbeMKTrL6LGelVL2k41jx6zuRbknSS9BI7WMdDRTxLi3z+VkDl3/7vb29oS3xhoZESdZOm4whrW/7/NHT83UtNze3u6c1I06Ozs7wdjc7PaQzsV8JNSOp7k97IDvtDPDYTdsvts6Pz8/MXCsm2PD2g/Tm+Vx0bHZHTNvjMyRyh2pajk/P0cIZEAHLLgXQLg5ckDCAFsKCwtIeHHAQGAmSnEkMAyZMBkin4lc3jBEM4a7MZgo7mBGhLD/+M1/qiCqDJflIjICYbknjlEtQEl81cBDYIaUi3aDwoEQ7mABuFMjcHOMQHLMRLSDhhlFQk4+k9IhLggZBREeVLN+NNwNCAhRwjGMimGyPJlA3owyIwiKEltWjTBHNchIGpLleIS5ITNKQHVDYRiBGUQI/83X/0XUyorhm2EKAsvT1IqFgwusgglCWARV3SuGmdNchwgiRHWQagcHIqCNJ7whJ6AI20AeUJ3A0ilP/vQJ33zzDdvNDbWkO91oAwphrah7wVGG1cHMqSHkggiwDJthmAcgjIIVg5rfWc1h2AZ7AgBLpMElMpQCUyOSX/3rr/j+9/+EGoEQTgKxKnDADRROmCiWySJBeILbMCxENVhwBISCnldm4EBEeiQRk1AJs/Y5ER2q7BX03v17SQnumDeXRqXgDaSA1cSdIExQDM+UgtoArTyMIjABJUPt4S2hRHEIgbdstV5LI4OusDvDMgMNqw3sHqi0HPcMotyRNqp5ArnmRrkLuBm4kHmjDAeEDMICk2PFMwomqjI2xYSHsJIUUnxoeBO7rdQUJ2qeJk8SLfdLGtgWCouEVzFUG7NXMAXVG1YqyDdMhSDgFuTpabUEiUguUw3AiAafbhoR4EtmpJknKArgytMaBHBmIozEIQ41M1dK7ySGEvxQ8NoI1w2WFh0XlsUaFYilJ5zhpuGKwBxXeygIqxlrE6Ih1wKPgi8L799/QGcJo4M5o9oYDfcKUZJmEFdX12zrikh2xwwrQA2KOeqETRlCGaKaUFXLpjQwy5Elu4dzflb4uw8/5MXP/wEsE6ORVX8hbVRzTVcN4ic/ec4HH3zA7XaTC1sQtZUXAm98Z7I7uvjii8+5ePw4pUiwu7TXuogM3cX7j/jhX/yIJz948gf/NPjll1/yy1/+E//z299RCGrL+AxI8krQfhk5Ab+6LmrGyDA1dvfkqOvXNzy7fMonn7w8umjafabmsDuowPPnz3nz5joLiN9VCwIqJDGHweixV59/weNHF4itZSMJbGq61kg3h3N2fs7D9x7jIdTwIzw3tCxrZo560U5U8frNFdu6URWJS8RmRukto3smv07uxwJrMa9uLDJCG1ZKI87AWJBvhEOsG9WEhSVcWBtu1A615da2kboiPaRW4hSRcBGEClhg0cTDycWdJR1XgUdkrN2hRqslGapydo+fffgRL37+Ir1opzrrJHZDAiB49vySv/3gp9zcRiqLCpsrjSLrnpQ27KH8/ItXPHz4PtRbRMoTajrBw6Hk4o8vLvjhj/6SH/w/wf/xx//I629/u9fPjkxLIZfVwmLwWBhQqUqgU1NZlCrkQVRwGW9urrl89pRPXr78gw27vHzO9dVVI2cIOYVIGHkrYXVDUQaPvXrFo4tHbFV7dnkjzGT+5BjXwnK/cPHovcRLI9hME3ZeM2+HtRwQAVdXb1ivr6ldzfYC3sSnPFAUZHW+HE7WtqamZL07avrcnYgKKtR6m/VKQTR9n0JQjZj7KqD2LCLY2h4quqsKNUWA5BQPatjAY1hTpuAO2iqlGLV1EQJ8C87vnfOzjz7ixS8+5vf93y+sFeZnl5f89K//htttw1bAW5d05rAK90awjOD//BUPHtynblmInXStyUHJR3jw3sV7/PjpU548eXJArvZ/gv/Fx7/g9bfftug4NfVKa7byd8pN9ZT5I9rFSM/wSPFXrOn5Tby5vubp0x/z8uU/t1Jx5/H9v3b3/q4YGJfPLrl+c0Pde8lgEWxN0znG1jG6e+zfXnHvwQNETdmMINqlSEeZJ1Dvn93j4uJiL+6jv8TQO9L6lya9f/fta26228wodVwZboFU2gLbqbqglZLarzTbdpvBEhWxNJI1bq5uuV6/SRCHt35AyAwPo5aKZzlIHRb5SqTR1nRSnitQtC4phNlyqvlTppRUlmZEQJizhCErbYSa57J8SNkLRm3s7RV54AHymjK9cYjUyg+wqV8XRCtfdzea+IZiFIoSsFKBEm1SE26SpXZCeDh7g9P64R4SrU2ZkC1btea5TMDsqCJ5UfUuZwO1BlnZ6tkgrWWWqjOgqhJmsLWa2dowsKZK0nuKlMWokWWBoBIeiJpZF6CqhtnMdHSHW6PdZLfijjISu2HX11dEjURrTza3BtymzaLV5NZwEGQYW4ekaLdCkXSDRCkidr2n/XKGUlOKjxc6oXZN0H4ZefXrVxQ3atTsjD1lkJpIDNEwlSCRZ53rp4zViNiQtqwEStHT1YoUOaclSY1MmmjXCelNz2Q1T5L/7LPPYDEePXqYNa0ENHnd7xeKKUFiAO2HBM97DZMoS1prMmQLrqCE8uZHIgVDNAFpFEW7BnGKWQtnYJ6GOmL54+99D0JEzfT1alRzikHtda+1/4nsxk/VqQZmlXXzJMUiqFu7nrJMe8v2LhteteuAvEcrVqk1m+Owdn9h7ZYSE6WAIrkjPCVIFua8s0jhWHfhZ5YZZ6rZNxoplZp3clg2uUSKAcmwYpgqUs1iFI5Z4rr3mliq3IVqVDbwM9CGkao1rN1IR6F4xepCEFht1wAhIKjRNH0Dv6ym5lHrEQw8JSlUtapghHJ+qiK13OyZ6yyf/sunSYqyVuPavVVq3bvSgrKxcKVGU7/s1U5ovXz1W5v9ftPVet68cbSehRo65ZNfUuB/AWHLchVUWJtFAAAAAElFTkSuQmCC);
-  display: none;
-}
-</style><template id="quad-stack-view-template">
-  <div id="header"></div>
-  <input id="stacking-distance-slider" max="400" min="1" step="1" type="range"/>
-  
-  <canvas id="canvas"></canvas>
-  <img id="chrome-left"/>
-  <img id="chrome-mid"/>
-  <img id="chrome-right"/>
-</template><style>
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view {
-  position: relative;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > top-controls {
-  -webkit-flex: 0 0 auto;
-  background-image: -webkit-gradient(linear,
-                                     0 0, 100% 0,
-                                     from(#E5E5E5),
-                                     to(#D1D1D1));
-  border-bottom: 1px solid #8e8e8e;
-  border-top: 1px solid white;
-  display: flex;
-  flex-flow: row wrap;
-  flex-direction: row;
-  font-size:  14px;
-  padding-left: 2px;
-  overflow: hidden;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view >
-      top-controls input[type='checkbox'] {
-  vertical-align: -2px;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > .what-rasterized {
-  color: -webkit-link;
-  cursor: pointer;
-  text-decoration: underline;
-  position: absolute;
-  bottom: 10px;
-  left: 10px;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > #input-event {
-  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMnwAADJ8BPja39wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAyNSURBVHic7Z1PTCPXHcc/4wWWVbJN2cJSLVqiQJuGpoIGEVWReoBNIlIF5RCRSysOK9EbksUeOHLIIQcULbLEEYk7oqduD6gSRoqUEyK7dCOabOHghCiAE/JntQtesHt4fuM3z2+MZzy2x8ZfaTTjN+Px4/fh9/7Pb6xMJkND4VGk2hloyKkGkJCpASRkagAJmRpAQqYGkJCpASRkaqp2BvzKsizf3w1z38sKc+ZUaQCuAFeB57P7q4AF/Kxsj4GnLrfL+6PDYofQAskCaAJ6gJeB6+QAFOvZpwgwPwOHwCNgN5uu/+H252raJHRALMu6ggDwCtALNAf8E88QUL5AAHqSTVcNUTU4oQBiWVYzMIiA0E3lGhtp4CsEnPtACgFDGqXiYKoKxLKsCPAaMIwojlzV1tZGV1cXHR0ddHR00N7ebh93dHQAcHh4aG/JZNI+3tvb4+jo6LzsPAY+QYA5Ix9KBsoPpmpALMt6BXgTaHe7pre3l5GREUZGRujv7/fdsspkMmxtbRGPx4nH4+zs7BS6/HtgHfgvOW9xeE05bVZxIJZldQNvATf1c5FIhMHBQYaHh7l16xbd3d1lyUMikWBtbY319XU2NzdJp9Omy74B1oAEAoa8yIZTDttVDIhlWZeB94Dfm86Pjo4SjUbLBsFNiUSCWCzG6uqq2yVfAv9CNKHTlNlbKgLEsqxrwF+BX+nnhoaGuHPnDv39/WXPRyFtbW1x9+5dNjY2TKePgBXgOwQUFUyg3lJ2IJZl9QAfAK1qek9PD9PT04yMjJT1970qHo8zPz/P7u6ufuoE+CewQw6Kw2OCsGVZgViW9SdgFNGLBqC1tZWZmRnGx8eJRMI5lJZOp1lZWWFubo7j42P1VAZR4W8gWmJn5KBAAEVYWYBkm7PvIvoWtjo7O1lYWKCvry/w3yyHtre3mZqaYn9/Xz/1EPg3ot+iQslQIpTAgWRh/A0x5GFrYGCAWCxGe7trKzeUSiaTRKNRHjx4oJ/6CvgHoigLDEo5yox30WCMjY2xtLRUczAA2tvbWVpaYmxsTD91E3gbMbTTBFxCFM0WYPntMwXqIdk64x3lM9FolMnJycB+o5paXFwkFovplfcniDrlNLvJXr4vTwnMQ7KtqVE1rZ5gAExOThKNRvXkPyMGQaWXlOQpgQDJ9jM+QGlNjY2N1RUMqcnJSb34shClwnVE8aVCAY9QSi6ysj3wv6N0+gYGBlhaWqKlpaWke4dVqVSK27dv6xX9j8AyYpDyGaL4svsqxdo5CA95DwVGZ2cnsVisbmEAtLS0EIvF6OzsVJNfQIzRlVTJlwQkO1Boj021traysLBQk60pr2pvb2dhYYHWVscAxEuI1pcKJYIHKKV6yFvqh5mZmZrp9AWhvr4+ZmZm9OQ3MAMpSr6BZOcz7CH0np4exsfH/d6uZjU+Pk5Pj6PbdR34LT69xBeQbG/8TTVteno6tGNT5VQkEmF6elpPfh24TK7VFaFIKH4t+BrKTN/Q0FDoRm0rqZGREYaGhtSkXyDqVs9Fl2cg2QUJw2ranTt3vN6m7mSwwR8R68dULzm31eXHQwZRFiSMjo5WfXIpDOrv72d01DFQcQXoQ3hI0V7iB8gr9pcjEdNQwoVVNBrV69EXcanccfEST0Cyi9jsSe/BwcGKz4GHWd3d3QwOOqaAOoDnMFfuRnn1kJfV7wwPD3v8ev1Ls4mF+Ac2FVsW5C8aLxpI9ou/U9Nu3brlOcP1LoNNbuJej+R5ihcPaQJ+Iz/09vY2iiuDuru76e3tVZN+jeiTyFHggsWWFyA9KAufL3K/4zxptrkE3MClYkcDUxQQU3HVAOIug226yHlIXvNXrUe8eEiHPGhra2v0PQqov7+ftrY2NekFzEVWSXWI3Rns6uoq6ZGyepdlWXR1dalJrRTwEFVegFyVB3L5f0Pu0mzUirC1CsPoJcUCuYLyGFkDyPnSbBQhB8VUZNm99nOBZC+8qqZdhBnBUmWw0RXMQHx5iOPpprB5yMbGBp999lm1s+GQwUZXKFBUSRULxOEhYQNy//59Hj58WO1sOOQCpGAfBOoESBhVwENMm61in/cOXRt3f3+f09NTAH766SdaWlrY29sDoLm5mevXr1cze25y9QypYoH8rH44PDwsIU/B6KOPPrLzcXBwQCQS4dNPPwXgxo0bfPzxx9XMnslGJ7h7hkX2GZOaBRKLxezjxcVFLl++zMTERBVz5JTBRseGy3zXIaEDEna5eAgENIX7WP2QTCaL/NrFlcFG0kMKLvIttsh6ilg83ATh85D3338/dGNrmo3SiAXYuvLgeImX9Rj4peHHqq5r165VOwt50mx0gjkqhJT92cvgol2P7O3thSa+VBiVyWTsJnhWsv4wBrZR5QWIjfzo6IitrS0vebxQ2tra0oPdPCbfQ4ze4gXII/VDPB73k9cLIYNtDnACUJ9td8gLkF2UiqkBxF2abc6AJOboD3lQzgWi1BWnCCgA7OzskEgk/Oa5bpVIJPTwT9+RCymoe4jvIkt+8Qs1cW1tzVem61kGm8jiKk1+gIE8eV25+Ihc3CjW19c9fr3+pdkkgwCiwsiL+oDyUKhXIE8QISUA2NzcbBRbihKJBJubm2rSD4h4KLLuOMMQRUiVn9XvdrGVTqcdg3wXXbFYTI9Op3qHuqlQHCoKSNadJNH7KGNbq6urjT4Jou+hRaVLIUoTE4zA6hD5Q5+oCXfv3vVxm/qSwQY7iG6C9BAZByWv6auOevgBIr3ke5mwsbFxofsl8XhcDw34BPgaYXg1KI0p6JlDRQPRiq0zRGQ1W/Pz827RPeta6XSa+fl5Pfl/5LxC3QrCAP9P4WYQcW2/kQm7u7usrKz4vF3tamVlRY/P+CPwLTlvcANiDN/kCYjiJXLv6AXNzc2xvb3t5ZY1re3tbebm5vRk2Vc7JReExgTDqFI8JIMIMvylTDw+PmZqaupCzCgmk0mmpqb0IJkHiLpV9Ypn5MA4oJimMDwD0eqSDCLIsD3WvL+/TzQaJZVKeb11zSiVShGNRvXgmE+Az8kVU8+UrSjvgNKCz8jxmaeIIMNyEoYHDx4wOztbwq3DrdnZWT1W1imi5XmCE0YKlyLLbYLPFxDlZhLKd4ggw/aJe/fusbi46Of2odbi4iL37t1TkzLAfxAzqmc4PcPkIQVVqofIfRrREVpXL4jFYnUFRQbB1PQIMZsqYaSUraiWlaqSQvxlV3rIFd2XEIsm/gL8Qb1ubGyMDz/8sGajzKVSKWZnZ3XPANHs/xxh+BSiyDrObifkirCiiisIDogK5TIwjvY6ijoMpHwEbCJAPCMHQIWhxl4sKmxsEEEwwQmlCQHlbeBV9do6CjX+DbBNDobqHSYYRQfCLDnimKEZfJbN0CpiENLOxf7+PhMTEywvL4d6mCWdTrO8vMzExIQOI4Pod31OPowTzHWHpz80kMjWyqpB6SXSU5oRQYbfARwVSA2+ruIU0ZrSK/ATnEBky8oxqlusnQMLNa4VXRa5Sr4JEYdwDPG8tkM18kKXJ+TmgWQ/Q3qDDsNTJa4r6NjvkA/lEsJTnkdEMX3J9N0Qv/LoAFFEyRaTbFFJGPK4ZBhQntdVgDuUZkTr6w2E1zgUspeC/YjoY3yPczgkZdhk568kGFC+F7qAE4qsU2S90owIpfo6ImCkUVV6bd4TxHzGtzgnmNThEN0rHK0pSngFUtleeeQCRa1XmhHN41eBAcRDka6qwIslU4jRhq/Jn8tQh0HUitttWtb3YvRyv4MKck8MyUeCZRGmeosMGPkiIshNpR72yCCW6hwgFiTI1pE0tDS6abDQ87BIMarEW9rAGUFNNot1MHL/HCIs3k1E8K9LAWfpDDEYepDd5Lopdc5b9Qx9r14nx/EgABhQASCQ109RizAdjApH9vhvIOJNvYCIFyJjhhSjNLlm6WMEgCS5tbbqAjbTlKsKwwTCHmCtmfcY2j/khCL3auwPNXyRGqOwifzQRq2IYk7dwDl8cYwwpjoqrRrSDYYKpdCaqpLrC5Oq8S5c+xCzx+hwTJtbEBdT3aMbUBpVXWvrtsnz+op1CNArVFXlbdEu3mICowJS9+cBsR/Exx2IaQG0af1tHggI1itUVft96vahsi/kOabPxQCRe93IaW3TAVQMhFRVgdiZMIORexOgQiDkXv3DdAObPMYIgAqBkAoFECmtJ+4Gp9Ax2rEORe51w+sQ7OOK17FhAqLKBY567AbBTSY4rsfVsktogagqACfvUpd0tz/SkR4GW9QEEFVBhtAI499ec0DqXf8H8f4X10jf2YAAAAAASUVORK5CYII=);
-  display: none;
-}
-</style><template id="tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template">
-  <img id="input-event"/>
-</template><style>
-* /deep/ tr-ui-e-chrome-cc-layer-view{-webkit-flex-direction:column;display:-webkit-flex;left:0;position:relative;top:0}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-tree-quad-stack-view{-webkit-flex:1 1 100%;-webkit-flex-direction:column;min-height:0;display:-webkit-flex;width:100%}* /deep/tr-ui-e-chrome-cc- layer-view>tr-ui-e-chrome-cc-layer-view-analysis{height:150px;overflow-y:auto}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-view-analysis *{-webkit-user-select:text}
-</style><style>
-* /deep/ .tr-ui-e-chrome-cc-lthi-s-view{-webkit-flex:1 1 auto!important;-webkit-flex-direction:row;display:-webkit-flex}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-e-chrome-cc-layer-picker{-webkit-flex:1 1 auto}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>x-drag-handle{-webkit-flex:0 0 auto}
-</style><style>
-* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view{-webkit-flex:0 0 auto;font-size:0;margin:0;min-height:200px;min-width:200px;overflow:hidden;padding:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view.hidden{display:none}
-</style><style>
-* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view{display:block;height:180px;margin:0;padding:0;position:relative}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view>.use-percentile-scale{left:0;position:absolute;top:0}
-</style><template id="tr-ui-e-chrome-cc-picture-debugger-template">
-  <style>
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger {
-    -webkit-flex: 1 1 auto;
-    -webkit-flex-direction: row;
-    display: -webkit-flex;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-a-generic-object-view {
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-    width: 400px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel {
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-    min-width: 300px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel > picture-info {
-    -webkit-flex: 0 0 auto;
-    padding-top: 2px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel >
-        picture-info .title {
-    font-weight: bold;
-    margin-left: 5px;
-    margin-right: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > x-drag-handle {
-    -webkit-flex: 0 0 auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger .filename {
-    -webkit-user-select: text;
-    margin-left: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel {
-    -webkit-flex: 1 1 auto;
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel >
-        tr-ui-e-chrome-cc-picture-ops-chart-view {
-    min-height: 150px;
-    min-width : 0;
-    overflow-x: auto;
-    overflow-y: hidden;
-  }
-
-  /*************************************************/
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger raster-area {
-    background-color: #ddd;
-    min-height: 200px;
-    min-width: 200px;
-    overflow-y: auto;
-    padding-left: 5px;
-  }
-  </style>
-
-  <left-panel>
-    <picture-info>
-      <div>
-        <span class="title">Skia Picture</span>
-        <span class="size"></span>
-      </div>
-      <div>
-        <input class="filename" type="text" value="skpicture.skp"/>
-        <button class="export">Export</button>
-      </div>
-    </picture-info>
-  </left-panel>
-  <right-panel>
-    <tr-ui-e-chrome-cc-picture-ops-chart-view>
-    </tr-ui-e-chrome-cc-picture-ops-chart-view>
-    <raster-area><canvas></canvas></raster-area>
-  </right-panel>
-</template><style>
-* /deep/ .tr-ui-e-chrome-cc-picture-snapshot-view{-webkit-flex:0 1 auto!important;display:-webkit-flex}
-</style><polymer-element name="tr-ui-e-chrome-cc-raster-task-view">
+</polymer-element><polymer-element name="tr-ui-b-grouping-table">
   <template>
     <style>
     :host {
       display: flex;
-      flex-direction: column;
     }
-    #heading {
-      flex: 0 0 auto;
+    #table {
+      flex: 1 1 auto;
     }
     </style>
-
-    <div id="heading">
-      Rasterization costs in
-      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
-    </div>
-    <tr-ui-b-table id="content"></tr-ui-b-table>
-  </template>
-
-  
-</polymer-element><style>
-.tr-ui-e-chrome-gpu-state-snapshot-view{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAEwATABMYqp3KAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90JCQsBMCH7ZqYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAUElEQVRYw+3WwQkAIAiF4Vc0hTO5/wiuURvYIcQOv1cRPhDlDXffSsrMsrYiQi/zU80FAACAVX3nt3lWAABA/x+ovnPyAAAA5AHyAAAA3wMOd34Xd+lsglgAAAAASUVORK5CYII=);display:-webkit-flex;overflow:auto}.tr-ui-e-chrome-gpu-state-snapshot-view img{display:block;margin:16px auto 16px auto}
-</style><style>
-.tr-ui-e-system-stats-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-system-stats-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-system-stats-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}
-</style><style>
-.tr-ui-e-system-stats-instance-track{height:500px}.tr-ui-e-system-stats-instance-track ul{list-style:none;list-style-position:outside;margin:0;overflow:hidden}
-</style><style>
-.tr-ui-e-tcmalloc-instance-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-tcmalloc-instance-view #args{white-space:pre}.tr-ui-e-tcmalloc-instance-view #snapshots>*{display:block}.tr-ui-e-tcmalloc-instance-view{overflow:auto}.tr-ui-e-tcmalloc-instance-view *{-webkit-user-select:text}.tr-ui-e-tcmalloc-instance-view .title{border-bottom:1px solid rgb(128,128,128);font-size:110%;font-weight:bold}.tr-ui-e-tcmalloc-instance-view td,.tr-ui-e-tcmalloc-instance-view th{font-size:small;text-align:right}
-</style><style>
-.tr-ui-e-tcmalloc-heap-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-tcmalloc-heap-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-tcmalloc-heap-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}.tr-ui-e-tcmalloc-heap-snapshot-view .collapsed{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAMAAADz0U65AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAwBQTFRFAAAAVVVVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASd3+7gAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAZdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjbQg61aAAAAGklEQVQYV2P4//8/IyOQYMBkMEIBA5yBWzEAD3Mj+VR5R78AAAAASUVORK5CYII=)}.tr-ui-e-tcmalloc-heap-snapshot-view .expanded{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuNtCDrVoAAAAoSURBVChTY2CgKggNDVUHYnsUQ4EC//FhBoIKkI0DKlYAYhmqupsBAMwgJH8K5nKoAAAAAElFTkSuQmCC)}.tr-ui-e-tcmalloc-heap-snapshot-view .trace-bytes{display:inline-block;padding-right:10px;text-align:right;width:80px}.tr-ui-e-tcmalloc-heap-snapshot-view .trace-allocs{display:inline-block;padding-right:10px;text-align:right;width:120px}.tr-ui-e-tcmalloc-heap-snapshot-view .trace-name{display:inline-block}
-</style><style>
-.tr-ui-e-tcmalloc-heap-instance-track{height:150px}.tr-ui-e-tcmalloc-heap-instance-track ul{list-style:none;list-style-position:outside;margin:0;overflow:hidden}
-</style><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-category-summary-side-panel">
-  <template>
-    <style>
-    :host {
-      display: block;
-      width: 450px;
-      overflow-x: auto;
-    }
-    </style>
-
     <tr-ui-b-table id="table"></tr-ui-b-table>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-input-latency-side-panel">
+</polymer-element><polymer-element name="tr-ui-b-grouping-table-groupby-picker">
   <template>
     <style>
     :host {
-      flex-direction: column;
       display: flex;
+      flex-direction: row;
+      align-items: center;
     }
-    toolbar {
-      flex: 0 0 auto;
-      border-bottom: 1px solid black;
+    groups {
+      -webkit-user-select: none;
       display: flex;
+      flex-direction: row;
+      padding-left: 10px;
     }
-    result-area {
-      flex: 1 1 auto;
-      display: block;
-      min-height: 0;
-      overflow-y: auto;
-    }
-    </style>
 
-    <toolbar id="toolbar"></toolbar>
-    <result-area id="result_area"></result-area>
-  </template>
-
-  
-</polymer-element><style>
-* /deep/ .pie-chart .arc-text{font-size:8pt}* /deep/ .pie-chart .label{font-size:10pt}* /deep/ .pie-chart polyline{fill:none;stroke:black}
-</style><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-time-summary-side-panel">
-  <template>
-    <style>
-    :host {
-      flex-direction: column;
-      display: flex;
-    }
-    toolbar {
-      flex: 0 0 auto;
-      border-bottom: 1px solid black;
-      display: flex;
-    }
-    result-area {
-      flex: 1 1 auto;
-      display: block;
-      min-height: 0;
-      overflow-y: auto;
-    }
-    </style>
-
-    <toolbar id="toolbar"></toolbar>
-    <result-area id="result_area"></result-area>
-  </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-e-rail-rail-score-span">
-  <template>
-  <style>
-    :host {
+    group, possible-group {
       display: span;
+      padding-right: 10px;
+      padding-left: 10px;
     }
-  </style>
-  <span id="content">
-    <span>RAIL Score: </span><span id="score"></span>
-  </span>
+
+    group {
+      border-left: 1px solid rgba(0,0,0,0);
+      cursor: move;
+    }
+
+    group.dragging {
+      opacity: 0.2;
+    }
+
+    group.drop-targeted {
+      border-left: 1px solid black;
+    }
+
+
+    #remove {
+      cursor: default;
+    }
+
+    #remove:not([hovered]) {
+      visibility: hidden;
+    }
+    </style>
+    <groups>
+    </groups>
+    <tr-ui-b-dropdown id="add-group"></tr-ui-b-dropdown>
   </template>
-  
-</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-rail-rail-score-side-panel">
+</polymer-element><template id="tr-ui-b-grouping-table-groupby-picker-group-template">
+  <span id="key"></span>
+  <span id="remove">×</span>
+</template><polymer-element extends="tr-ui-side-panel" name="tr-ui-sp-file-size-stats-side-panel">
   <template>
     <style>
     :host {
       display: flex;
       flex-direction: column;
-      width: 450px;
-      overflow-x: auto;
+      width: 600px;
     }
-
-    #score {
-      background-color: rgb(236, 236, 236)
-      flex: 0 0 auto;
-    }
-
-    #content {
-      min-width: 0;
-      flex-direction: column;
+    toolbar {
+      align-items: center;
+      background-color: rgb(236, 236, 236);
+      border-bottom: 1px solid #8e8e8e;
       display: flex;
-      flex: 1 1 auto;
+      flex-direction: row;
+      flex-direction: row;
+      flex: 0 0 auto;
+      font-size: 12px;
+      padding: 0 10px 0 10px;
     }
-
-    #coverage {
-      font-size: 10px;
+    table-container {
+      display: flex;
+      min-height: 0px;
+      overflow-y: auto;
     }
     </style>
 
-    <tr-ui-e-rail-rail-score-span id="score"></tr-ui-e-rail-rail-score-span>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-
-    <div id="coverage">
-      <b>Coverage:</b><br/>
-      <tr-ui-a-analysis-link id="associated-events"></tr-ui-a-analysis-link><br/>
-      <tr-ui-a-analysis-link id="unassociated-events"></tr-ui-a-analysis-link>
-    </div>
-    <button id="test">Create Test</button>
+    <toolbar>
+      <span><b>Group by:</b></span>
+      <tr-ui-b-grouping-table-groupby-picker id="picker">
+      </tr-ui-b-grouping-table-groupby-picker>
+    </toolbar>
+    <table-container>
+      <tr-ui-b-grouping-table id="table"></tr-ui-b-grouping-table>
+    </table-container>
   </template>
 </polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-alerts-side-panel">
   <template>
@@ -2792,7 +2937,11 @@
 function findFirstKeyInDictMatching(dict,opt_func,opt_this){var func=opt_func||identity;for(var key in dict){if(func.call(opt_this,key,dict[key]))
 return key;}
 return undefined;}
-return{asArray:asArray,concatenateArrays:concatenateArrays,concatenateObjects:concatenateObjects,compareArrays:compareArrays,comparePossiblyUndefinedValues:comparePossiblyUndefinedValues,compareNumericWithNaNs:compareNumericWithNaNs,dictionaryLength:dictionaryLength,dictionaryKeys:dictionaryKeys,dictionaryValues:dictionaryValues,dictionaryContainsValue:dictionaryContainsValue,group:group,iterItems:iterItems,mapItems:mapItems,filterItems:filterItems,iterObjectFieldsRecursively:iterObjectFieldsRecursively,invertArrayOfDicts:invertArrayOfDicts,arrayToDict:arrayToDict,identity:identity,findFirstIndexInArray:findFirstIndexInArray,findFirstInArray:findFirstInArray,findFirstKeyInDictMatching:findFirstKeyInDictMatching};});'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
+function mapValues(map){var values=[];for(var value of map.values())
+values.push(value);return values;}
+function iterMapItems(map,fn,opt_this){opt_this=opt_this||this;for(var key of map.keys())
+fn.call(opt_this,key,map.get(key));}
+return{asArray:asArray,concatenateArrays:concatenateArrays,concatenateObjects:concatenateObjects,compareArrays:compareArrays,comparePossiblyUndefinedValues:comparePossiblyUndefinedValues,compareNumericWithNaNs:compareNumericWithNaNs,dictionaryLength:dictionaryLength,dictionaryKeys:dictionaryKeys,dictionaryValues:dictionaryValues,dictionaryContainsValue:dictionaryContainsValue,group:group,iterItems:iterItems,mapItems:mapItems,filterItems:filterItems,iterObjectFieldsRecursively:iterObjectFieldsRecursively,invertArrayOfDicts:invertArrayOfDicts,arrayToDict:arrayToDict,identity:identity,findFirstIndexInArray:findFirstIndexInArray,findFirstInArray:findFirstInArray,findFirstKeyInDictMatching:findFirstKeyInDictMatching,mapValues:mapValues,iterMapItems:iterMapItems};});'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
 EventTarget.decorate=function(target){for(var k in EventTarget.prototype){if(k=='decorate')
 continue;var v=EventTarget.prototype[k];if(typeof v!=='function')
 continue;target[k]=v;}};EventTarget.prototype={addEventListener:function(type,handler){if(!this.listeners_)
@@ -2808,7 +2957,9 @@
 continue;var v=EventTargetHelper[k];if(typeof v!=='function')
 continue;target[k]=v;}
 target.listenerCounts_={};},addEventListener:function(type,listener,useCapture){this.__proto__.addEventListener.call(this,type,listener,useCapture);if(this.listenerCounts_[type]===undefined)
-this.listenerCounts_[type]=0;this.listenerCounts_[type]++;},removeEventListener:function(type,listener,useCapture){this.__proto__.removeEventListener.call(this,type,listener,useCapture);this.listenerCounts_[type]--;},hasEventListener:function(type){return this.listenerCounts_[type]>0;}};return{EventTarget:EventTarget,EventTargetHelper:EventTargetHelper};});'use strict';tr.exportTo('tr.b',function(){function RegisteredTypeInfo(constructor,metadata){this.constructor=constructor;this.metadata=metadata;};var BASIC_REGISTRY_MODE='BASIC_REGISTRY_MODE';var TYPE_BASED_REGISTRY_MODE='TYPE_BASED_REGISTRY_MODE';var ALL_MODES={BASIC_REGISTRY_MODE:true,TYPE_BASED_REGISTRY_MODE:true};function ExtensionRegistryOptions(mode){if(mode===undefined)
+this.listenerCounts_[type]=0;this.listenerCounts_[type]++;},removeEventListener:function(type,listener,useCapture){this.__proto__.removeEventListener.call(this,type,listener,useCapture);this.listenerCounts_[type]--;},hasEventListener:function(type){return this.listenerCounts_[type]>0;}};return{EventTarget:EventTarget,EventTargetHelper:EventTargetHelper};});'use strict';tr.exportTo('tr.b',function(){var Event;if(tr.isHeadless){function HeadlessEvent(type,opt_bubbles,opt_preventable){this.type=type;this.bubbles=(opt_bubbles!==undefined?!!opt_bubbles:false);this.cancelable=(opt_preventable!==undefined?!!opt_preventable:false);this.defaultPrevented=false;this.cancelBubble=false;};HeadlessEvent.prototype={preventDefault:function(){this.defaultPrevented=true;},stopPropagation:function(){this.cancelBubble=true;}};Event=HeadlessEvent;}else{function TrEvent(type,opt_bubbles,opt_preventable){var e=tr.doc.createEvent('Event');e.initEvent(type,!!opt_bubbles,!!opt_preventable);e.__proto__=global.Event.prototype;return e;};TrEvent.prototype={__proto__:global.Event.prototype};Event=TrEvent;}
+function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable){var e=new tr.b.Event(type,opt_bubbles,opt_cancelable);return target.dispatchEvent(e);}
+return{Event:Event,dispatchSimpleEvent:dispatchSimpleEvent};});'use strict';tr.exportTo('tr.b',function(){function RegisteredTypeInfo(constructor,metadata){this.constructor=constructor;this.metadata=metadata;};var BASIC_REGISTRY_MODE='BASIC_REGISTRY_MODE';var TYPE_BASED_REGISTRY_MODE='TYPE_BASED_REGISTRY_MODE';var ALL_MODES={BASIC_REGISTRY_MODE:true,TYPE_BASED_REGISTRY_MODE:true};function ExtensionRegistryOptions(mode){if(mode===undefined)
 throw new Error('Mode is required');if(!ALL_MODES[mode])
 throw new Error('Not a mode.');this.mode_=mode;this.defaultMetadata_={};this.defaultConstructor_=undefined;this.mandatoryBaseClass_=undefined;this.defaultTypeInfo_=undefined;this.frozen_=false;}
 ExtensionRegistryOptions.prototype={freeze:function(){if(this.frozen_)
@@ -2819,9 +2970,7 @@
 return;var curProto=constructor.prototype.__proto__;var ok=false;while(curProto){if(curProto===this.mandatoryBaseClass.prototype){ok=true;break;}
 curProto=curProto.__proto__;}
 if(!ok)
-throw new Error(constructor+'must be subclass of '+registry);}};return{BASIC_REGISTRY_MODE:BASIC_REGISTRY_MODE,TYPE_BASED_REGISTRY_MODE:TYPE_BASED_REGISTRY_MODE,ExtensionRegistryOptions:ExtensionRegistryOptions,RegisteredTypeInfo:RegisteredTypeInfo};});'use strict';tr.exportTo('tr.b',function(){var Event;if(tr.isHeadless){function HeadlessEvent(type,opt_bubbles,opt_preventable){this.type=type;this.bubbles=(opt_bubbles!==undefined?!!opt_bubbles:false);this.cancelable=(opt_preventable!==undefined?!!opt_preventable:false);this.defaultPrevented=false;this.cancelBubble=false;};HeadlessEvent.prototype={preventDefault:function(){this.defaultPrevented=true;},stopPropagation:function(){this.cancelBubble=true;}};Event=HeadlessEvent;}else{function TrEvent(type,opt_bubbles,opt_preventable){var e=tr.doc.createEvent('Event');e.initEvent(type,!!opt_bubbles,!!opt_preventable);e.__proto__=global.Event.prototype;return e;};TrEvent.prototype={__proto__:global.Event.prototype};Event=TrEvent;}
-function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable){var e=new tr.b.Event(type,opt_bubbles,opt_cancelable);return target.dispatchEvent(e);}
-return{Event:Event,dispatchSimpleEvent:dispatchSimpleEvent};});'use strict';tr.exportTo('tr.b',function(){var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateBasicExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.register=function(constructor,opt_metadata){if(registry.findIndexOfRegisteredConstructor(constructor)!==undefined)
+throw new Error(constructor+'must be subclass of '+registry);}};return{BASIC_REGISTRY_MODE:BASIC_REGISTRY_MODE,TYPE_BASED_REGISTRY_MODE:TYPE_BASED_REGISTRY_MODE,ExtensionRegistryOptions:ExtensionRegistryOptions,RegisteredTypeInfo:RegisteredTypeInfo};});'use strict';tr.exportTo('tr.b',function(){var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateBasicExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.register=function(constructor,opt_metadata){if(registry.findIndexOfRegisteredConstructor(constructor)!==undefined)
 throw new Error('Handler already registered for '+constructor);extensionRegistryOptions.validateConstructor(constructor);var metadata={};for(var k in extensionRegistryOptions.defaultMetadata)
 metadata[k]=extensionRegistryOptions.defaultMetadata[k];if(opt_metadata){for(var k in opt_metadata)
 metadata[k]=opt_metadata[k];}
@@ -2831,7 +2980,9 @@
 throw new Error(constructor+' not registered');registry.registeredTypeInfos_.splice(foundIndex,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getAllRegisteredTypeInfos=function(){return registry.registeredTypeInfos_;};registry.findTypeInfo=function(constructor){var foundIndex=this.findIndexOfRegisteredConstructor(constructor);if(foundIndex!==undefined)
 return this.registeredTypeInfos_[foundIndex];return undefined;};registry.findTypeInfoMatching=function(predicate,opt_this){opt_this=opt_this?opt_this:undefined;for(var i=0;i<registry.registeredTypeInfos_.length;++i){var typeInfo=registry.registeredTypeInfos_[i];if(predicate.call(opt_this,typeInfo))
 return typeInfo;}
-return extensionRegistryOptions.defaultTypeInfo;};}
+return extensionRegistryOptions.defaultTypeInfo;};registry.findTypeInfoWithName=function(name){if(typeof(name)!=='string')
+throw new Error('Name is not a string.');var typeInfo=registry.findTypeInfoMatching(function(ti){return ti.constructor.name===name;});if(typeInfo)
+return typeInfo;return undefined;};}
 return{_decorateBasicExtensionRegistry:decorateBasicExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){var categoryPartsFor={};function getCategoryParts(category){var parts=categoryPartsFor[category];if(parts!==undefined)
 return parts;parts=category.split(',');categoryPartsFor[category]=parts;return parts;}
 return{getCategoryParts:getCategoryParts};});'use strict';tr.exportTo('tr.b',function(){var getCategoryParts=tr.b.getCategoryParts;var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateTypeBasedExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.categoryPartToTypeInfoMap_={};registry.typeNameToTypeInfoMap_={};registry.register=function(constructor,metadata){extensionRegistryOptions.validateConstructor(constructor);var typeInfo=new RegisteredTypeInfo(constructor,metadata||extensionRegistryOptions.defaultMetadata);typeInfo.typeNames=[];typeInfo.categoryParts=[];if(metadata&&metadata.typeName)
@@ -2851,39 +3002,32 @@
 if(registry.addEventListener===undefined)
 tr.b.EventTarget.decorate(registry);}
 return{decorateExtensionRegistry:decorateExtensionRegistry};});'use strict';tr.exportTo('tr.importer',function(){function Importer(){}
-Importer.prototype={__proto__:Object.prototype,isTraceDataContainer:function(){return false;},extractSubtraces:function(){return[];},importEvents:function(){},importSampleData:function(){},finalizeImport:function(){},joinRefs:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Importer;tr.b.decorateExtensionRegistry(Importer,options);Importer.findImporterFor=function(eventData){var typeInfo=Importer.findTypeInfoMatching(function(ti){return ti.constructor.canImport(eventData);});if(typeInfo)
+Importer.prototype={__proto__:Object.prototype,get importerName(){return'Importer';},isTraceDataContainer:function(){return false;},extractSubtraces:function(){return[];},importClockSyncMarkers:function(){},importEvents:function(){},importSampleData:function(){},finalizeImport:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Importer;tr.b.decorateExtensionRegistry(Importer,options);Importer.findImporterFor=function(eventData){var typeInfo=Importer.findTypeInfoMatching(function(ti){return ti.constructor.canImport(eventData);});if(typeInfo)
 return typeInfo.constructor;return undefined;};return{Importer:Importer};});'use strict';tr.exportTo('tr.e.importer.gcloud_trace',function(){function GcloudTraceImporter(model,eventData){this.importPriority=2;this.eventData_=eventData;}
 GcloudTraceImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
 return false;var normalizedEventData=eventData.slice(0,20).replace(/\s/g,'');if(normalizedEventData.length<14)
-return false;return normalizedEventData.slice(0,14)=='{"projectId":"';};GcloudTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,extractSubtraces:function(){var traceEvents=this.createEventsForTrace();return traceEvents?[traceEvents]:[];},createEventsForTrace:function(){var events=[];var trace=JSON.parse(this.eventData_);var spanLength=trace.spans.length;for(var i=0;i<spanLength;i++){events.push(this.createEventForSpan(trace.traceId,trace.spans[i]));}
+return false;return normalizedEventData.slice(0,14)=='{"projectId":"';};GcloudTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GcloudTraceImporter';},extractSubtraces:function(){var traceEvents=this.createEventsForTrace();return traceEvents?[traceEvents]:[];},createEventsForTrace:function(){var events=[];var trace=JSON.parse(this.eventData_);var spanLength=trace.spans.length;for(var i=0;i<spanLength;i++){events.push(this.createEventForSpan(trace.traceId,trace.spans[i]));}
 return{'traceEvents':events};},createEventForSpan:function(traceId,span){var newArgs={};if(span.labels){newArgs=JSON.parse(JSON.stringify(span.labels));}
 newArgs['Span ID']=span.spanId;newArgs['Start Time']=span.startTime;newArgs['End Time']=span.endTime;if(span.parentSpanId){newArgs['Parent Span ID']=span.parentSpanId;}
-return{name:span.name,args:newArgs,pid:traceId,ts:Date.parse(span.startTime)*1000,dur:(Date.parse(span.endTime)-Date.parse(span.startTime))*1000,cat:'tracespan',tid:traceId,ph:'X'};}};tr.importer.Importer.register(GcloudTraceImporter);return{GcloudTraceImporter:GcloudTraceImporter};});'use strict';tr.exportTo('tr.b',function(){function max(a,b){if(a===undefined)
-return b;if(b===undefined)
-return a;return Math.max(a,b);}
-function IntervalTree(beginPositionCb,endPositionCb){this.beginPositionCb_=beginPositionCb;this.endPositionCb_=endPositionCb;this.root_=undefined;this.size_=0;}
-IntervalTree.prototype={insert:function(datum){var startPosition=this.beginPositionCb_(datum);var endPosition=this.endPositionCb_(datum);var node=new IntervalTreeNode(datum,startPosition,endPosition);this.size_++;this.root_=this.insertNode_(this.root_,node);this.root_.colour=Colour.BLACK;return datum;},insertNode_:function(root,node){if(root===undefined)
-return node;if(root.leftNode&&root.leftNode.isRed&&root.rightNode&&root.rightNode.isRed)
-this.flipNodeColour_(root);if(node.key<root.key)
-root.leftNode=this.insertNode_(root.leftNode,node);else if(node.key===root.key)
-root.merge(node);else
-root.rightNode=this.insertNode_(root.rightNode,node);if(root.rightNode&&root.rightNode.isRed&&(root.leftNode===undefined||!root.leftNode.isRed))
-root=this.rotateLeft_(root);if(root.leftNode&&root.leftNode.isRed&&root.leftNode.leftNode&&root.leftNode.leftNode.isRed)
-root=this.rotateRight_(root);return root;},rotateRight_:function(node){var sibling=node.leftNode;node.leftNode=sibling.rightNode;sibling.rightNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},rotateLeft_:function(node){var sibling=node.rightNode;node.rightNode=sibling.leftNode;sibling.leftNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},flipNodeColour_:function(node){node.colour=this.flipColour_(node.colour);node.leftNode.colour=this.flipColour_(node.leftNode.colour);node.rightNode.colour=this.flipColour_(node.rightNode.colour);},flipColour_:function(colour){return colour===Colour.RED?Colour.BLACK:Colour.RED;},updateHighValues:function(){this.updateHighValues_(this.root_);},updateHighValues_:function(node){if(node===undefined)
-return undefined;node.maxHighLeft=this.updateHighValues_(node.leftNode);node.maxHighRight=this.updateHighValues_(node.rightNode);return max(max(node.maxHighLeft,node.highValue),node.maxHighRight);},validateFindArguments_:function(queryLow,queryHigh){if(queryLow===undefined||queryHigh===undefined)
-throw new Error('queryLow and queryHigh must be defined');if((typeof queryLow!=='number')||(typeof queryHigh!=='number'))
-throw new Error('queryLow and queryHigh must be numbers');},findIntersection:function(queryLow,queryHigh){this.validateFindArguments_(queryLow,queryHigh);if(this.root_===undefined)
-return[];var ret=[];this.root_.appendIntersectionsInto_(ret,queryLow,queryHigh);return ret;},get size(){return this.size_;},get root(){return this.root_;},dump_:function(){if(this.root_===undefined)
-return[];return this.root_.dump();}};var Colour={RED:'red',BLACK:'black'};function IntervalTreeNode(datum,lowValue,highValue){this.lowValue_=lowValue;this.data_=[{datum:datum,high:highValue,low:lowValue}];this.colour_=Colour.RED;this.parentNode_=undefined;this.leftNode_=undefined;this.rightNode_=undefined;this.maxHighLeft_=undefined;this.maxHighRight_=undefined;}
-IntervalTreeNode.prototype={appendIntersectionsInto_:function(ret,queryLow,queryHigh){if(this.lowValue_>=queryHigh){if(!this.leftNode_)
-return;return this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
-if(this.maxHighLeft_>queryLow){this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
-if(this.highValue>queryLow){for(var i=(this.data.length-1);i>=0;--i){if(this.data[i].high<queryLow)
-break;ret.push(this.data[i].datum);}}
-if(this.rightNode_){this.rightNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}},get colour(){return this.colour_;},set colour(colour){this.colour_=colour;},get key(){return this.lowValue_;},get lowValue(){return this.lowValue_;},get highValue(){return this.data_[this.data_.length-1].high;},set leftNode(left){this.leftNode_=left;},get leftNode(){return this.leftNode_;},get hasLeftNode(){return this.leftNode_!==undefined;},set rightNode(right){this.rightNode_=right;},get rightNode(){return this.rightNode_;},get hasRightNode(){return this.rightNode_!==undefined;},set parentNode(parent){this.parentNode_=parent;},get parentNode(){return this.parentNode_;},get isRootNode(){return this.parentNode_===undefined;},set maxHighLeft(high){this.maxHighLeft_=high;},get maxHighLeft(){return this.maxHighLeft_;},set maxHighRight(high){this.maxHighRight_=high;},get maxHighRight(){return this.maxHighRight_;},get data(){return this.data_;},get isRed(){return this.colour_===Colour.RED;},merge:function(node){for(var i=0;i<node.data.length;i++)
-this.data_.push(node.data[i]);this.data_.sort(function(a,b){return a.high-b.high;});},dump:function(){var ret={};if(this.leftNode_)
-ret['left']=this.leftNode_.dump();ret['data']=this.data_.map(function(d){return[d.low,d.high];});if(this.rightNode_)
-ret['right']=this.rightNode_.dump();return ret;}};return{IntervalTree:IntervalTree};});'use strict';tr.exportTo('tr.b',function(){function Range(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};Range.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addRange:function(range){if(range.isEmpty)
+return{name:span.name,args:newArgs,pid:traceId,ts:Date.parse(span.startTime)*1000,dur:(Date.parse(span.endTime)-Date.parse(span.startTime))*1000,cat:'tracespan',tid:traceId,ph:'X'};}};tr.importer.Importer.register(GcloudTraceImporter);return{GcloudTraceImporter:GcloudTraceImporter};});'use strict';tr.exportTo('tr.b',function(){function convertEventsToRanges(events){return events.map(function(event){return tr.b.Range.fromExplicitRange(event.start,event.end);});}
+function mergeRanges(inRanges,mergeThreshold,mergeFunction){var remainingEvents=inRanges.slice();remainingEvents.sort(function(x,y){return x.min-y.min;});if(remainingEvents.length<=1){var merged=[];if(remainingEvents.length==1){merged.push(mergeFunction(remainingEvents));}
+return merged;}
+var mergedEvents=[];var currentMergeBuffer=[];var rightEdge;function beginMerging(){currentMergeBuffer.push(remainingEvents[0]);remainingEvents.splice(0,1);rightEdge=currentMergeBuffer[0].max;}
+function flushCurrentMergeBuffer(){if(currentMergeBuffer.length==0)
+return;mergedEvents.push(mergeFunction(currentMergeBuffer));currentMergeBuffer=[];if(remainingEvents.length!=0)
+beginMerging();}
+beginMerging();while(remainingEvents.length){var currentEvent=remainingEvents[0];var distanceFromRightEdge=currentEvent.min-rightEdge;if(distanceFromRightEdge<mergeThreshold){rightEdge=Math.max(rightEdge,currentEvent.max);remainingEvents.splice(0,1);currentMergeBuffer.push(currentEvent);continue;}
+flushCurrentMergeBuffer();}
+flushCurrentMergeBuffer();return mergedEvents;}
+function findEmptyRangesBetweenRanges(inRanges,opt_totalRange){if(opt_totalRange&&opt_totalRange.isEmpty)
+opt_totalRange=undefined;var emptyRanges=[];if(!inRanges.length){if(opt_totalRange)
+emptyRanges.push(opt_totalRange);return emptyRanges;}
+inRanges=inRanges.slice();inRanges.sort(function(x,y){return x.min-y.min;});if(opt_totalRange&&(opt_totalRange.min<inRanges[0].min)){emptyRanges.push(tr.b.Range.fromExplicitRange(opt_totalRange.min,inRanges[0].min));}
+inRanges.forEach(function(range,index){for(var otherIndex=0;otherIndex<inRanges.length;++otherIndex){if(index===otherIndex)
+continue;var other=inRanges[otherIndex];if(other.min>range.max){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,other.min));return;}
+if(other.max>range.max){return;}}
+if(opt_totalRange&&(range.max<opt_totalRange.max)){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,opt_totalRange.max));}});return emptyRanges;}
+return{convertEventsToRanges:convertEventsToRanges,findEmptyRangesBetweenRanges:findEmptyRangesBetweenRanges,mergeRanges:mergeRanges};});'use strict';tr.exportTo('tr.b',function(){function Range(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};Range.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addRange:function(range){if(range.isEmpty)
 return;this.addValue(range.min);this.addValue(range.max);},addValue:function(value){if(this.isEmpty_){this.max_=value;this.min_=value;this.isEmpty_=false;return;}
 this.max_=Math.max(this.max_,value);this.min_=Math.min(this.min_,value);},set min(min){this.isEmpty_=false;this.min_=min;},get min(){if(this.isEmpty_)
 return undefined;return this.min_;},get max(){if(this.isEmpty_)
@@ -2891,118 +3035,64 @@
 return undefined;return this.max_-this.min_;},get center(){return(this.min_+this.max_)*0.5;},get duration(){if(this.isEmpty_)
 return 0;return this.max_-this.min_;},equals:function(that){if(this.isEmpty&&that.isEmpty)
 return true;if(this.isEmpty!=that.isEmpty)
-return false;return this.min===that.min&&this.max===that.max;},containsRange:function(range){if(this.isEmpty||range.isEmpty)
-return false;return this.findIntersection(range).duration==range.duration;},containsExplicitRange:function(min,max){return this.containsRange(Range.fromExplicitRange(min,max));},intersectsRange:function(range){if(this.isEmpty||range.isEmpty)
-return false;return!this.findIntersection(range).isEmpty;},intersectsExplicitRange:function(min,max){return this.intersectsRange(Range.fromExplicitRange(min,max));},findIntersection:function(range){if(this.isEmpty||range.isEmpty)
+return false;return this.min===that.min&&this.max===that.max;},containsExplicitRangeInclusive:function(min,max){if(this.isEmpty)
+return false;return this.min_<=min&&max<=this.max_;},containsExplicitRangeExclusive:function(min,max){if(this.isEmpty)
+return false;return this.min_<min&&max<this.max_;},intersectsExplicitRangeInclusive:function(min,max){if(this.isEmpty)
+return false;return this.min_<=max&&min<=this.max_;},intersectsExplicitRangeExclusive:function(min,max){if(this.isEmpty)
+return false;return this.min_<max&&min<this.max_;},containsRangeInclusive:function(range){if(range.isEmpty)
+return false;return this.containsExplicitRangeInclusive(range.min_,range.max_);},containsRangeExclusive:function(range){if(range.isEmpty)
+return false;return this.containsExplicitRangeExclusive(range.min_,range.max_);},intersectsRangeInclusive:function(range){if(range.isEmpty)
+return false;return this.intersectsExplicitRangeInclusive(range.min_,range.max_);},intersectsRangeExclusive:function(range){if(range.isEmpty)
+return false;return this.intersectsExplicitRangeExclusive(range.min_,range.max_);},findIntersection:function(range){if(this.isEmpty||range.isEmpty)
 return new Range();var min=Math.max(this.min,range.min);var max=Math.min(this.max,range.max);if(max<min)
 return new Range();return Range.fromExplicitRange(min,max);},toJSON:function(){if(this.isEmpty_)
 return{isEmpty:true};return{isEmpty:false,max:this.max,min:this.min};},filterArray:function(array,opt_keyFunc,opt_this){if(this.isEmpty_)
-return[];function binSearch(test){var i0=0;var i1=array.length;while(i0<i1-1){var i=Math.trunc((i0+i1)/2);if(test(i))
+return[];function binSearch(test){var i0=0;var i1=array.length;while(i0<i1){var i=Math.trunc((i0+i1)/2);if(test(i))
 i1=i;else
-i0=i;}
+i0=i+1;}
 return i1;}
 var keyFunc=opt_keyFunc||tr.b.identity;function getValue(index){return keyFunc.call(opt_this,array[index]);}
 var first=binSearch(function(i){return this.min_===undefined||this.min_<=getValue(i);}.bind(this));var last=binSearch(function(i){return this.max_!==undefined&&this.max_<getValue(i);}.bind(this));return array.slice(first,last);}};Range.fromDict=function(d){if(d.isEmpty===true){return new Range();}else if(d.isEmpty===false){var range=new Range();range.min=d.min;range.max=d.max;return range;}else{throw new Error('Not a range');}};Range.fromExplicitRange=function(min,max){var range=new Range();range.min=min;range.max=max;return range;};Range.compareByMinTimes=function(a,b){if(!a.isEmpty&&!b.isEmpty)
 return a.min_-b.min_;if(a.isEmpty&&!b.isEmpty)
 return-1;if(!a.isEmpty&&b.isEmpty)
-return 1;return 0;};return{Range:Range};});'use strict';tr.exportTo('tr.b',function(){function addSingletonGetter(ctor){ctor.getInstance=function(){return ctor.instance_||(ctor.instance_=new ctor());};}
-function deepCopy(value){if(!(value instanceof Object)){if(value===undefined||value===null)
-return value;if(typeof value=='string')
-return value.substring();if(typeof value=='boolean')
-return value;if(typeof value=='number')
-return value;throw new Error('Unrecognized: '+typeof value);}
-var object=value;if(object instanceof Array){var res=new Array(object.length);for(var i=0;i<object.length;i++)
-res[i]=deepCopy(object[i]);return res;}
-if(object.__proto__!=Object.prototype)
-throw new Error('Can only clone simple types');var res={};for(var key in object){res[key]=deepCopy(object[key]);}
-return res;}
-function normalizeException(e){if(e===undefined||e===null){return{typeName:'UndefinedError',message:'Unknown: null or undefined exception',stack:'Unknown'};}
-if(typeof(e)=='string'){return{typeName:'StringError',message:e,stack:[e]};}
-var typeName;if(e.name){typeName=e.name;}else if(e.constructor){if(e.constructor.name){typeName=e.constructor.name;}else{typeName='AnonymousError';}}else{typeName='ErrorWithNoConstructor';}
-var msg=e.message?e.message:'Unknown';return{typeName:typeName,message:msg,stack:e.stack?e.stack:[msg]};}
-function stackTraceAsString(){return new Error().stack+'';}
-function stackTrace(){var stack=stackTraceAsString();stack=stack.split('\n');return stack.slice(2);}
-function getUsingPath(path,from_dict){var parts=path.split('.');var cur=from_dict;for(var part;parts.length&&(part=parts.shift());){if(!parts.length){return cur[part];}else if(part in cur){cur=cur[part];}else{return undefined;}}
-return undefined;}
-return{addSingletonGetter:addSingletonGetter,deepCopy:deepCopy,normalizeException:normalizeException,stackTrace:stackTrace,stackTraceAsString:stackTraceAsString,getUsingPath:getUsingPath};});'use strict';tr.exportTo('tr.b',function(){var recordRAFStacks=false;var pendingPreAFs=[];var pendingRAFs=[];var pendingIdleCallbacks=[];var currentRAFDispatchList=undefined;var rafScheduled=false;function scheduleRAF(){if(rafScheduled)
-return;rafScheduled=true;if(tr.isHeadless){Promise.resolve().then(function(){processRequests(0);},function(e){console.log(e.stack);throw e;});}else{if(window.requestAnimationFrame){window.requestAnimationFrame(processRequests);}else{var delta=Date.now()-window.performance.now();window.webkitRequestAnimationFrame(function(domTimeStamp){processRequests(domTimeStamp-delta);});}}}
-function onAnimationFrameError(e,opt_stack){console.log(e.stack);if(tr.isHeadless)
-throw e;if(opt_stack)
-console.log(opt_stack);if(e.message)
-console.error(e.message,e.stack);else
-console.error(e);}
-function runTask(task,frameBeginTime){try{task.callback.call(task.context,frameBeginTime);}catch(e){tr.b.onAnimationFrameError(e,task.stack);}}
-function processRequests(frameBeginTime){var rafCompletionDeadline=frameBeginTime+10;rafScheduled=false;var currentPreAFs=pendingPreAFs;currentRAFDispatchList=pendingRAFs;pendingPreAFs=[];pendingRAFs=[];var hasRAFTasks=currentPreAFs.length||currentRAFDispatchList.length;for(var i=0;i<currentPreAFs.length;i++)
-runTask(currentPreAFs[i],frameBeginTime);while(currentRAFDispatchList.length>0)
-runTask(currentRAFDispatchList.shift(),frameBeginTime);currentRAFDispatchList=undefined;if(!hasRAFTasks){while(pendingIdleCallbacks.length>0){runTask(pendingIdleCallbacks.shift());if(tr.isHeadless||window.performance.now()>=rafCompletionDeadline)
-break;}}
-if(pendingIdleCallbacks.length>0)
-scheduleRAF();}
-function getStack_(){if(!recordRAFStacks)
-return'';var stackLines=tr.b.stackTrace();stackLines.shift();return stackLines.join('\n');}
-function requestPreAnimationFrame(callback,opt_this){pendingPreAFs.push({callback:callback,context:opt_this||window,stack:getStack_()});scheduleRAF();}
-function requestAnimationFrameInThisFrameIfPossible(callback,opt_this){if(!currentRAFDispatchList){requestAnimationFrame(callback,opt_this);return;}
-currentRAFDispatchList.push({callback:callback,context:opt_this||window,stack:getStack_()});return;}
-function requestAnimationFrame(callback,opt_this){pendingRAFs.push({callback:callback,context:opt_this||window,stack:getStack_()});scheduleRAF();}
-function requestIdleCallback(callback,opt_this){pendingIdleCallbacks.push({callback:callback,context:opt_this||window,stack:getStack_()});scheduleRAF();}
-function forcePendingRAFTasksToRun(frameBeginTime){if(!rafScheduled)
-return;processRequests(frameBeginTime);}
-return{onAnimationFrameError:onAnimationFrameError,requestPreAnimationFrame:requestPreAnimationFrame,requestAnimationFrame:requestAnimationFrame,requestAnimationFrameInThisFrameIfPossible:requestAnimationFrameInThisFrameIfPossible,requestIdleCallback:requestIdleCallback,forcePendingRAFTasksToRun:forcePendingRAFTasksToRun};});'use strict';tr.exportTo('tr.b',function(){function Task(runCb,thisArg){if(runCb!==undefined&&thisArg===undefined)
-throw new Error('Almost certainly, you meant to pass a thisArg.');this.runCb_=runCb;this.thisArg_=thisArg;this.afterTask_=undefined;this.subTasks_=[];}
-Task.prototype={subTask:function(cb,thisArg){if(cb instanceof Task)
-this.subTasks_.push(cb);else
-this.subTasks_.push(new Task(cb,thisArg));return this.subTasks_[this.subTasks_.length-1];},run:function(){if(this.runCb_!==undefined)
-this.runCb_.call(this.thisArg_,this);var subTasks=this.subTasks_;this.subTasks_=undefined;if(!subTasks.length)
-return this.afterTask_;for(var i=1;i<subTasks.length;i++)
-subTasks[i-1].afterTask_=subTasks[i];subTasks[subTasks.length-1].afterTask_=this.afterTask_;return subTasks[0];},after:function(cb,thisArg){if(this.afterTask_)
-throw new Error('Has an after task already');if(cb instanceof Task)
-this.afterTask_=cb;else
-this.afterTask_=new Task(cb,thisArg);return this.afterTask_;},enqueue:function(cb,thisArg){var lastTask=this;while(lastTask.afterTask_)
-lastTask=lastTask.afterTask_;return lastTask.after(cb,thisArg);}};Task.RunSynchronously=function(task){var curTask=task;while(curTask)
-curTask=curTask.run();}
-Task.RunWhenIdle=function(task){return new Promise(function(resolve,reject){var curTask=task;function runAnother(){try{curTask=curTask.run();}catch(e){reject(e);console.error(e.stack);return;}
-if(curTask){tr.b.requestIdleCallback(runAnother);return;}
-resolve();}
-tr.b.requestIdleCallback(runAnother);});}
-return{Task:Task};});'use strict';tr.exportTo('tr.b',function(){function _iterateElementDeeplyImpl(element,cb,thisArg,includeElement){if(includeElement){if(cb.call(thisArg,element))
-return true;}
-if(element.shadowRoot){if(_iterateElementDeeplyImpl(element.shadowRoot,cb,thisArg,false))
-return true;}
-for(var i=0;i<element.children.length;i++){if(_iterateElementDeeplyImpl(element.children[i],cb,thisArg,true))
-return true;}}
-function iterateElementDeeply(element,cb,thisArg){_iterateElementDeeplyImpl(element,cb,thisArg,false);}
-function findDeepElementMatchingPredicate(element,predicate){var foundElement=undefined;function matches(element){var match=predicate(element);if(!match)
-return false;foundElement=element;return true;}
-iterateElementDeeply(element,matches);return foundElement;}
-function findDeepElementsMatchingPredicate(element,predicate){var foundElements=[];function matches(element){var match=predicate(element);if(match){foundElements.push(element);}
-return false;}
-iterateElementDeeply(element,matches);return foundElements;}
-function findDeepElementMatching(element,selector){return findDeepElementMatchingPredicate(element,function(element){return element.matches(selector);});}
-function findDeepElementsMatching(element,selector){return findDeepElementsMatchingPredicate(element,function(element){return element.matches(selector);});}
-function findDeepElementWithTextContent(element,re){return findDeepElementMatchingPredicate(element,function(element){if(element.children.length!==0)
-return false;return re.test(element.textContent);});}
-return{iterateElementDeeply:iterateElementDeeply,findDeepElementMatching:findDeepElementMatching,findDeepElementsMatching:findDeepElementsMatching,findDeepElementMatchingPredicate:findDeepElementMatchingPredicate,findDeepElementsMatchingPredicate:findDeepElementsMatchingPredicate,findDeepElementWithTextContent:findDeepElementWithTextContent};});'use strict';tr.exportTo('tr.b.u',function(){var msDisplayMode={scale:1e-3,suffix:'ms',roundedLess:function(a,b){return Math.round(a*1000)<Math.round(b*1000);},format:function(ts){return new Number(ts).toLocaleString(undefined,{minimumFractionDigits:3})+' ms';}};var nsDisplayMode={scale:1e-9,suffix:'ns',roundedLess:function(a,b){return Math.round(a*1000000)<Math.round(b*1000000);},format:function(ts){return new Number(ts*1000000).toLocaleString(undefined,{maximumFractionDigits:0})+' ns';}};var TimeDisplayModes={ns:nsDisplayMode,ms:msDisplayMode};return{TimeDisplayModes:TimeDisplayModes};});'use strict';tr.exportTo('tr.b.u',function(){var TimeDisplayModes=tr.b.u.TimeDisplayModes;function max(a,b){if(a===undefined)
-return b;if(b===undefined)
-return a;return a.scale>b.scale?a:b;}
-var Units={reset:function(){this.currentTimeDisplayMode=TimeDisplayModes.ms;},timestampFromUs:function(us){return us/1000;},maybeTimestampFromUs:function(us){return us===undefined?undefined:us/1000;},get currentTimeDisplayMode(){return this.currentTimeDisplayMode_;},set currentTimeDisplayMode(value){if(this.currentTimeDisplayMode_==value)
-return;this.currentTimeDisplayMode_=value;this.dispatchEvent(new tr.b.Event('display-mode-changed'));},didPreferredTimeDisplayUnitChange:function(){var largest=undefined;var els=tr.b.findDeepElementsMatching(document.body,'tr-ui-u-preferred-display-unit');els.forEach(function(el){largest=max(largest,el.preferredTimeDisplayMode);});this.currentDisplayUnit=largest===undefined?TimeDisplayModes.ms:largest;},unitsByJSONName:{},fromJSON:function(object){var u=this.unitsByJSONName[object];if(u){return u;}
-throw new Error('Unrecognized unit');}};tr.b.EventTarget.decorate(Units);Units.reset();Units.timeDurationInMs={asJSON:function(){return'ms';},format:function(value){return Units.currentTimeDisplayMode_.format(value);}};Units.unitsByJSONName['ms']=Units.timeDurationInMs;Units.timeStampInMs={asJSON:function(){return'tsMs';},format:function(value){return Units.currentTimeDisplayMode_.format(value);}};Units.unitsByJSONName['tsMs']=Units.timeStampInMs;Units.normalizedPercentage={asJSON:function(){return'n%';},format:function(value){var tmp=new Number(Math.round(value*100000)/1000);return tmp.toLocaleString(undefined,{minimumFractionDigits:3})+'%';}};Units.unitsByJSONName['n%']=Units.normalizedPercentage;var SIZE_UNIT_PREFIXES=['','Ki','Mi','Gi','Ti'];Units.sizeInBytes={asJSON:function(){return'sizeInBytes';},format:function(value){var signPrefix='';if(value<0){signPrefix='-';value=-value;}
-var i=0;while(value>=1024&&i<SIZE_UNIT_PREFIXES.length-1){value/=1024;i++;}
-return signPrefix+value.toFixed(1)+' '+SIZE_UNIT_PREFIXES[i]+'B';}};Units.unitsByJSONName['sizeInBytes']=Units.sizeInBytes;Units.energyInJoules={asJSON:function(){return'J';},format:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3})+' J';}};Units.unitsByJSONName['J']=Units.energyInJoules;Units.powerInWatts={asJSON:function(){return'W';},format:function(value){return(value*1000.0).toLocaleString(undefined,{minimumFractionDigits:3})+' mW';}};Units.unitsByJSONName['W']=Units.powerInWatts;Units.unitlessNumber={asJSON:function(){return'unitless';},format:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}};Units.unitsByJSONName['unitless']=Units.unitlessNumber;return{Units:Units};});'use strict';tr.exportTo('tr.c',function(){function Auditor(model){this.model_=model;}
-Auditor.prototype={__proto__:Object.prototype,get model(){return this.model_;},runAnnotate:function(){},runAudit:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Auditor;tr.b.decorateExtensionRegistry(Auditor,options);return{Auditor:Auditor};});'use strict';tr.exportTo('tr.c',function(){function makeCaseInsensitiveRegex(pattern){pattern=pattern.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');return new RegExp(pattern,'i');}
-function Filter(){}
-Filter.prototype={__proto__:Object.prototype,matchCounter:function(counter){return true;},matchCpu:function(cpu){return true;},matchProcess:function(process){return true;},matchSlice:function(slice){return true;},matchThread:function(thread){return true;}};function TitleOrCategoryFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);if(!text.length)
-throw new Error('Filter text is empty.');}
-TitleOrCategoryFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){if(slice.title===undefined&&slice.category===undefined)
-return false;return this.regex_.test(slice.title)||(!!slice.category&&this.regex_.test(slice.category));}};function ExactTitleFilter(text){Filter.call(this);this.text_=text;if(!text.length)
-throw new Error('Filter text is empty.');}
-ExactTitleFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){return slice.title===this.text_;}};function FullTextFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);this.titleOrCategoryFilter_=new TitleOrCategoryFilter(text);}
-FullTextFilter.prototype={__proto__:Filter.prototype,matchObject_:function(obj){for(var key in obj){if(!obj.hasOwnProperty(key))
-continue;if(this.regex_.test(key))
-return true;if(this.regex_.test(obj[key]))
-return true;}
-return false;},matchSlice:function(slice){if(this.titleOrCategoryFilter_.matchSlice(slice))
-return true;return this.matchObject_(slice.args);}};return{Filter:Filter,TitleOrCategoryFilter:TitleOrCategoryFilter,ExactTitleFilter:ExactTitleFilter,FullTextFilter:FullTextFilter};});'use strict';tr.exportTo('tr.b.u',function(){function Scalar(value,unit){this.value=value;this.unit=unit;};Scalar.prototype={toString:function(){return this.unit.format(this.value);}};return{Scalar:Scalar};});'use strict';tr.exportTo('tr.b.u',function(){function TimeStamp(timestamp){tr.b.u.Scalar.call(this,timestamp,tr.b.u.Units.timeStampInMs);};TimeStamp.prototype={__proto__:tr.b.u.Scalar.prototype,get timestamp(){return this.value;}};TimeStamp.format=function(timestamp){return tr.b.u.Units.timeStampInMs.format(timestamp);};return{TimeStamp:TimeStamp};});'use strict';tr.exportTo('tr.b',function(){function clamp01(value){return Math.max(0,Math.min(1,value));}
+return 1;return 0;};return{Range:Range};});'use strict';tr.exportTo('tr.b',function(){function identity(d){return d;}
+function Statistics(){}
+Statistics.divideIfPossibleOrZero=function(numerator,denominator){if(denominator===0)
+return 0;return numerator/denominator;};Statistics.sum=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=0;for(var i=0;i<ary.length;i++)
+ret+=func.call(opt_this,ary[i],i);return ret;};Statistics.mean=function(ary,opt_func,opt_this){return Statistics.sum(ary,opt_func,opt_this)/ary.length;};Statistics.weightedMean=function(ary,weightCallback,opt_valueCallback,opt_this){var valueCallback=opt_valueCallback||identity;var numerator=0;var denominator=0;for(var i=0;i<ary.length;i++){var value=valueCallback.call(opt_this,ary[i],i);if(value===undefined)
+continue;var weight=weightCallback.call(opt_this,ary[i],i,value);numerator+=weight*value;denominator+=weight;}
+if(denominator===0)
+return undefined;return numerator/denominator;};Statistics.variance=function(ary,opt_func,opt_this){var func=opt_func||identity;var mean=Statistics.mean(ary,func,opt_this);var sumOfSquaredDistances=Statistics.sum(ary,function(d,i){var v=func.call(this,d,i)-mean;return v*v;},opt_this);return sumOfSquaredDistances/(ary.length-1);};Statistics.stddev=function(ary,opt_func,opt_this){return Math.sqrt(Statistics.variance(ary,opt_func,opt_this));};Statistics.max=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=-Infinity;for(var i=0;i<ary.length;i++)
+ret=Math.max(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.min=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=Infinity;for(var i=0;i<ary.length;i++)
+ret=Math.min(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.range=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=new tr.b.Range();for(var i=0;i<ary.length;i++)
+ret.addValue(func.call(opt_this,ary[i],i));return ret;};Statistics.percentile=function(ary,percent,opt_func,opt_this){if(!(percent>=0&&percent<=1))
+throw new Error('percent must be [0,1]');var func=opt_func||identity;var tmp=new Array(ary.length);for(var i=0;i<ary.length;i++)
+tmp[i]=func.call(opt_this,ary[i],i);tmp.sort();var idx=Math.floor((ary.length-1)*percent);return tmp[idx];};Statistics.clamp=function(value,opt_low,opt_high){opt_low=opt_low||0.0;opt_high=opt_high||1.0;return Math.min(Math.max(value,opt_low),opt_high);};Statistics.normalizeSamples=function(samples){if(samples.length===0){return{normalized_samples:samples,scale:1.0};}
+samples=samples.slice().sort(function(a,b){return a-b;});var low=Math.min.apply(null,samples);var high=Math.max.apply(null,samples);var new_low=0.5/samples.length;var new_high=(samples.length-0.5)/samples.length;if(high-low===0.0){samples=Array.apply(null,new Array(samples.length)).map(function(){return 0.5;});return{normalized_samples:samples,scale:1.0};}
+var scale=(new_high-new_low)/(high-low);for(var i=0;i<samples.length;i++){samples[i]=(samples[i]-low)*scale+new_low;}
+return{normalized_samples:samples,scale:scale};};Statistics.discrepancy=function(samples,opt_location_count){if(samples.length===0)
+return 0.0;var max_local_discrepancy=0;var inv_sample_count=1.0/samples.length;var locations=[];var count_less=[];var count_less_equal=[];if(opt_location_count!==undefined){var sample_index=0;for(var i=0;i<opt_location_count;i++){var location=i/(opt_location_count-1);locations.push(location);while(sample_index<samples.length&&samples[sample_index]<location){sample_index+=1;}
+count_less.push(sample_index);while(sample_index<samples.length&&samples[sample_index]<=location){sample_index+=1;}
+count_less_equal.push(sample_index);}}else{if(samples[0]>0.0){locations.push(0.0);count_less.push(0);count_less_equal.push(0);}
+for(var i=0;i<samples.length;i++){locations.push(samples[i]);count_less.push(i);count_less_equal.push(i+1);}
+if(samples[-1]<1.0){locations.push(1.0);count_less.push(samples.length);count_less_equal.push(samples.length);}}
+for(var i=0;i<locations.length;i++){for(var j=i+1;j<locations.length;j++){var length=locations[j]-locations[i];var count_closed=count_less_equal[j]-count_less[i];var local_discrepancy_closed=Math.abs(count_closed*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_closed,max_local_discrepancy);var count_open=count_less[j]-count_less_equal[i];var local_discrepancy_open=Math.abs(count_open*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_open,max_local_discrepancy);}}
+return max_local_discrepancy;};Statistics.timestampsDiscrepancy=function(timestamps,opt_absolute,opt_location_count){if(timestamps.length===0)
+return 0.0;if(opt_absolute===undefined)
+opt_absolute=true;if(Array.isArray(timestamps[0])){var range_discrepancies=timestamps.map(function(r){return Statistics.timestampsDiscrepancy(r);});return Math.max.apply(null,range_discrepancies);}
+var s=Statistics.normalizeSamples(timestamps);var samples=s.normalized_samples;var sample_scale=s.scale;var discrepancy=Statistics.discrepancy(samples,opt_location_count);var inv_sample_count=1.0/samples.length;if(opt_absolute===true){discrepancy/=sample_scale;}else{discrepancy=Statistics.clamp((discrepancy-inv_sample_count)/(1.0-inv_sample_count));}
+return discrepancy;};Statistics.durationsDiscrepancy=function(durations,opt_absolute,opt_location_count){if(durations.length===0)
+return 0.0;var timestamps=durations.reduce(function(prev,curr,index,array){prev.push(prev[prev.length-1]+curr);return prev;},[0]);return Statistics.timestampsDiscrepancy(timestamps,opt_absolute,opt_location_count);};Statistics.uniformlySampleStream=function(samples,streamLength,newElement,numSamples){if(streamLength<=numSamples){if(samples.length>=streamLength)
+samples[streamLength-1]=newElement;else
+samples.push(newElement);return;}
+var probToKeep=numSamples/streamLength;if(Math.random()>probToKeep)
+return;var index=Math.floor(Math.random()*numSamples);samples[index]=newElement;};Statistics.mergeSampledStreams=function(samplesA,streamLengthA,samplesB,streamLengthB,numSamples){if(streamLengthB<numSamples){var nbElements=Math.min(streamLengthB,samplesB.length);for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(samplesA,streamLengthA+i+1,samplesB[i],numSamples);}
+return;}
+if(streamLengthA<numSamples){var nbElements=Math.min(streamLengthA,samplesA.length);var tempSamples=samplesB.slice();for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(tempSamples,streamLengthB+i+1,samplesA[i],numSamples);}
+for(var i=0;i<tempSamples.length;++i){samplesA[i]=tempSamples[i];}
+return;}
+var nbElements=Math.min(numSamples,samplesB.length);var probOfSwapping=streamLengthB/(streamLengthA+streamLengthB);for(var i=0;i<nbElements;++i){if(Math.random()<probOfSwapping){samplesA[i]=samplesB[i];}}};return{Statistics:Statistics};});'use strict';tr.exportTo('tr.c',function(){function Auditor(model){this.model_=model;}
+Auditor.prototype={__proto__:Object.prototype,get model(){return this.model_;},runAnnotate:function(){},installUserFriendlyCategoryDriverIfNeeded:function(){},runAudit:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Auditor;tr.b.decorateExtensionRegistry(Auditor,options);return{Auditor:Auditor};});'use strict';tr.exportTo('tr.b',function(){function clamp01(value){return Math.max(0,Math.min(1,value));}
 function Color(opt_r,opt_g,opt_b,opt_a){this.r=Math.floor(opt_r)||0;this.g=Math.floor(opt_g)||0;this.b=Math.floor(opt_b)||0;this.a=opt_a;}
 Color.fromString=function(str){var tmp;var values;if(str.substr(0,4)=='rgb('){tmp=str.substr(4,str.length-5);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!=3)
 throw new Error('Malformatted rgb-expression');return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]));}else if(str.substr(0,5)=='rgba('){tmp=str.substr(5,str.length-6);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!=4)
@@ -3025,7 +3115,7 @@
 h/=6;}
 return{h:h,s:s,l:l,a:this.a};},toStringWithAlphaOverride:function(alpha){return'rgba('+
 this.r+','+this.g+','+
-this.b+','+alpha+')';}};return{Color:Color};});'use strict';tr.exportTo('tr.b',function(){var generalPurposeColors=[new tr.b.Color(122,98,135),new tr.b.Color(150,83,105),new tr.b.Color(44,56,189),new tr.b.Color(99,86,147),new tr.b.Color(104,129,107),new tr.b.Color(130,178,55),new tr.b.Color(87,109,147),new tr.b.Color(111,145,88),new tr.b.Color(81,152,131),new tr.b.Color(142,91,111),new tr.b.Color(81,163,70),new tr.b.Color(148,94,86),new tr.b.Color(144,89,118),new tr.b.Color(83,150,97),new tr.b.Color(105,94,139),new tr.b.Color(89,144,122),new tr.b.Color(105,119,128),new tr.b.Color(96,128,137),new tr.b.Color(145,88,145),new tr.b.Color(88,145,144),new tr.b.Color(90,100,143),new tr.b.Color(121,97,136),new tr.b.Color(111,160,73),new tr.b.Color(112,91,142),new tr.b.Color(86,147,86),new tr.b.Color(63,100,170),new tr.b.Color(81,152,107),new tr.b.Color(60,164,173),new tr.b.Color(143,72,161),new tr.b.Color(159,74,86)];var reservedColorsByName={thread_state_iowait:new tr.b.Color(182,125,143),thread_state_running:new tr.b.Color(126,200,148),thread_state_runnable:new tr.b.Color(133,160,210),thread_state_sleeping:new tr.b.Color(240,240,240),thread_state_unknown:new tr.b.Color(199,155,125),light_memory_dump:new tr.b.Color(0,0,180),detailed_memory_dump:new tr.b.Color(180,0,180),generic_work:new tr.b.Color(125,125,125),good:new tr.b.Color(0,125,0),bad:new tr.b.Color(180,125,0),terrible:new tr.b.Color(180,0,0),black:new tr.b.Color(0,0,0),rail_response:new tr.b.Color(67,135,253),rail_animate:new tr.b.Color(244,74,63),rail_idle:new tr.b.Color(238,142,0),rail_load:new tr.b.Color(13,168,97),used_memory_column:new tr.b.Color(0,0,255),older_used_memory_column:new tr.b.Color(153,204,255),tracing_memory_column:new tr.b.Color(153,153,153),cq_build_running:new tr.b.Color(255,255,119),cq_build_passed:new tr.b.Color(153,238,102),cq_build_failed:new tr.b.Color(238,136,136),cq_build_abandoned:new tr.b.Color(187,187,187),cq_build_attempt_runnig:new tr.b.Color(222,222,75),cq_build_attempt_passed:new tr.b.Color(103,218,35),cq_build_attempt_failed:new tr.b.Color(197,81,81)};var numGeneralPurposeColorIds=generalPurposeColors.length;var numReservedColorIds=tr.b.dictionaryLength(reservedColorsByName);var numColorsPerVariant=numGeneralPurposeColorIds+numReservedColorIds;function ColorScheme(){}
+this.b+','+alpha+')';}};return{Color:Color};});'use strict';tr.exportTo('tr.b',function(){var generalPurposeColors=[new tr.b.Color(122,98,135),new tr.b.Color(150,83,105),new tr.b.Color(44,56,189),new tr.b.Color(99,86,147),new tr.b.Color(104,129,107),new tr.b.Color(130,178,55),new tr.b.Color(87,109,147),new tr.b.Color(111,145,88),new tr.b.Color(81,152,131),new tr.b.Color(142,91,111),new tr.b.Color(81,163,70),new tr.b.Color(148,94,86),new tr.b.Color(144,89,118),new tr.b.Color(83,150,97),new tr.b.Color(105,94,139),new tr.b.Color(89,144,122),new tr.b.Color(105,119,128),new tr.b.Color(96,128,137),new tr.b.Color(145,88,145),new tr.b.Color(88,145,144),new tr.b.Color(90,100,143),new tr.b.Color(121,97,136),new tr.b.Color(111,160,73),new tr.b.Color(112,91,142),new tr.b.Color(86,147,86),new tr.b.Color(63,100,170),new tr.b.Color(81,152,107),new tr.b.Color(60,164,173),new tr.b.Color(143,72,161),new tr.b.Color(159,74,86)];var reservedColorsByName={thread_state_uninterruptible:new tr.b.Color(182,125,143),thread_state_iowait:new tr.b.Color(255,140,0),thread_state_running:new tr.b.Color(126,200,148),thread_state_runnable:new tr.b.Color(133,160,210),thread_state_sleeping:new tr.b.Color(240,240,240),thread_state_unknown:new tr.b.Color(199,155,125),light_memory_dump:new tr.b.Color(0,0,180),detailed_memory_dump:new tr.b.Color(180,0,180),generic_work:new tr.b.Color(125,125,125),good:new tr.b.Color(0,125,0),bad:new tr.b.Color(180,125,0),terrible:new tr.b.Color(180,0,0),black:new tr.b.Color(0,0,0),rail_response:new tr.b.Color(67,135,253),rail_animation:new tr.b.Color(244,74,63),rail_idle:new tr.b.Color(238,142,0),rail_load:new tr.b.Color(13,168,97),used_memory_column:new tr.b.Color(0,0,255),older_used_memory_column:new tr.b.Color(153,204,255),tracing_memory_column:new tr.b.Color(153,153,153),heap_dump_stack_frame:new tr.b.Color(128,128,128),heap_dump_object_type:new tr.b.Color(0,0,255),cq_build_running:new tr.b.Color(255,255,119),cq_build_passed:new tr.b.Color(153,238,102),cq_build_failed:new tr.b.Color(238,136,136),cq_build_abandoned:new tr.b.Color(187,187,187),cq_build_attempt_runnig:new tr.b.Color(222,222,75),cq_build_attempt_passed:new tr.b.Color(103,218,35),cq_build_attempt_failed:new tr.b.Color(197,81,81)};var numGeneralPurposeColorIds=generalPurposeColors.length;var numReservedColorIds=tr.b.dictionaryLength(reservedColorsByName);var numColorsPerVariant=numGeneralPurposeColorIds+numReservedColorIds;function ColorScheme(){}
 var paletteBase=[];paletteBase.push.apply(paletteBase,generalPurposeColors);paletteBase.push.apply(paletteBase,tr.b.dictionaryValues(reservedColorsByName));ColorScheme.colors=[];ColorScheme.properties={};ColorScheme.properties={numColorsPerVariant:numColorsPerVariant};function pushVariant(func){var variantColors=paletteBase.map(func);ColorScheme.colors.push.apply(ColorScheme.colors,variantColors);}
 pushVariant(function(c){return c;});ColorScheme.properties.brightenedOffsets=[];ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.3,0.9);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.48,0.9);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.65,0.9);});ColorScheme.properties.dimmedOffsets=[];ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate();});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.5);});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.3);});ColorScheme.colorsAsStrings=ColorScheme.colors.map(function(c){return c.toString();});var reservedColorNameToIdMap=(function(){var m={};var i=generalPurposeColors.length;tr.b.iterItems(reservedColorsByName,function(key,value){m[key]=i++;});return m;})();ColorScheme.getColorIdForReservedName=function(name){var id=reservedColorNameToIdMap[name];if(id===undefined)
 throw new Error('Unrecognized color ')+name;return id;};ColorScheme.getColorForReservedNameAsString=function(reservedName){var id=ColorScheme.getColorIdForReservedName(reservedName);return ColorScheme.colorsAsStrings[id];};ColorScheme.getStringHash=function(name){var hash=0;for(var i=0;i<name.length;++i)
@@ -3041,13 +3131,15 @@
 EventRegistry.addEventListener('registry-changed',function(){eventsByTypeName=undefined;});function convertCamelCaseToTitleCase(name){var result=name.replace(/[A-Z]/g,' $&');result=result.charAt(0).toUpperCase()+result.slice(1);return result;}
 EventRegistry.getUserFriendlySingularName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.name;return convertCamelCaseToTitleCase(str);};EventRegistry.getUserFriendlyPluralName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.pluralName;return convertCamelCaseToTitleCase(str);};return{EventRegistry:EventRegistry};});'use strict';tr.exportTo('tr.model',function(){var EventRegistry=tr.model.EventRegistry;var RequestSelectionChangeEvent=tr.b.Event.bind(undefined,'requestSelectionChange',true,false);function EventSet(opt_events){this.bounds_dirty_=true;this.bounds_=new tr.b.Range();this.length_=0;this.guid_=tr.b.GUID.allocate();this.pushed_guids_={};if(opt_events){if(opt_events instanceof Array){for(var i=0;i<opt_events.length;i++)
 this.push(opt_events[i]);}else if(opt_events instanceof EventSet){this.addEventSet(opt_events);}else{this.push(opt_events);}}}
-EventSet.prototype={__proto__:Object.prototype,get bounds(){if(this.bounds_dirty_){this.bounds_.reset();for(var i=0;i<this.length_;i++)
-this[i].addBoundsToRange(this.bounds_);this.bounds_dirty_=false;}
-return this.bounds_;},get duration(){if(this.bounds_.isEmpty)
+EventSet.prototype={__proto__:Object.prototype,get bounds(){if(this.bounds_dirty_)
+this.resolveBounds_();return this.bounds_;},get duration(){if(this.bounds_.isEmpty)
 return 0;return this.bounds_.max-this.bounds_.min;},get length(){return this.length_;},get guid(){return this.guid_;},clear:function(){for(var i=0;i<this.length_;++i)
-delete this[i];this.length_=0;this.bounds_dirty_=true;},push:function(event){if(event.guid==undefined)
+delete this[i];this.length_=0;this.bounds_dirty_=true;},resolveBounds_:function(){this.bounds_.reset();for(var i=0;i<this.length_;i++)
+this[i].addBoundsToRange(this.bounds_);this.bounds_dirty_=false;},push:function(event){if(event.guid==undefined)
 throw new Error('Event must have a GUID');if(this.contains(event))
-return event;this.pushed_guids_[event.guid]=true;this[this.length_++]=event;this.bounds_dirty_=true;return event;},contains:function(event){return this.pushed_guids_[event.guid];},addEventSet:function(eventSet){for(var i=0;i<eventSet.length;i++)
+return event;this.pushed_guids_[event.guid]=true;this[this.length_++]=event;this.bounds_dirty_=true;return event;},contains:function(event){return this.pushed_guids_[event.guid];},indexOf:function(event){for(var i=0;i<this.length;i++){if(this[i].guid===event.guid)
+return i;}
+return-1;},addEventSet:function(eventSet){for(var i=0;i<eventSet.length;i++)
 this.push(eventSet[i]);},subEventSet:function(index,count){count=count||1;var eventSet=new EventSet();eventSet.bounds_dirty_=true;if(index<0||index+count>this.length_)
 throw new Error('Index out of bounds');for(var i=index;i<index+count;i++)
 eventSet.push(this[i]);return eventSet;},intersectionIsEmpty:function(otherEventSet){return!this.some(function(event){return otherEventSet.contains(event);});},equals:function(that){if(this.length!==that.length)
@@ -3074,163 +3166,32 @@
 if(!fn.call(opt_this,this[i],i))
 return false;return true;},some:function(fn,opt_this){for(var i=0;i<this.length;i++)
 if(fn.call(opt_this,this[i],i))
-return true;return false;},asDict:function(){var stable_ids=[];this.forEach(function(event){stable_ids.push(event.stableId);});return{'events':stable_ids};}};return{EventSet:EventSet,RequestSelectionChangeEvent:RequestSelectionChangeEvent};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var SelectionState={NONE:0,SELECTED:ColorScheme.properties.brightenedOffsets[0],HIGHLIGHTED:ColorScheme.properties.brightenedOffsets[1],DIMMED:ColorScheme.properties.dimmedOffsets[0],BRIGHTENED0:ColorScheme.properties.brightenedOffsets[0],BRIGHTENED1:ColorScheme.properties.brightenedOffsets[1],BRIGHTENED2:ColorScheme.properties.brightenedOffsets[2],DIMMED0:ColorScheme.properties.dimmedOffsets[0],DIMMED1:ColorScheme.properties.dimmedOffsets[1],DIMMED2:ColorScheme.properties.dimmedOffsets[2]};var brighteningLevels=[SelectionState.NONE,SelectionState.BRIGHTENED0,SelectionState.BRIGHTENED1,SelectionState.BRIGHTENED2];SelectionState.getFromBrighteningLevel=function(level){return brighteningLevels[level];}
+return true;return false;},asDict:function(){var stable_ids=[];this.forEach(function(event){stable_ids.push(event.stableId);});return{'events':stable_ids};}};EventSet.IMMUTABLE_EMPTY_SET=(function(){var s=new EventSet();s.resolveBounds_();s.push=function(){throw new Error('Cannot push to an immutable event set');};s.addEventSet=function(){throw new Error('Cannot add to an immutable event set');};Object.freeze(s);return s;})();return{EventSet:EventSet,RequestSelectionChangeEvent:RequestSelectionChangeEvent};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var SelectionState={NONE:0,SELECTED:ColorScheme.properties.brightenedOffsets[0],HIGHLIGHTED:ColorScheme.properties.brightenedOffsets[1],DIMMED:ColorScheme.properties.dimmedOffsets[0],BRIGHTENED0:ColorScheme.properties.brightenedOffsets[0],BRIGHTENED1:ColorScheme.properties.brightenedOffsets[1],BRIGHTENED2:ColorScheme.properties.brightenedOffsets[2],DIMMED0:ColorScheme.properties.dimmedOffsets[0],DIMMED1:ColorScheme.properties.dimmedOffsets[1],DIMMED2:ColorScheme.properties.dimmedOffsets[2]};var brighteningLevels=[SelectionState.NONE,SelectionState.BRIGHTENED0,SelectionState.BRIGHTENED1,SelectionState.BRIGHTENED2];SelectionState.getFromBrighteningLevel=function(level){return brighteningLevels[level];}
 var dimmingLevels=[SelectionState.DIMMED0,SelectionState.DIMMED1,SelectionState.DIMMED2];SelectionState.getFromDimmingLevel=function(level){return dimmingLevels[level];}
 return{SelectionState:SelectionState};});'use strict';tr.exportTo('tr.model',function(){var SelectionState=tr.model.SelectionState;function SelectableItem(modelItem){this.modelItem_=modelItem;}
 SelectableItem.prototype={get modelItem(){return this.modelItem_;},get selected(){return this.selectionState===SelectionState.SELECTED;},addToSelection:function(selection){var modelItem=this.modelItem_;if(!modelItem)
 return;selection.push(modelItem);},addToTrackMap:function(eventToTrackMap,track){var modelItem=this.modelItem_;if(!modelItem)
-return;eventToTrackMap.addEvent(modelItem,track);}};return{SelectableItem:SelectableItem};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;function Event(){SelectableItem.call(this,this);this.guid_=tr.b.GUID.allocate();this.selectionState=SelectionState.NONE;this.associatedAlerts=new tr.model.EventSet();this.info=undefined;}
-Event.prototype={__proto__:SelectableItem.prototype,get guid(){return this.guid_;},get stableId(){return undefined;},addBoundsToRange:function(range){throw new Error('Not implemented');}};return{Event:Event};});'use strict';tr.exportTo('tr.model',function(){function TimedEvent(start){tr.model.Event.call(this);this.start=start;this.duration=0;this.cpuStart=undefined;this.cpuDuration=undefined;}
-TimedEvent.prototype={__proto__:tr.model.Event.prototype,get end(){return this.start+this.duration;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);},bounds:function(that,precisionUnit){if(precisionUnit===undefined){precisionUnit=tr.b.u.TimeDisplayModes.ms;}
-var startsBefore=precisionUnit.roundedLess(that.start,this.start);var endsAfter=precisionUnit.roundedLess(this.end,that.end);return!startsBefore&&!endsAfter;}};return{TimedEvent:TimedEvent};});'use strict';tr.exportTo('tr.model',function(){function Alert(info,start,opt_associatedEvents,opt_args){tr.model.TimedEvent.call(this,start);this.info=info;this.args=opt_args||{};this.associatedEvents=new tr.model.EventSet(opt_associatedEvents);this.associatedEvents.forEach(function(event){event.associatedAlerts.push(this);},this);}
+return;eventToTrackMap.addEvent(modelItem,track);}};return{SelectableItem:SelectableItem};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;var IMMUTABLE_EMPTY_SET=tr.model.EventSet.IMMUTABLE_EMPTY_SET;function Event(){SelectableItem.call(this,this);this.guid_=tr.b.GUID.allocate();this.selectionState=SelectionState.NONE;this.info=undefined;}
+Event.prototype={__proto__:SelectableItem.prototype,get guid(){return this.guid_;},get stableId(){return undefined;},associatedAlerts:IMMUTABLE_EMPTY_SET,addAssociatedAlert:function(alert){if(this.associatedAlerts===IMMUTABLE_EMPTY_SET)
+this.associatedAlerts=new tr.model.EventSet();this.associatedAlerts.push(alert);},addBoundsToRange:function(range){throw new Error('Not implemented');}};return{Event:Event};});'use strict';tr.exportTo('tr.v',function(){var msDisplayMode={scale:1e-3,suffix:'ms',roundedLess:function(a,b){return Math.round(a*1000)<Math.round(b*1000);},format:function(ts){return new Number(ts).toLocaleString(undefined,{minimumFractionDigits:3})+' ms';}};var nsDisplayMode={scale:1e-9,suffix:'ns',roundedLess:function(a,b){return Math.round(a*1000000)<Math.round(b*1000000);},format:function(ts){return new Number(ts*1000000).toLocaleString(undefined,{maximumFractionDigits:0})+' ns';}};var TimeDisplayModes={ns:nsDisplayMode,ms:msDisplayMode};return{TimeDisplayModes:TimeDisplayModes};});'use strict';tr.exportTo('tr.model',function(){function TimedEvent(start){tr.model.Event.call(this);this.start=start;this.duration=0;this.cpuStart=undefined;this.cpuDuration=undefined;}
+TimedEvent.prototype={__proto__:tr.model.Event.prototype,get end(){return this.start+this.duration;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);},bounds:function(that,opt_precisionUnit){if(opt_precisionUnit===undefined)
+opt_precisionUnit=tr.v.TimeDisplayModes.ms;var startsBefore=opt_precisionUnit.roundedLess(that.start,this.start);var endsAfter=opt_precisionUnit.roundedLess(this.end,that.end);return!startsBefore&&!endsAfter;}};return{TimedEvent:TimedEvent};});'use strict';tr.exportTo('tr.v',function(){var TimeDisplayModes=tr.v.TimeDisplayModes;var BINARY_PREFIXES=['','Ki','Mi','Gi','Ti'];var PLUS_MINUS_SIGN=String.fromCharCode(177);function max(a,b){if(a===undefined)
+return b;if(b===undefined)
+return a;return a.scale>b.scale?a:b;}
+var ImprovementDirection={DONT_CARE:0,BIGGER_IS_BETTER:1,SMALLER_IS_BETTER:2};function Unit(unitName,jsonName,isDelta,improvementDirection,formatValue){this.unitName=unitName;this.jsonName=jsonName;this.isDelta=isDelta;this.improvementDirection=improvementDirection;this.formatValue_=formatValue;this.correspondingDeltaUnit=undefined;}
+Unit.prototype={asJSON:function(){return this.jsonName;},format:function(value){var formattedValue=this.formatValue_(value);if(!this.isDelta||value<0)
+return formattedValue;if(value===0)
+return PLUS_MINUS_SIGN+formattedValue;else
+return'+'+formattedValue;}};Unit.reset=function(){Unit.currentTimeDisplayMode=TimeDisplayModes.ms;};Unit.timestampFromUs=function(us){return us/1000;};Unit.maybeTimestampFromUs=function(us){return us===undefined?undefined:us/1000;};Object.defineProperty(Unit,'currentTimeDisplayMode',{get:function(){return Unit.currentTimeDisplayMode_;},set:function(value){if(Unit.currentTimeDisplayMode_===value)
+return;Unit.currentTimeDisplayMode_=value;Unit.dispatchEvent(new tr.b.Event('display-mode-changed'));}});Unit.didPreferredTimeDisplayUnitChange=function(){var largest=undefined;var els=tr.b.findDeepElementsMatching(document.body,'tr-v-ui-preferred-display-unit');els.forEach(function(el){largest=max(largest,el.preferredTimeDisplayMode);});Unit.currentDisplayUnit=largest===undefined?TimeDisplayModes.ms:largest;};Unit.byName={};Unit.byJSONName={};Unit.fromJSON=function(object){var u=Unit.byJSONName[object];if(u){return u;}
+throw new Error('Unrecognized unit');};Unit.define=function(params){tr.b.iterItems(ImprovementDirection,function(_,improvementDirection){var regularUnit=Unit.defineUnitVariant_(params,false,improvementDirection);var deltaUnit=Unit.defineUnitVariant_(params,true,improvementDirection);regularUnit.correspondingDeltaUnit=deltaUnit;deltaUnit.correspondingDeltaUnit=deltaUnit;});};Unit.defineUnitVariant_=function(params,isDelta,improvementDirection){var nameSuffix=isDelta?'Delta':'';switch(improvementDirection){case ImprovementDirection.DONT_CARE:break;case ImprovementDirection.BIGGER_IS_BETTER:nameSuffix+='_biggerIsBetter';break;case ImprovementDirection.SMALLER_IS_BETTER:nameSuffix+='_smallerIsBetter';break;default:throw new Error('Unknown improvement direction: '+improvementDirection);}
+var unitName=params.baseUnitName+nameSuffix;var jsonName=params.baseJsonName+nameSuffix;if(Unit.byName[unitName]!==undefined)
+throw new Error('Unit \''+unitName+'\' already exists');if(Unit.byJSONName[jsonName]!==undefined)
+throw new Error('JSON unit \''+jsonName+'\' alread exists');var unit=new Unit(unitName,jsonName,isDelta,improvementDirection,params.formatValue);Unit.byName[unitName]=unit;Unit.byJSONName[jsonName]=unit;return unit;};tr.b.EventTarget.decorate(Unit);Unit.reset();Unit.define({baseUnitName:'timeDurationInMs',baseJsonName:'ms',formatValue:function(value){return Unit.currentTimeDisplayMode_.format(value);}});Unit.define({baseUnitName:'timeStampInMs',baseJsonName:'tsMs',formatValue:function(value){return Unit.currentTimeDisplayMode_.format(value);}});Unit.define({baseUnitName:'normalizedPercentage',baseJsonName:'n%',formatValue:function(value){var tmp=new Number(Math.round(value*100000)/1000);return tmp.toLocaleString(undefined,{minimumFractionDigits:3})+'%';}});Unit.define({baseUnitName:'sizeInBytes',baseJsonName:'sizeInBytes',formatValue:function(value){var signPrefix='';if(value<0){signPrefix='-';value=-value;}
+var i=0;while(value>=1024&&i<BINARY_PREFIXES.length-1){value/=1024;i++;}
+return signPrefix+value.toFixed(1)+' '+BINARY_PREFIXES[i]+'B';}});Unit.define({baseUnitName:'energyInJoules',baseJsonName:'J',formatValue:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3})+' J';}});Unit.define({baseUnitName:'powerInWatts',baseJsonName:'W',formatValue:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3})+' W';}});Unit.define({baseUnitName:'unitlessNumber',baseJsonName:'unitless',formatValue:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}});return{ImprovementDirection:ImprovementDirection,Unit:Unit};});'use strict';tr.exportTo('tr.model',function(){function Alert(info,start,opt_associatedEvents,opt_args){tr.model.TimedEvent.call(this,start);this.info=info;this.args=opt_args||{};this.associatedEvents=new tr.model.EventSet(opt_associatedEvents);this.associatedEvents.forEach(function(event){event.addAssociatedAlert(this);},this);}
 Alert.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.info.title;},get colorId(){return this.info.colorId;},get userFriendlyName(){return'Alert '+this.title+' at '+
-tr.b.u.TimeStamp.format(this.start);}};tr.model.EventRegistry.register(Alert,{name:'alert',pluralName:'alerts',singleViewElementName:'tr-ui-a-alert-sub-view',multiViewElementName:'tr-ui-a-alert-sub-view'});return{Alert:Alert};});'use strict';tr.exportTo('tr.model',function(){function EventContainer(){this.guid_=tr.b.GUID.allocate();this.important=true;this.bounds_=new tr.b.Range();}
-EventContainer.prototype={get guid(){return this.guid_;},get stableId(){throw new Error('Not implemented');},get bounds(){return this.bounds_;},updateBounds:function(){throw new Error('Not implemented');},shiftTimestampsForward:function(amount){throw new Error('Not implemented');},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){throw new Error('Not implemented');},iterateAllChildEventContainers:function(callback,opt_this){throw new Error('Not implemented');},iterateAllEvents:function(callback,opt_this){this.iterateAllEventContainers(function(ec){ec.iterateAllEventsInThisContainer(function(eventType){return true;},callback,opt_this);});},iterateAllEventContainers:function(callback,opt_this){function visit(ec){callback.call(opt_this,ec);ec.iterateAllChildEventContainers(visit);}
-visit(this);}};return{EventContainer:EventContainer};});'use strict';tr.exportTo('tr.model',function(){var Event=tr.model.Event;var EventRegistry=tr.model.EventRegistry;function PowerSample(series,start,power){Event.call(this);this.series_=series;this.start_=start;this.power_=power;}
-PowerSample.prototype={__proto__:Event.prototype,get series(){return this.series_;},get start(){return this.start_;},set start(value){this.start_=value;},get power(){return this.power_;},set power(value){this.power_=value;},addBoundsToRange:function(range){range.addValue(this.start);}};EventRegistry.register(PowerSample,{name:'powerSample',pluralName:'powerSamples',singleViewElementName:'tr-ui-a-single-power-sample-sub-view',multiViewElementName:'tr-ui-a-multi-power-sample-sub-view'});return{PowerSample:PowerSample};});'use strict';tr.exportTo('tr.model',function(){var PowerSample=tr.model.PowerSample;function PowerSeries(device){tr.model.EventContainer.call(this);this.device_=device;this.samples_=[];}
-PowerSeries.prototype={__proto__:tr.model.EventContainer.prototype,get device(){return this.device_;},get samples(){return this.samples_;},get stableId(){return this.device_.stableId+'.PowerSeries';},addPowerSample:function(ts,val){var sample=new PowerSample(this,ts,val);this.samples_.push(sample);return sample;},getEnergyConsumed:function(start,end){var measurementRange=tr.b.Range.fromExplicitRange(start,end);var energyConsumed=0;for(var i=0;i<this.samples.length;i++){var sample=this.samples[i];var nextSample=this.samples[i+1];var sampleRange=new tr.b.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:Infinity);var timeIntersection=measurementRange.findIntersection(sampleRange);energyConsumed+=timeIntersection.duration/1000*sample.power;}
-return energyConsumed;},shiftTimestampsForward:function(amount){for(var i=0;i<this.samples_.length;++i)
-this.samples_[i].start+=amount;},updateBounds:function(){this.bounds.reset();if(this.samples_.length===0)
-return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,PowerSample))
-this.samples_.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){}};return{PowerSeries:PowerSeries};});'use strict';tr.exportTo('tr.model',function(){function Device(model){if(!model)
-throw new Error('Must provide a model.');tr.model.EventContainer.call(this);this.powerSeries_=undefined;this.vSyncTimestamps_=[];};Device.compare=function(x,y){return x.guid-y.guid;};Device.prototype={__proto__:tr.model.EventContainer.prototype,compareTo:function(that){return Device.compare(this,that);},get userFriendlyName(){return'Device';},get userFriendlyDetails(){return'Device';},get stableId(){return'Device';},getSettingsKey:function(){return'device';},get powerSeries(){return this.powerSeries_;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;},get vSyncTimestamps(){return this.vSyncTimestamps_;},set vSyncTimestamps(value){this.vSyncTimestamps_=value;},updateBounds:function(){this.bounds.reset();this.iterateAllChildEventContainers(function(child){child.updateBounds();this.bounds.addRange(child.bounds);},this);},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});for(var i=0;i<this.vSyncTimestamps_.length;i++)
-this.vSyncTimestamps_[i]+=amount;},addCategoriesToDict:function(categoriesDict){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){if(this.powerSeries_)
-callback.call(opt_this,this.powerSeries_);}};return{Device:Device};});'use strict';tr.exportTo('tr.model',function(){function FlowEvent(category,id,title,colorId,start,args,opt_duration){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.id=id;this.startSlice=undefined;this.endSlice=undefined;this.startStackFrame=undefined;this.endStackFrame=undefined;if(opt_duration!==undefined)
-this.duration=opt_duration;}
-FlowEvent.prototype={__proto__:tr.model.TimedEvent.prototype,get userFriendlyName(){return'Flow event named '+this.title+' at '+
-tr.b.u.TimeStamp.format(this.timestamp);}};tr.model.EventRegistry.register(FlowEvent,{name:'flowEvent',pluralName:'flowEvents',singleViewElementName:'tr-ui-a-single-flow-event-sub-view',multiViewElementName:'tr-ui-a-multi-flow-event-sub-view'});return{FlowEvent:FlowEvent};});'use strict';tr.exportTo('tr.b',function(){function identity(d){return d;}
-function Statistics(){}
-Statistics.divideIfPossibleOrZero=function(numerator,denominator){if(denominator===0)
-return 0;return numerator/denominator;}
-Statistics.sum=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=0;for(var i=0;i<ary.length;i++)
-ret+=func.call(opt_this,ary[i],i);return ret;};Statistics.mean=function(ary,opt_func,opt_this){return Statistics.sum(ary,opt_func,opt_this)/ary.length;};Statistics.variance=function(ary,opt_func,opt_this){var func=opt_func||identity;var mean=Statistics.mean(ary,func,opt_this);var sumOfSquaredDistances=Statistics.sum(ary,function(d,i){var v=func.call(this,d,i)-mean;return v*v;},opt_this);return sumOfSquaredDistances/(ary.length-1);};Statistics.stddev=function(ary,opt_func,opt_this){return Math.sqrt(Statistics.variance(ary,opt_func,opt_this));};Statistics.max=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=-Infinity;for(var i=0;i<ary.length;i++)
-ret=Math.max(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.min=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=Infinity;for(var i=0;i<ary.length;i++)
-ret=Math.min(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.range=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=new tr.b.Range();for(var i=0;i<ary.length;i++)
-ret.addValue(func.call(opt_this,ary[i],i));return ret;}
-Statistics.percentile=function(ary,percent,opt_func,opt_this){if(!(percent>=0&&percent<=1))
-throw new Error('percent must be [0,1]');var func=opt_func||identity;var tmp=new Array(ary.length);for(var i=0;i<ary.length;i++)
-tmp[i]=func.call(opt_this,ary[i],i);tmp.sort();var idx=Math.floor((ary.length-1)*percent);return tmp[idx];};Statistics.clamp=function(value,opt_low,opt_high){opt_low=opt_low||0.0;opt_high=opt_high||1.0;return Math.min(Math.max(value,opt_low),opt_high);}
-Statistics.normalizeSamples=function(samples){if(samples.length===0){return{normalized_samples:samples,scale:1.0};}
-samples=samples.slice().sort(function(a,b){return a-b;});var low=Math.min.apply(null,samples);var high=Math.max.apply(null,samples);var new_low=0.5/samples.length;var new_high=(samples.length-0.5)/samples.length;if(high-low===0.0){samples=Array.apply(null,new Array(samples.length)).map(function(){return 0.5;});return{normalized_samples:samples,scale:1.0};}
-var scale=(new_high-new_low)/(high-low);for(var i=0;i<samples.length;i++){samples[i]=(samples[i]-low)*scale+new_low;}
-return{normalized_samples:samples,scale:scale};}
-Statistics.discrepancy=function(samples,opt_location_count){if(samples.length===0)
-return 0.0;var max_local_discrepancy=0;var inv_sample_count=1.0/samples.length;var locations=[];var count_less=[];var count_less_equal=[];if(opt_location_count!==undefined){var sample_index=0;for(var i=0;i<opt_location_count;i++){var location=i/(opt_location_count-1);locations.push(location);while(sample_index<samples.length&&samples[sample_index]<location){sample_index+=1;}
-count_less.push(sample_index);while(sample_index<samples.length&&samples[sample_index]<=location){sample_index+=1;}
-count_less_equal.push(sample_index);}}else{if(samples[0]>0.0){locations.push(0.0);count_less.push(0);count_less_equal.push(0);}
-for(var i=0;i<samples.length;i++){locations.push(samples[i]);count_less.push(i);count_less_equal.push(i+1);}
-if(samples[-1]<1.0){locations.push(1.0);count_less.push(samples.length);count_less_equal.push(samples.length);}}
-for(var i=0;i<locations.length;i++){for(var j=i+1;j<locations.length;j++){var length=locations[j]-locations[i];var count_closed=count_less_equal[j]-count_less[i];var local_discrepancy_closed=Math.abs(count_closed*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_closed,max_local_discrepancy);var count_open=count_less[j]-count_less_equal[i];var local_discrepancy_open=Math.abs(count_open*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_open,max_local_discrepancy);}}
-return max_local_discrepancy;};Statistics.timestampsDiscrepancy=function(timestamps,opt_absolute,opt_location_count){if(timestamps.length===0)
-return 0.0;if(opt_absolute===undefined)
-opt_absolute=true;if(Array.isArray(timestamps[0])){var range_discrepancies=timestamps.map(function(r){return Statistics.timestampsDiscrepancy(r);});return Math.max.apply(null,range_discrepancies);}
-var s=Statistics.normalizeSamples(timestamps);var samples=s.normalized_samples;var sample_scale=s.scale;var discrepancy=Statistics.discrepancy(samples,opt_location_count);var inv_sample_count=1.0/samples.length;if(opt_absolute===true){discrepancy/=sample_scale;}else{discrepancy=Statistics.clamp((discrepancy-inv_sample_count)/(1.0-inv_sample_count));}
-return discrepancy;};Statistics.durationsDiscrepancy=function(durations,opt_absolute,opt_location_count){if(durations.length===0)
-return 0.0;var timestamps=durations.reduce(function(prev,curr,index,array){prev.push(prev[prev.length-1]+curr);return prev;},[0]);return Statistics.timestampsDiscrepancy(timestamps,opt_absolute,opt_location_count);};Statistics.uniformlySampleStream=function(samples,streamLength,newElement,numSamples){if(streamLength<=numSamples){if(samples.length>=streamLength)
-samples[streamLength-1]=newElement;else
-samples.push(newElement);return;}
-var probToKeep=numSamples/streamLength;if(Math.random()>probToKeep)
-return;var index=Math.floor(Math.random()*numSamples);samples[index]=newElement;};Statistics.mergeSampledStreams=function(samplesA,streamLengthA,samplesB,streamLengthB,numSamples){if(streamLengthB<numSamples){var nbElements=Math.min(streamLengthB,samplesB.length);for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(samplesA,streamLengthA+i+1,samplesB[i],numSamples);}
-return;}
-if(streamLengthA<numSamples){var nbElements=Math.min(streamLengthA,samplesA.length);var tempSamples=samplesB.slice();for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(tempSamples,streamLengthB+i+1,samplesA[i],numSamples);}
-for(var i=0;i<tempSamples.length;++i){samplesA[i]=tempSamples[i];}
-return;}
-var nbElements=Math.min(numSamples,samplesB.length);var probOfSwapping=streamLengthB/(streamLengthA+streamLengthB);for(var i=0;i<nbElements;++i){if(Math.random()<probOfSwapping){samplesA[i]=samplesB[i];}}}
-return{Statistics:Statistics};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS={GOOD:'good',BAD:'bad',TERRIBLE:'terrible',NEUTRAL:'generic_work'};function Frame(associatedEvents,threadTimeRanges,opt_args){tr.model.Event.call(this);this.threadTimeRanges=threadTimeRanges;this.associatedEvents=new tr.model.EventSet(associatedEvents);this.args=opt_args||{};this.title='Frame';this.start=Statistics.min(threadTimeRanges,function(x){return x.start;});this.end=Statistics.max(threadTimeRanges,function(x){return x.end;});this.totalDuration=Statistics.sum(threadTimeRanges,function(x){return x.end-x.start;});this.perfClass=FRAME_PERF_CLASS.NEUTRAL;};Frame.prototype={__proto__:tr.model.Event.prototype,set perfClass(perfClass){this.colorId=ColorScheme.getColorIdForReservedName(perfClass);this.perfClass_=perfClass;},get perfClass(){return this.perfClass_;},shiftTimestampsForward:function(amount){this.start+=amount;this.end+=amount;for(var i=0;i<this.threadTimeRanges.length;i++){this.threadTimeRanges[i].start+=amount;this.threadTimeRanges[i].end+=amount;}},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};tr.model.EventRegistry.register(Frame,{name:'frame',pluralName:'frames',singleViewElementName:'tr-ui-a-single-frame-sub-view',multiViewElementName:'tr-ui-a-multi-frame-sub-view'});return{Frame:Frame,FRAME_PERF_CLASS:FRAME_PERF_CLASS};});'use strict';tr.exportTo('tr.model',function(){function Attribute(units){this.units=units;this.infos=[];}
-Attribute.fromDictIfPossible=function(dict,opt_model){var typeInfo=Attribute.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.type===dict.type;});if(typeInfo===undefined){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Unknown attribute type \''+dict.type+'\'.'});}
-return UnknownAttribute.fromDict(dict,opt_model);}
-return typeInfo.constructor.fromDict(dict,opt_model);};Attribute.findCommonTraits=function(attributes,opt_model){var commonTraits;for(var i=0;i<attributes.length;i++){var attribute=attributes[i];if(attribute===undefined)
-continue;var attributeConstructor=attribute.constructor;var attributeUnits=attribute.units;if(commonTraits===undefined){commonTraits={constructor:attributeConstructor,units:attributeUnits};}else if(attributeConstructor!==commonTraits.constructor){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different types: '+
-commonTraits.constructor+' and '+attributeConstructor+'.'});}
-commonTraits={constructor:UnknownAttribute,units:undefined};break;}else if(attributeUnits!==commonTraits.units){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different units: '+commonTraits.units+' and '+attributeUnits+'.'});}
-commonTraits={constructor:UnknownAttribute,units:undefined};break;}}
-return commonTraits;};Attribute.aggregate=function(childAttributes,existingParentAttribute,opt_model){var definedChildAttributes=childAttributes.filter(function(childAttribute){return childAttribute!==undefined;});var traits=Attribute.findCommonTraits(definedChildAttributes,opt_model);if(traits===undefined)
-return existingParentAttribute;var constructor=traits.constructor;if(constructor.merge===undefined)
-return existingParentAttribute;var mergedAttribute=constructor.merge(definedChildAttributes,traits.units,opt_model);if(existingParentAttribute===undefined)
-return mergedAttribute;existingParentAttribute.useMergedAttribute(mergedAttribute,opt_model);return existingParentAttribute;}
-Attribute.fromTraceValue=function(dict,opt_model){throw new Error('Not implemented');};Attribute.prototype.useMergedAttribute=function(mergedAttribute,opt_model){if(mergedAttribute.constructor!==this.constructor){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different types: '+this.constructor+' and '+mergedAttribute.constructor+'.'});}}else if(mergedAttribute.units!==this.units){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different units: '+this.units+' and '+mergedAttribute.units+'.'});}}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Attribute,options);Attribute.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict'))
-throw new Error('Attributes must have fromDict method');if(!e.typeInfo.metadata.type)
-throw new Error('Attributes must provide type');if(e.typeInfo.constructor.prototype.constructor!==e.typeInfo.constructor)
-throw new Error('Attribute prototypes must provide constructor.');});function ScalarAttribute(units,value){Attribute.call(this,units);this.value=value;}
-ScalarAttribute.fromDict=function(dict){return new ScalarAttribute(dict.units,parseInt(dict.value,16));};ScalarAttribute.merge=function(childAttributes,units){var sum=0;childAttributes.forEach(function(childAttribute){sum+=childAttribute.value;});return new ScalarAttribute(units,sum);}
-ScalarAttribute.prototype.__proto__=Attribute.prototype;Attribute.register(ScalarAttribute,{type:'scalar'});function StringAttribute(units,value){Attribute.call(this,units);this.value=value;}
-StringAttribute.fromDict=function(dict){return new StringAttribute(dict.units,dict.value);};Attribute.register(StringAttribute,{type:'string'});function UnknownAttribute(units,opt_value){Attribute.call(this,units,opt_value);this.value=opt_value;}
-UnknownAttribute.fromDict=function(dict){return new UnknownAttribute(dict.units);};UnknownAttribute.prototype.__proto__=Attribute.prototype;function AttributeInfo(type,message){this.type=type;this.message=message;}
-var AttributeInfoType={INFORMATION:0,WARNING:1,LINK:2,MEMORY_OWNER:3,MEMORY_OWNED:4,OVERALL_VALUE:5,RECENT_VALUE:6,HAS_HEAP_DUMP:7};return{Attribute:Attribute,ScalarAttribute:ScalarAttribute,StringAttribute:StringAttribute,UnknownAttribute:UnknownAttribute,AttributeInfo:AttributeInfo,AttributeInfoType:AttributeInfoType};});'use strict';tr.exportTo('tr.model',function(){function ContainerMemoryDump(start){tr.model.TimedEvent.call(this,start);this.levelOfDetail=undefined;this.memoryAllocatorDumps_=undefined;this.memoryAllocatorDumpsByFullName_=undefined;};ContainerMemoryDump.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.memoryAllocatorDumpsByFullName_=undefined;},getMemoryAllocatorDumpByFullName:function(fullName){if(this.memoryAllocatorDumps_===undefined)
-return undefined;if(this.memoryAllocatorDumpsByFullName_===undefined){var index={};function addDumpsToIndex(dumps){dumps.forEach(function(dump){index[dump.fullName]=dump;addDumpsToIndex(dump.children);});};addDumpsToIndex(this.memoryAllocatorDumps_);this.memoryAllocatorDumpsByFullName_=index;}
-return this.memoryAllocatorDumpsByFullName_[fullName];},iterateRootAllocatorDumps:function(fn,opt_this){if(this.memoryAllocatorDumps===undefined)
-return;this.memoryAllocatorDumps.forEach(fn,opt_this||this);}};return{ContainerMemoryDump:ContainerMemoryDump};});'use strict';tr.exportTo('tr.model',function(){function MemoryAllocatorDump(containerMemoryDump,fullName,opt_guid){this.fullName=fullName;this.parent=undefined;this.children=[];this.attributes={};this.containerMemoryDump=containerMemoryDump;this.owns=undefined;this.ownedBy=[];this.retains=[];this.retainedBy=[];this.guid=opt_guid;};MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME='size';MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME='effective_size';MemoryAllocatorDump.DISPLAYED_SIZE_ATTRIBUTE_NAME=MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME;MemoryAllocatorDump.prototype={get name(){return this.fullName.substring(this.fullName.lastIndexOf('/')+1);},get quantifiedName(){return'\''+this.fullName+'\' in '+
-this.containerMemoryDump.containerName;},isDescendantOf:function(otherDump){var dump=this;while(dump!==undefined){if(dump===otherDump)
-return true;dump=dump.parent;}
-return false;},addAttribute:function(name,value){if(name in this.attributes)
-throw new Error('Duplicate attribute name: '+name+'.');this.attributes[name]=value;},aggregateAttributes:function(opt_model){var attributes={};this.children.forEach(function(child){child.aggregateAttributes(opt_model);tr.b.iterItems(child.attributes,function(name){attributes[name]=true;},this);},this);tr.b.iterItems(attributes,function(name){var childAttributes=this.children.map(function(child){return child.attributes[name];},this);var currentAttribute=this.attributes[name];this.attributes[name]=tr.model.Attribute.aggregate(childAttributes,currentAttribute,opt_model);},this);},getValidSizeAttributeOrUndefined:function(sizeAttrName,opt_model){var sizeAttr=this.attributes[sizeAttrName];if(sizeAttr===undefined)
-return undefined;if(!(sizeAttr instanceof tr.model.ScalarAttribute)){if(opt_model!==undefined){opt_model.importWarning({type:'memory_dump_parse_error',message:'\''+sizeAttrName+'\' attribute of memory allocator '+'dump \''+memoryAllocatorDump.fullName+'\' is not a scalar.'});}
-return undefined;}
-return sizeAttr;}};function MemoryAllocatorDumpLink(source,target,opt_importance){this.source=source;this.target=target;this.importance=opt_importance;}
-return{MemoryAllocatorDump:MemoryAllocatorDump,MemoryAllocatorDumpLink:MemoryAllocatorDumpLink};});'use strict';tr.exportTo('tr.model',function(){function GlobalMemoryDump(model,start){tr.model.ContainerMemoryDump.call(this,start);this.model=model;this.processMemoryDumps={};}
-var SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME;var EFFECTIVE_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME;function getSize(dump){var attr=dump.attributes[SIZE_ATTRIBUTE_NAME];if(attr===undefined)
-return 0;return attr.value;}
-function hasSize(dump){return dump.attributes[SIZE_ATTRIBUTE_NAME]!==undefined;}
-function optional(value,defaultValue){if(value===undefined)
-return defaultValue;return value;}
-function ownershipToUserFriendlyString(dump,importance){return dump.quantifiedName+' (importance: '+
-optional(importance,0)+')';}
-GlobalMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Global memory dump at '+tr.b.u.TimeStamp.format(this.start);},get containerName(){return'global space';},calculateGraphAttributes:function(){this.calculateSizes();this.calculateEffectiveSizes();this.aggregateAttributes();this.discountTracingOverhead();},calculateSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateMemoryAllocatorDumpSize_.bind(this));},calculateMemoryAllocatorDumpSize_:function(dump){var shouldDefineSize=false;function getDependencySize(dependencyDump){var attr=dependencyDump.attributes[SIZE_ATTRIBUTE_NAME];if(attr===undefined)
-return 0;shouldDefineSize=true;return attr.value;}
-var sizeAttribute=dump.getValidSizeAttributeOrUndefined(SIZE_ATTRIBUTE_NAME,this.model);var size=0;var infos=[];var checkDependentSizeIsConsistent=function(){};if(sizeAttribute!==undefined){size=sizeAttribute.value;shouldDefineSize=true;checkDependentSizeIsConsistent=function(dependentSize,dependentName){if(size>=dependentSize)
-return;var messageSuffix=' ('+tr.b.u.Units.sizeInBytes.format(size)+') is less than '+dependentName+' ('+
-tr.b.u.Units.sizeInBytes.format(dependentSize)+').';this.model.importWarning({type:'memory_dump_parse_error',message:'Size provided by memory allocator dump \''+
-dump.fullName+'\''+messageSuffix});infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.WARNING,'Size provided by this memory allocator dump'+messageSuffix));}.bind(this);}
-var aggregatedChildrenSize=0;var allOverlaps={};dump.children.forEach(function(childDump){function aggregateDescendantDump(descendantDump){var ownedDumpLink=descendantDump.owns;if(ownedDumpLink!==undefined&&ownedDumpLink.target.isDescendantOf(dump)){var ownedDescendantDump=ownedDumpLink.target;var ownedChildDump=ownedDescendantDump;while(ownedChildDump.parent!==dump)
-ownedChildDump=ownedChildDump.parent;if(childDump!==ownedChildDump){var overlap=getDependencySize(descendantDump);if(overlap>0){var ownedChildOverlaps=allOverlaps[ownedChildDump.name];if(ownedChildOverlaps===undefined)
-allOverlaps[ownedChildDump.name]=ownedChildOverlaps={};var previousTotalOverlap=ownedChildOverlaps[childDump.name]||0;var updatedTotalOverlap=previousTotalOverlap+overlap;ownedChildOverlaps[childDump.name]=updatedTotalOverlap;}}
-return;}
-if(descendantDump.children.length===0){aggregatedChildrenSize+=getDependencySize(descendantDump);return;}
-descendantDump.children.forEach(aggregateDescendantDump);}
-aggregateDescendantDump(childDump);});dump.children.forEach(function(childDump){var childOverlaps=allOverlaps[childDump.name];if(childOverlaps===undefined)
-return;var message=tr.b.dictionaryValues(tr.b.mapItems(childOverlaps,function(ownerChildName,overlap){return'overlaps with its sibling \''+ownerChildName+'\' ('+
-tr.b.u.Units.sizeInBytes.format(overlap)+')';})).join(' ');childDump.attributes[SIZE_ATTRIBUTE_NAME].infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.INFORMATION,message));});checkDependentSizeIsConsistent(aggregatedChildrenSize,'the aggregated size of its children');var largestOwnerSize=0;dump.ownedBy.forEach(function(ownershipLink){var owner=ownershipLink.source;var ownerSize=getDependencySize(owner);largestOwnerSize=Math.max(largestOwnerSize,ownerSize);});checkDependentSizeIsConsistent(largestOwnerSize,'the size of its largest owner');if(!shouldDefineSize){dump.attributes[SIZE_ATTRIBUTE_NAME]=undefined;return;}
-size=Math.max(size,aggregatedChildrenSize,largestOwnerSize);var sizeAttribute=new tr.model.ScalarAttribute('bytes',size);sizeAttribute.infos=infos;dump.attributes[SIZE_ATTRIBUTE_NAME]=sizeAttribute;if(aggregatedChildrenSize<size&&dump.children!==undefined&&dump.children.length>0){var virtualChild=new tr.model.MemoryAllocatorDump(dump.containerMemoryDump,dump.fullName+'/<unspecified>');virtualChild.parent=dump;dump.children.unshift(virtualChild);virtualChild.attributes[SIZE_ATTRIBUTE_NAME]=new tr.model.ScalarAttribute('bytes',size-aggregatedChildrenSize);}},calculateEffectiveSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpSubSizes_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPreOrder(this.calculateDumpCumulativeOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpEffectiveSize_.bind(this));},calculateDumpSubSizes_:function(dump){if(!hasSize(dump))
-return;if(dump.children===undefined||dump.children.length===0){var size=getSize(dump);dump.notOwningSubSize_=size;dump.notOwnedSubSize_=size;return;}
-var notOwningSubSize=0;dump.children.forEach(function(childDump){if(childDump.owns!==undefined)
-return;notOwningSubSize+=optional(childDump.notOwningSubSize_,0);});dump.notOwningSubSize_=notOwningSubSize;var notOwnedSubSize=0;dump.children.forEach(function(childDump){if(childDump.ownedBy.length===0){notOwnedSubSize+=optional(childDump.notOwnedSubSize_,0);return;}
-var largestChildOwnerSize=0;childDump.ownedBy.forEach(function(ownershipLink){largestChildOwnerSize=Math.max(largestChildOwnerSize,getSize(ownershipLink.source));});notOwnedSubSize+=getSize(childDump)-largestChildOwnerSize;});dump.notOwnedSubSize_=notOwnedSubSize;},calculateDumpOwnershipCoefficient_:function(dump){if(!hasSize(dump))
-return;if(dump.ownedBy.length===0)
-return;var owners=dump.ownedBy.map(function(ownershipLink){return{dump:ownershipLink.source,importance:optional(ownershipLink.importance,0),notOwningSubSize:optional(ownershipLink.source.notOwningSubSize_,0)};});owners.sort(function(a,b){if(a.importance===b.importance)
-return a.notOwningSubSize-b.notOwningSubSize;return b.importance-a.importance;});var currentImportanceStartPos=0;var alreadyAttributedSubSize=0;while(currentImportanceStartPos<owners.length){var currentImportance=owners[currentImportanceStartPos].importance;var nextImportanceStartPos=currentImportanceStartPos+1;while(nextImportanceStartPos<owners.length&&owners[nextImportanceStartPos].importance===currentImportance){nextImportanceStartPos++;}
-var attributedNotOwningSubSize=0;for(var pos=currentImportanceStartPos;pos<nextImportanceStartPos;pos++){var owner=owners[pos];var notOwningSubSize=owner.notOwningSubSize;if(notOwningSubSize>alreadyAttributedSubSize){attributedNotOwningSubSize+=(notOwningSubSize-alreadyAttributedSubSize)/(nextImportanceStartPos-pos);alreadyAttributedSubSize=notOwningSubSize;}
-var owningCoefficient=0;if(notOwningSubSize!==0)
-owningCoefficient=attributedNotOwningSubSize/notOwningSubSize;owner.dump.owningCoefficient_=owningCoefficient;}
-currentImportanceStartPos=nextImportanceStartPos;}
-var notOwnedSubSize=optional(dump.notOwnedSubSize_,0);var remainderSubSize=notOwnedSubSize-alreadyAttributedSubSize;var ownedCoefficient=0;if(notOwnedSubSize!==0)
-ownedCoefficient=remainderSubSize/notOwnedSubSize;dump.ownedCoefficient_=ownedCoefficient;},calculateDumpCumulativeOwnershipCoefficient_:function(dump){if(!hasSize(dump))
-return;var cumulativeOwnedCoefficient=optional(dump.ownedCoefficient_,1);var parent=dump.parent;if(dump.parent!==undefined)
-cumulativeOwnedCoefficient*=dump.parent.cumulativeOwnedCoefficient_;dump.cumulativeOwnedCoefficient_=cumulativeOwnedCoefficient;var cumulativeOwningCoefficient;if(dump.owns!==undefined){cumulativeOwningCoefficient=dump.owningCoefficient_*dump.owns.target.cumulativeOwningCoefficient_;}else if(dump.parent!==undefined){cumulativeOwningCoefficient=dump.parent.cumulativeOwningCoefficient_;}else{cumulativeOwningCoefficient=1;}
-dump.cumulativeOwningCoefficient_=cumulativeOwningCoefficient;},calculateDumpEffectiveSize_:function(dump){if(!hasSize(dump)){dump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME]=undefined;return;}
-var effectiveSize;if(dump.children===undefined||dump.children.length===0){effectiveSize=getSize(dump)*dump.cumulativeOwningCoefficient_*dump.cumulativeOwnedCoefficient_;}else{effectiveSize=0;dump.children.forEach(function(childDump){if(!hasSize(childDump))
-return;effectiveSize+=childDump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME].value;});}
-var attribute=new tr.model.ScalarAttribute('bytes',effectiveSize);dump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME]=attribute;if(dump.ownedBy.length>0){var message='shared by:'+
-dump.ownedBy.map(function(ownershipLink){return'\n  - '+ownershipToUserFriendlyString(ownershipLink.source,ownershipLink.importance);}).join();attribute.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.MEMORY_OWNED,message));}
-if(dump.owns!==undefined){var target=dump.owns.target;var message='shares '+
-ownershipToUserFriendlyString(target,dump.owns.importance)+' with';var otherOwnershipLinks=target.ownedBy.filter(function(ownershipLink){return ownershipLink.source!==dump;});if(otherOwnershipLinks.length>0){message+=':';message+=otherOwnershipLinks.map(function(ownershipLink){return'\n  - '+ownershipToUserFriendlyString(ownershipLink.source,ownershipLink.importance);}).join();}else{message+=' no other dumps';}
-attribute.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.MEMORY_OWNER,message));}},aggregateAttributes:function(){this.iterateRootAllocatorDumps(function(dump){dump.aggregateAttributes(this.model);});this.iterateRootAllocatorDumps(this.propagateAttributesRecursively);tr.b.iterItems(this.processMemoryDumps,function(pid,processMemoryDump){processMemoryDump.iterateRootAllocatorDumps(function(dump){dump.aggregateAttributes(this.model);},this);},this);},propagateAttributesRecursively:function(globalAllocatorDump){tr.b.iterItems(globalAllocatorDump.attributes,function(attrName,attr){if(attrName===SIZE_ATTRIBUTE_NAME||attrName===EFFECTIVE_SIZE_ATTRIBUTE_NAME){return;}
-globalAllocatorDump.ownedBy.forEach(function(ownershipLink){var processAllocatorDump=ownershipLink.source;if(processAllocatorDump.attributes[attrName]!==undefined){return;}
-processAllocatorDump.attributes[attrName]=attr;});});globalAllocatorDump.children.forEach(this.propagateAttributesRecursively,this);},discountTracingOverhead:function(){tr.b.iterItems(this.processMemoryDumps,function(pid,dump){dump.discountTracingOverhead(this.model);},this);},iterateContainerDumps:function(fn){fn.call(this,this);tr.b.iterItems(this.processMemoryDumps,function(pid,processDump){fn.call(this,processDump);},this);},iterateAllRootAllocatorDumps:function(fn){this.iterateContainerDumps(function(containerDump){containerDump.iterateRootAllocatorDumps(fn,this);});},traverseAllocatorDumpsInDepthFirstPostOrder:function(fn){var visitedDumps=new WeakSet();var openDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
-return;if(openDumps.has(dump))
-throw new Error(dump.userFriendlyName+' contains a cycle');openDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);fn.call(this,dump);visitedDumps.add(dump);openDumps.delete(dump);}
-this.iterateAllRootAllocatorDumps(visit);},traverseAllocatorDumpsInDepthFirstPreOrder:function(fn){var visitedDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
-return;if(dump.owns!==undefined&&!visitedDumps.has(dump.owns.target))
-return;if(dump.parent!==undefined&&!visitedDumps.has(dump.parent))
-return;fn.call(this,dump);visitedDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);}
-this.iterateAllRootAllocatorDumps(visit);}};tr.model.EventRegistry.register(GlobalMemoryDump,{name:'globalMemoryDump',pluralName:'globalMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{GlobalMemoryDump:GlobalMemoryDump};});'use strict';tr.exportTo('tr.model',function(){var InstantEventType={GLOBAL:1,PROCESS:2};function InstantEvent(category,title,colorId,start,args){tr.model.TimedEvent.call(this);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.type=undefined;};InstantEvent.prototype={__proto__:tr.model.TimedEvent.prototype};function GlobalInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.GLOBAL;};GlobalInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Global instant event '+this.title+' @ '+
-tr.b.u.TimeStamp.format(start);}};function ProcessInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.PROCESS;};ProcessInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Process-level instant event '+this.title+' @ '+
-tr.b.u.TimeStamp.format(start);}};tr.model.EventRegistry.register(InstantEvent,{name:'instantEvent',pluralName:'instantEvents',singleViewElementName:'tr-ui-a-single-instant-event-sub-view',multiViewElementName:'tr-ui-a-multi-instant-event-sub-view'});return{GlobalInstantEvent:GlobalInstantEvent,ProcessInstantEvent:ProcessInstantEvent,InstantEventType:InstantEventType,InstantEvent:InstantEvent};});'use strict';tr.exportTo('tr.model',function(){var CompoundEventSelectionState={NOT_SELECTED:0,EVENT_SELECTED:0x1,SOME_ASSOCIATED_EVENTS_SELECTED:0x2,ALL_ASSOCIATED_EVENTS_SELECTED:0x4,EVENT_AND_SOME_ASSOCIATED_SELECTED:0x1|0x2,EVENT_AND_ALL_ASSOCIATED_SELECTED:0x1|0x4};return{CompoundEventSelectionState:CompoundEventSelectionState};});'use strict';tr.exportTo('tr.model',function(){var CompoundEventSelectionState=tr.model.CompoundEventSelectionState;function InteractionRecord(parentModel,title,colorId,start,duration){tr.model.TimedEvent.call(this,start);this.title=title;this.colorId=colorId;this.duration=duration;this.args={};this.associatedEvents=new tr.model.EventSet();this.parentModel=parentModel;this.sourceEvents=new tr.model.EventSet();}
-InteractionRecord.prototype={__proto__:tr.model.TimedEvent.prototype,get subSlices(){return[];},get userFriendlyName(){return this.title+' interaction at '+
-tr.b.u.TimeStamp.format(this.start);},get stableId(){return'IR.'+this.parentModel.interactionRecords.indexOf(this);},computeCompoundEvenSelectionState:function(selection){var cess=CompoundEventSelectionState.NOT_SELECTED;if(selection.contains(this))
-cess|=CompoundEventSelectionState.EVENT_SELECTED;if(this.associatedEvents.intersectionIsEmpty(selection))
-return cess;var allContained=this.associatedEvents.every(function(event){return selection.contains(event);});if(allContained)
-cess|=CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;else
-cess|=CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;return cess;}};tr.model.EventRegistry.register(InteractionRecord,{name:'interaction',pluralName:'interactions',singleViewElementName:'tr-ui-a-single-interaction-record-sub-view',multiViewElementName:'tr-ui-a-multi-interaction-record-sub-view'});return{InteractionRecord:InteractionRecord};});'use strict';tr.exportTo('tr.b',function(){function findLowIndexInSortedArray(ary,mapFn,loVal){if(ary.length==0)
+tr.v.Unit.byName.timeStampInMs.format(this.start);}};tr.model.EventRegistry.register(Alert,{name:'alert',pluralName:'alerts',singleViewElementName:'tr-ui-a-alert-sub-view',multiViewElementName:'tr-ui-a-alert-sub-view'});return{Alert:Alert};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS={GOOD:'good',BAD:'bad',TERRIBLE:'terrible',NEUTRAL:'generic_work'};function Frame(associatedEvents,threadTimeRanges,opt_args){tr.model.Event.call(this);this.threadTimeRanges=threadTimeRanges;this.associatedEvents=new tr.model.EventSet(associatedEvents);this.args=opt_args||{};this.title='Frame';this.start=Statistics.min(threadTimeRanges,function(x){return x.start;});this.end=Statistics.max(threadTimeRanges,function(x){return x.end;});this.totalDuration=Statistics.sum(threadTimeRanges,function(x){return x.end-x.start;});this.perfClass=FRAME_PERF_CLASS.NEUTRAL;};Frame.prototype={__proto__:tr.model.Event.prototype,set perfClass(perfClass){this.colorId=ColorScheme.getColorIdForReservedName(perfClass);this.perfClass_=perfClass;},get perfClass(){return this.perfClass_;},shiftTimestampsForward:function(amount){this.start+=amount;this.end+=amount;for(var i=0;i<this.threadTimeRanges.length;i++){this.threadTimeRanges[i].start+=amount;this.threadTimeRanges[i].end+=amount;}},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};tr.model.EventRegistry.register(Frame,{name:'frame',pluralName:'frames',singleViewElementName:'tr-ui-a-single-frame-sub-view',multiViewElementName:'tr-ui-a-multi-frame-sub-view'});return{Frame:Frame,FRAME_PERF_CLASS:FRAME_PERF_CLASS};});'use strict';tr.exportTo('tr.b',function(){function findLowIndexInSortedArray(ary,mapFn,loVal){if(ary.length==0)
 return 1;var low=0;var high=ary.length-1;var i,comparison;var hitPos=-1;while(low<=high){i=Math.floor((low+high)/2);comparison=mapFn(ary[i])-loVal;if(comparison<0){low=i+1;continue;}else if(comparison>0){high=i-1;continue;}else{hitPos=i;high=i-1;}}
 return hitPos!=-1?hitPos:low;}
 function findHighIndexInSortedArray(ary,mapFn,loVal,hiVal){var lo=loVal||0;var hi=hiVal!==undefined?hiVal:ary.length;while(lo<hi){var mid=(lo+hi)>>1;if(mapFn(ary[mid])>=0)
@@ -3259,35 +3220,72 @@
 return null;if(loDiff<hiDiff)
 return loInt;else
 return hiInt;}
-return{findLowIndexInSortedArray:findLowIndexInSortedArray,findHighIndexInSortedArray:findHighIndexInSortedArray,findIndexInSortedIntervals:findIndexInSortedIntervals,findIndexInSortedClosedIntervals:findIndexInSortedClosedIntervals,iterateOverIntersectingIntervals:iterateOverIntersectingIntervals,getIntersectingIntervals:getIntersectingIntervals,findClosestElementInSortedArray:findClosestElementInSortedArray,findClosestIntervalInSortedIntervals:findClosestIntervalInSortedIntervals};});'use strict';tr.exportTo('tr.model',function(){function CounterSample(series,timestamp,value){tr.model.Event.call(this);this.series_=series;this.timestamp_=timestamp;this.value_=value;}
-CounterSample.groupByTimestamp=function(samples){var samplesByTimestamp=tr.b.group(samples,function(sample){return sample.timestamp;});var timestamps=tr.b.dictionaryKeys(samplesByTimestamp);timestamps.sort();var groups=[];for(var i=0;i<timestamps.length;i++){var ts=timestamps[i];var group=samplesByTimestamp[ts];group.sort(function(x,y){return x.series.seriesIndex-y.series.seriesIndex;});groups.push(group);}
-return groups;}
-CounterSample.prototype={__proto__:tr.model.Event.prototype,get series(){return this.series_;},get timestamp(){return this.timestamp_;},get value(){return this.value_;},set timestamp(timestamp){this.timestamp_=timestamp;},addBoundsToRange:function(range){range.addValue(this.timestamp);},getSampleIndex:function(){return tr.b.findLowIndexInSortedArray(this.series.timestamps,function(x){return x;},this.timestamp_);},get userFriendlyName(){return'Counter sample from '+this.series_.title+' at '+
-tr.b.u.TimeStamp.format(this.timestamp);}};tr.model.EventRegistry.register(CounterSample,{name:'counterSample',pluralName:'counterSamples',singleViewElementName:'tr-ui-a-counter-sample-sub-view',multiViewElementName:'tr-ui-a-counter-sample-sub-view'});return{CounterSample:CounterSample};});'use strict';tr.exportTo('tr.model',function(){var CounterSample=tr.model.CounterSample;function CounterSeries(name,color){tr.model.EventContainer.call(this);this.name_=name;this.color_=color;this.timestamps_=[];this.samples_=[];this.counter=undefined;this.seriesIndex=undefined;}
-CounterSeries.prototype={__proto__:tr.model.EventContainer.prototype,get length(){return this.timestamps_.length;},get name(){return this.name_;},get color(){return this.color_;},get samples(){return this.samples_;},get timestamps(){return this.timestamps_;},getSample:function(idx){return this.samples_[idx];},getTimestamp:function(idx){return this.timestamps_[idx];},addCounterSample:function(ts,val){var sample=new CounterSample(this,ts,val);this.addSample(sample);return sample;},addSample:function(sample){this.timestamps_.push(sample.timestamp);this.samples_.push(sample);},getStatistics:function(sampleIndices){var sum=0;var min=Number.MAX_VALUE;var max=-Number.MAX_VALUE;for(var i=0;i<sampleIndices.length;++i){var sample=this.getSample(sampleIndices[i]).value;sum+=sample;min=Math.min(sample,min);max=Math.max(sample,max);}
-return{min:min,max:max,avg:(sum/sampleIndices.length),start:this.getSample(sampleIndices[0]).value,end:this.getSample(sampleIndices.length-1).value};},shiftTimestampsForward:function(amount){for(var i=0;i<this.timestamps_.length;++i){this.timestamps_[i]+=amount;this.samples_[i].timestamp=this.timestamps_[i];}},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.CounterSample)){this.samples_.forEach(callback,opt_this);}},iterateAllChildEventContainers:function(callback,opt_this){}};return{CounterSeries:CounterSeries};});'use strict';tr.exportTo('tr.model',function(){function Counter(parent,id,category,name){tr.model.EventContainer.call(this);this.parent_=parent;this.id_=id;this.category_=category||'';this.name_=name;this.series_=[];this.totals=[];}
-Counter.prototype={__proto__:tr.model.EventContainer.prototype,get parent(){return this.parent_;},get id(){return this.id_;},get category(){return this.category_;},get name(){return this.name_;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){for(var i=0;i<this.series_.length;i++)
-callback.call(opt_this,this.series_[i]);},set timestamps(arg){throw new Error('Bad counter API. No cookie.');},set seriesNames(arg){throw new Error('Bad counter API. No cookie.');},set seriesColors(arg){throw new Error('Bad counter API. No cookie.');},set samples(arg){throw new Error('Bad counter API. No cookie.');},addSeries:function(series){series.counter=this;series.seriesIndex=this.series_.length;this.series_.push(series);return series;},getSeries:function(idx){return this.series_[idx];},get series(){return this.series_;},get numSeries(){return this.series_.length;},get numSamples(){if(this.series_.length===0)
-return 0;return this.series_[0].length;},get timestamps(){if(this.series_.length===0)
-return[];return this.series_[0].timestamps;},getSampleStatistics:function(sampleIndices){sampleIndices.sort();var ret=[];this.series_.forEach(function(series){ret.push(series.getStatistics(sampleIndices));});return ret;},shiftTimestampsForward:function(amount){for(var i=0;i<this.series_.length;++i)
-this.series_[i].shiftTimestampsForward(amount);},updateBounds:function(){this.totals=[];this.maxTotal=0;this.bounds.reset();if(this.series_.length===0)
-return;var firstSeries=this.series_[0];var lastSeries=this.series_[this.series_.length-1];this.bounds.addValue(firstSeries.getTimestamp(0));this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length-1));var numSeries=this.numSeries;this.maxTotal=-Infinity;for(var i=0;i<firstSeries.length;++i){var total=0;this.series_.forEach(function(series){total+=series.getSample(i).value;this.totals.push(total);}.bind(this));this.maxTotal=Math.max(total,this.maxTotal);}}};Counter.compare=function(x,y){var tmp=x.parent.compareTo(y);if(tmp!=0)
-return tmp;var tmp=x.name.localeCompare(y.name);if(tmp==0)
-return x.tid-y.tid;return tmp;};return{Counter:Counter};});'use strict';tr.exportTo('tr.model',function(){function Slice(category,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.inFlowEvents=[];this.outFlowEvents=[];this.subSlices=[];this.selfTime=undefined;this.cpuSelfTime=undefined;this.important=false;this.parentContainer=undefined;this.argsStripped=false;this.bind_id_=opt_bind_id;this.parentSlice=undefined;this.isTopLevel=false;if(opt_duration!==undefined)
+return{findLowIndexInSortedArray:findLowIndexInSortedArray,findHighIndexInSortedArray:findHighIndexInSortedArray,findIndexInSortedIntervals:findIndexInSortedIntervals,findIndexInSortedClosedIntervals:findIndexInSortedClosedIntervals,iterateOverIntersectingIntervals:iterateOverIntersectingIntervals,getIntersectingIntervals:getIntersectingIntervals,findClosestElementInSortedArray:findClosestElementInSortedArray,findClosestIntervalInSortedIntervals:findClosestIntervalInSortedIntervals};});'use strict';tr.exportTo('tr.model.helpers',function(){var Frame=tr.model.Frame;var Statistics=tr.b.Statistics;var UI_DRAW_TYPE={NONE:'none',LEGACY:'legacy',MARSHMALLOW:'marshmallow'};var UI_THREAD_DRAW_NAMES={'performTraversals':UI_DRAW_TYPE.LEGACY,'Choreographer#doFrame':UI_DRAW_TYPE.MARSHMALLOW};var RENDER_THREAD_DRAW_NAME='DrawFrame';var RENDER_THREAD_INDEP_DRAW_NAME='doFrame';var THREAD_SYNC_NAME='syncFrameState';function getSlicesForThreadTimeRanges(threadTimeRanges){var ret=[];threadTimeRanges.forEach(function(threadTimeRange){var slices=[];threadTimeRange.thread.sliceGroup.iterSlicesInTimeRange(function(slice){slices.push(slice);},threadTimeRange.start,threadTimeRange.end);ret.push.apply(ret,slices);});return ret;}
+function makeFrame(threadTimeRanges,surfaceFlinger){var args={};if(surfaceFlinger&&surfaceFlinger.hasVsyncs){var start=Statistics.min(threadTimeRanges,function(threadTimeRanges){return threadTimeRanges.start;});args['deadline']=surfaceFlinger.getFrameDeadline(start);args['frameKickoff']=surfaceFlinger.getFrameKickoff(start);}
+var events=getSlicesForThreadTimeRanges(threadTimeRanges);return new Frame(events,threadTimeRanges,args);}
+function findOverlappingDrawFrame(renderThread,time){if(!renderThread)
+return undefined;var slices=renderThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){var slice=slices[i];if(slice.title==RENDER_THREAD_DRAW_NAME&&slice.start<=time&&time<=slice.end){return slice;}}
+return undefined;}
+function getPreTraversalWorkRanges(uiThread){if(!uiThread)
+return[];var preFrameEvents=[];uiThread.sliceGroup.slices.forEach(function(slice){if(slice.title=='obtainView'||slice.title=='setupListItem'||slice.title=='deliverInputEvent'||slice.title=='RV Scroll')
+preFrameEvents.push(slice);});uiThread.asyncSliceGroup.slices.forEach(function(slice){if(slice.title=='deliverInputEvent')
+preFrameEvents.push(slice);});return tr.b.mergeRanges(tr.b.convertEventsToRanges(preFrameEvents),3,function(events){return{start:events[0].min,end:events[events.length-1].max};});}
+function getFrameStartTime(traversalStart,preTraversalWorkRanges){var preTraversalWorkRange=tr.b.findClosestIntervalInSortedIntervals(preTraversalWorkRanges,function(range){return range.start},function(range){return range.end},traversalStart,3);if(preTraversalWorkRange)
+return preTraversalWorkRange.start;return traversalStart;}
+function getUiThreadDrivenFrames(app){if(!app.uiThread)
+return[];var preTraversalWorkRanges=[];if(app.uiDrawType==UI_DRAW_TYPE.LEGACY)
+preTraversalWorkRanges=getPreTraversalWorkRanges(app.uiThread);var frames=[];app.uiThread.sliceGroup.slices.forEach(function(slice){if(!(slice.title in UI_THREAD_DRAW_NAMES)){return;}
+var threadTimeRanges=[];var uiThreadTimeRange={thread:app.uiThread,start:getFrameStartTime(slice.start,preTraversalWorkRanges),end:slice.end};threadTimeRanges.push(uiThreadTimeRange);var rtDrawSlice=findOverlappingDrawFrame(app.renderThread,slice.end);if(rtDrawSlice){var rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice){uiThreadTimeRange.end=Math.min(uiThreadTimeRange.end,rtSyncSlice.start);}
+threadTimeRanges.push({thread:app.renderThread,start:rtDrawSlice.start,end:rtDrawSlice.end});}
+frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getRenderThreadDrivenFrames(app){if(!app.renderThread)
+return[];var frames=[];app.renderThread.sliceGroup.getSlicesOfName(RENDER_THREAD_INDEP_DRAW_NAME).forEach(function(slice){var threadTimeRanges=[{thread:app.renderThread,start:slice.start,end:slice.end}];frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getUiDrawType(uiThread){if(!uiThread)
+return UI_DRAW_TYPE.NONE;var slices=uiThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){if(slices[i].title in UI_THREAD_DRAW_NAMES){return UI_THREAD_DRAW_NAMES[slices[i].title];}}
+return UI_DRAW_TYPE.NONE;}
+function getInputSamples(process){var samples=undefined;for(var counterName in process.counters){if(/^android\.aq\:pending/.test(counterName)&&process.counters[counterName].numSeries==1){samples=process.counters[counterName].series[0].samples;break;}}
+if(!samples)
+return[];var inputSamples=[];var lastValue=0;samples.forEach(function(sample){if(sample.value>lastValue){inputSamples.push(sample);}
+lastValue=sample.value;});return inputSamples;}
+function getAnimationAsyncSlices(uiThread){if(!uiThread)
+return[];var slices=[];uiThread.asyncSliceGroup.iterateAllEvents(function(slice){if(/^animator\:/.test(slice.title))
+slices.push(slice);});return slices;}
+function AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType){this.process=process;this.uiThread=uiThread;this.renderThread=renderThread;this.surfaceFlinger=surfaceFlinger;this.uiDrawType=uiDrawType;this.frames_=undefined;this.inputs_=undefined;};AndroidApp.createForProcessIfPossible=function(process,surfaceFlinger){var uiThread=process.getThread(process.pid);var uiDrawType=getUiDrawType(uiThread);if(uiDrawType==UI_DRAW_TYPE.NONE){uiThread=undefined;}
+var renderThreads=process.findAllThreadsNamed('RenderThread');var renderThread=renderThreads.length==1?renderThreads[0]:undefined;if(uiThread||renderThread){return new AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType);}};AndroidApp.prototype={getFrames:function(){if(!this.frames_){var uiFrames=getUiThreadDrivenFrames(this);var rtFrames=getRenderThreadDrivenFrames(this);this.frames_=uiFrames.concat(rtFrames);this.frames_.sort(function(a,b){a.end-b.end});}
+return this.frames_;},getInputSamples:function(){if(!this.inputs_){this.inputs_=getInputSamples(this.process);}
+return this.inputs_;},getAnimationAsyncSlices:function(){if(!this.animations_){this.animations_=getAnimationAsyncSlices(this.uiThread);}
+return this.animations_;}};return{AndroidApp:AndroidApp};});'use strict';tr.exportTo('tr.model.helpers',function(){var findLowIndexInSortedArray=tr.b.findLowIndexInSortedArray;var VSYNC_SF_NAME='android.VSYNC-sf';var VSYNC_APP_NAME='android.VSYNC-app';var VSYNC_FALLBACK_NAME='android.VSYNC';var TIMESTAMP_FUDGE_MS=0.01;function getVsyncTimestamps(process,counterName){var vsync=process.counters[counterName];if(!vsync)
+vsync=process.counters[VSYNC_FALLBACK_NAME];if(vsync&&vsync.numSeries==1&&vsync.numSamples>1)
+return vsync.series[0].timestamps;return undefined;}
+function AndroidSurfaceFlinger(process,thread){this.process=process;this.thread=thread;this.appVsync_=undefined;this.sfVsync_=undefined;this.appVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_APP_NAME);this.sfVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_SF_NAME);};AndroidSurfaceFlinger.createForProcessIfPossible=function(process){var mainThread=process.getThread(process.pid);if(mainThread&&mainThread.name&&/surfaceflinger/.test(mainThread.name))
+return new AndroidSurfaceFlinger(process,mainThread);var primaryThreads=process.findAllThreadsNamed('SurfaceFlinger');if(primaryThreads.length==1)
+return new AndroidSurfaceFlinger(process,primaryThreads[0]);return undefined;};AndroidSurfaceFlinger.prototype={get hasVsyncs(){return!!this.appVsyncTimestamps_&&!!this.sfVsyncTimestamps_;},getFrameKickoff:function(timestamp){if(!this.hasVsyncs)
+throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.appVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex<1)
+return undefined;return this.appVsyncTimestamps_[firstGreaterIndex-1];},getFrameDeadline:function(timestamp){if(!this.hasVsyncs)
+throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.sfVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex>=this.sfVsyncTimestamps_.length)
+return undefined;return this.sfVsyncTimestamps_[firstGreaterIndex];}};return{AndroidSurfaceFlinger:AndroidSurfaceFlinger};});'use strict';tr.exportTo('tr.model.helpers',function(){var AndroidApp=tr.model.helpers.AndroidApp;var AndroidSurfaceFlinger=tr.model.helpers.AndroidSurfaceFlinger;var IMPORTANT_SURFACE_FLINGER_SLICES={'doComposition':true,'updateTexImage':true,'postFramebuffer':true};var IMPORTANT_UI_THREAD_SLICES={'Choreographer#doFrame':true,'performTraversals':true,'deliverInputEvent':true};var IMPORTANT_RENDER_THREAD_SLICES={'doFrame':true};function iterateImportantThreadSlices(thread,important,callback){if(!thread)
+return;thread.sliceGroup.slices.forEach(function(slice){if(slice.title in important)
+callback(slice);});}
+function AndroidModelHelper(model){this.model=model;this.apps=[];this.surfaceFlinger=undefined;var processes=model.getAllProcesses();for(var i=0;i<processes.length&&!this.surfaceFlinger;i++){this.surfaceFlinger=AndroidSurfaceFlinger.createForProcessIfPossible(processes[i]);}
+model.getAllProcesses().forEach(function(process){var app=AndroidApp.createForProcessIfPossible(process,this.surfaceFlinger);if(app)
+this.apps.push(app);},this);};AndroidModelHelper.guid=tr.b.GUID.allocate();AndroidModelHelper.supportsModel=function(model){return true;};AndroidModelHelper.prototype={iterateImportantSlices:function(callback){if(this.surfaceFlinger){iterateImportantThreadSlices(this.surfaceFlinger.thread,IMPORTANT_SURFACE_FLINGER_SLICES,callback);}
+this.apps.forEach(function(app){iterateImportantThreadSlices(app.uiThread,IMPORTANT_UI_THREAD_SLICES,callback);iterateImportantThreadSlices(app.renderThread,IMPORTANT_RENDER_THREAD_SLICES,callback);});}};return{AndroidModelHelper:AndroidModelHelper};});'use strict';tr.exportTo('tr.model',function(){function Slice(category,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.inFlowEvents=[];this.outFlowEvents=[];this.subSlices=[];this.selfTime=undefined;this.cpuSelfTime=undefined;this.important=false;this.parentContainer=undefined;this.argsStripped=false;this.bind_id_=opt_bind_id;this.parentSlice=undefined;this.isTopLevel=false;if(opt_duration!==undefined)
 this.duration=opt_duration;if(opt_cpuStart!==undefined)
 this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
 this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
 this.argsStripped=true;}
 Slice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get userFriendlyName(){return'Slice '+this.title+' at '+
-tr.b.u.TimeStamp.format(this.start);},get stableId(){var parentSliceGroup=this.parentContainer.sliceGroup;return parentSliceGroup.stableId+'.'+
+tr.v.Unit.byName.timeStampInMs.format(this.start);},get stableId(){var parentSliceGroup=this.parentContainer.sliceGroup;return parentSliceGroup.stableId+'.'+
 parentSliceGroup.slices.indexOf(this);},findDescendentSlice:function(targetTitle){if(!this.subSlices)
 return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
 return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
 return undefined;},get mostTopLevelSlice(){var curSlice=this;while(curSlice.parentSlice)
-curSlice=curSlice.parentSlice;return curSlice;},iterateAllSubsequentSlices:function(callback,opt_this){var parentStack=[];var started=false;var topmostSlice=this.mostTopLevelSlice;parentStack.push(topmostSlice);while(parentStack.length!==0){var curSlice=parentStack.pop();if(started)
+curSlice=curSlice.parentSlice;return curSlice;},getProcess:function(){var thread=this.parentContainer;if(thread&&thread.getProcess)
+return thread.getProcess();return undefined;},get model(){var process=this.getProcess();if(process!==undefined)
+return this.getProcess().model;return undefined;},iterateAllSubsequentSlices:function(callback,opt_this){var parentStack=[];var started=false;var topmostSlice=this.mostTopLevelSlice;parentStack.push(topmostSlice);while(parentStack.length!==0){var curSlice=parentStack.pop();if(started)
 callback.call(opt_this,curSlice);else
-started=(curSlice.guid===this.guid);for(var i=curSlice.subSlices.length-1;i>=0;i--){parentStack.push(curSlice.subSlices[i]);}}},get subsequentSlices(){var res=[];this.iterateAllSubsequentSlices(function(subseqSlice){res.push(subseqSlice);});return res;},iterateAllAncestors:function(callback,opt_this){var curSlice=this;while(curSlice.parentSlice){curSlice=curSlice.parentSlice;callback.call(opt_this,curSlice);}},get ancestorSlices(){var res=[];this.iterateAllAncestors(function(ancestor){res.push(ancestor);});return res;},iterateEntireHierarchy:function(callback,opt_this){var mostTopLevelSlice=this.mostTopLevelSlice;callback.call(opt_this,mostTopLevelSlice);mostTopLevelSlice.iterateAllSubsequentSlices(callback,opt_this);},get entireHierarchy(){var res=[];this.iterateEntireHierarchy(function(slice){res.push(slice);});return res;},get ancestorAndSubsequentSlices(){var res=[];res.push(this);this.iterateAllAncestors(function(aSlice){res.push(aSlice);});this.iterateAllSubsequentSlices(function(sSlice){res.push(sSlice);});return res;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},get descendentSlices(){var res=[];this.iterateAllDescendents(function(des){res.push(des);});return res;}};return{Slice:Slice};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;var SCHEDULING_STATE={DEBUG:'Debug',EXIT_DEAD:'Exit Dead',RUNNABLE:'Runnable',RUNNING:'Running',SLEEPING:'Sleeping',STOPPED:'Stopped',TASK_DEAD:'Task Dead',UNINTR_SLEEP:'Uninterruptible Sleep',UNINTR_SLEEP_WAKE_KILL:'Uninterruptible Sleep | WakeKill',UNINTR_SLEEP_WAKING:'Uninterruptible Sleep | Waking',UNKNOWN:'UNKNOWN',WAKE_KILL:'Wakekill',WAKING:'Waking',ZOMBIE:'Zombie'};function ThreadTimeSlice(thread,schedulingState,cat,start,args,opt_duration){Slice.call(this,cat,schedulingState,this.getColorForState_(schedulingState),start,args,opt_duration);this.thread=thread;this.schedulingState=schedulingState;this.cpuOnWhichThreadWasRunning=undefined;}
-ThreadTimeSlice.prototype={__proto__:Slice.prototype,getColorForState_:function(state){var getColorIdForReservedName=tr.b.ColorScheme.getColorIdForReservedName;switch(state){case SCHEDULING_STATE.RUNNABLE:return getColorIdForReservedName('thread_state_runnable');case SCHEDULING_STATE.RUNNING:return getColorIdForReservedName('thread_state_running');case SCHEDULING_STATE.SLEEPING:return getColorIdForReservedName('thread_state_sleeping');case SCHEDULING_STATE.DEBUG:case SCHEDULING_STATE.EXIT_DEAD:case SCHEDULING_STATE.STOPPED:case SCHEDULING_STATE.TASK_DEAD:case SCHEDULING_STATE.UNINTR_SLEEP:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:case SCHEDULING_STATE.UNKNOWN:case SCHEDULING_STATE.WAKE_KILL:case SCHEDULING_STATE.WAKING:case SCHEDULING_STATE.ZOMBIE:return getColorIdForReservedName('thread_state_iowait');default:return getColorIdForReservedName('thread_state_unknown');}},get analysisTypeName(){return'tr.ui.analysis.ThreadTimeSlice';},getAssociatedCpuSlice:function(){if(!this.cpuOnWhichThreadWasRunning)
+started=(curSlice.guid===this.guid);for(var i=curSlice.subSlices.length-1;i>=0;i--){parentStack.push(curSlice.subSlices[i]);}}},get subsequentSlices(){var res=[];this.iterateAllSubsequentSlices(function(subseqSlice){res.push(subseqSlice);});return res;},iterateAllAncestors:function(callback,opt_this){var curSlice=this;while(curSlice.parentSlice){curSlice=curSlice.parentSlice;callback.call(opt_this,curSlice);}},get ancestorSlices(){var res=[];this.iterateAllAncestors(function(ancestor){res.push(ancestor);});return res;},iterateEntireHierarchy:function(callback,opt_this){var mostTopLevelSlice=this.mostTopLevelSlice;callback.call(opt_this,mostTopLevelSlice);mostTopLevelSlice.iterateAllSubsequentSlices(callback,opt_this);},get entireHierarchy(){var res=[];this.iterateEntireHierarchy(function(slice){res.push(slice);});return res;},get ancestorAndSubsequentSlices(){var res=[];res.push(this);this.iterateAllAncestors(function(aSlice){res.push(aSlice);});this.iterateAllSubsequentSlices(function(sSlice){res.push(sSlice);});return res;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},get descendentSlices(){var res=[];this.iterateAllDescendents(function(des){res.push(des);});return res;}};return{Slice:Slice};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;var SCHEDULING_STATE={DEBUG:'Debug',EXIT_DEAD:'Exit Dead',RUNNABLE:'Runnable',RUNNING:'Running',SLEEPING:'Sleeping',STOPPED:'Stopped',TASK_DEAD:'Task Dead',UNINTR_SLEEP:'Uninterruptible Sleep',UNINTR_SLEEP_WAKE_KILL:'Uninterruptible Sleep | WakeKill',UNINTR_SLEEP_WAKING:'Uninterruptible Sleep | Waking',UNINTR_SLEEP_IO:'Uninterruptible Sleep - Block I/O',UNINTR_SLEEP_WAKE_KILL_IO:'Uninterruptible Sleep | WakeKill - Block I/O',UNINTR_SLEEP_WAKING_IO:'Uninterruptible Sleep | Waking - Block I/O',UNKNOWN:'UNKNOWN',WAKE_KILL:'Wakekill',WAKING:'Waking',ZOMBIE:'Zombie'};function ThreadTimeSlice(thread,schedulingState,cat,start,args,opt_duration){Slice.call(this,cat,schedulingState,this.getColorForState_(schedulingState),start,args,opt_duration);this.thread=thread;this.schedulingState=schedulingState;this.cpuOnWhichThreadWasRunning=undefined;}
+ThreadTimeSlice.prototype={__proto__:Slice.prototype,getColorForState_:function(state){var getColorIdForReservedName=tr.b.ColorScheme.getColorIdForReservedName;switch(state){case SCHEDULING_STATE.RUNNABLE:return getColorIdForReservedName('thread_state_runnable');case SCHEDULING_STATE.RUNNING:return getColorIdForReservedName('thread_state_running');case SCHEDULING_STATE.SLEEPING:return getColorIdForReservedName('thread_state_sleeping');case SCHEDULING_STATE.DEBUG:case SCHEDULING_STATE.EXIT_DEAD:case SCHEDULING_STATE.STOPPED:case SCHEDULING_STATE.TASK_DEAD:case SCHEDULING_STATE.UNINTR_SLEEP:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:case SCHEDULING_STATE.UNKNOWN:case SCHEDULING_STATE.WAKE_KILL:case SCHEDULING_STATE.WAKING:case SCHEDULING_STATE.ZOMBIE:return getColorIdForReservedName('thread_state_uninterruptible');case SCHEDULING_STATE.UNINTR_SLEEP_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING_IO:return getColorIdForReservedName('thread_state_iowait');default:return getColorIdForReservedName('thread_state_unknown');}},get analysisTypeName(){return'tr.ui.analysis.ThreadTimeSlice';},getAssociatedCpuSlice:function(){if(!this.cpuOnWhichThreadWasRunning)
 return undefined;var cpuSlices=this.cpuOnWhichThreadWasRunning.slices;for(var i=0;i<cpuSlices.length;i++){var cpuSlice=cpuSlices[i];if(cpuSlice.start!==this.start)
 continue;if(cpuSlice.duration!==this.duration)
 continue;return cpuSlice;}
@@ -3297,7 +3295,554 @@
 if(!cpuSliceWhenLastRunning)
 return undefined;var cpu=cpuSliceWhenLastRunning.cpu;var indexOfSliceOnCpuWhenLastRunning=cpu.indexOf(cpuSliceWhenLastRunning);var nextRunningSlice=cpu.slices[indexOfSliceOnCpuWhenLastRunning+1];if(!nextRunningSlice)
 return undefined;if(Math.abs(nextRunningSlice.start-cpuSliceWhenLastRunning.end)<0.00001)
-return nextRunningSlice;return undefined;}};tr.model.EventRegistry.register(ThreadTimeSlice,{name:'threadTimeSlice',pluralName:'threadTimeSlices',singleViewElementName:'tr-ui-a-single-thread-time-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-time-slice-sub-view'});return{ThreadTimeSlice:ThreadTimeSlice,SCHEDULING_STATE:SCHEDULING_STATE};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function CpuSlice(cat,title,colorId,start,args,opt_duration){Slice.apply(this,arguments);this.threadThatWasRunning=undefined;this.cpu=undefined;}
+return nextRunningSlice;return undefined;}};tr.model.EventRegistry.register(ThreadTimeSlice,{name:'threadTimeSlice',pluralName:'threadTimeSlices',singleViewElementName:'tr-ui-a-single-thread-time-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-time-slice-sub-view'});return{ThreadTimeSlice:ThreadTimeSlice,SCHEDULING_STATE:SCHEDULING_STATE};});'use strict';tr.exportTo('tr.model',function(){var CompoundEventSelectionState={NOT_SELECTED:0,EVENT_SELECTED:0x1,SOME_ASSOCIATED_EVENTS_SELECTED:0x2,ALL_ASSOCIATED_EVENTS_SELECTED:0x4,EVENT_AND_SOME_ASSOCIATED_SELECTED:0x1|0x2,EVENT_AND_ALL_ASSOCIATED_SELECTED:0x1|0x4};return{CompoundEventSelectionState:CompoundEventSelectionState};});'use strict';tr.exportTo('tr.model.um',function(){var CompoundEventSelectionState=tr.model.CompoundEventSelectionState;function UserExpectation(parentModel,initiatorTitle,start,duration){tr.model.TimedEvent.call(this,start);this.associatedEvents=new tr.model.EventSet();this.duration=duration;this.initiatorTitle_=initiatorTitle;this.parentModel=parentModel;this.typeInfo_=undefined;this.sourceEvents=new tr.model.EventSet();}
+UserExpectation.prototype={__proto__:tr.model.TimedEvent.prototype,computeCompoundEvenSelectionState:function(selection){var cess=CompoundEventSelectionState.NOT_SELECTED;if(selection.contains(this))
+cess|=CompoundEventSelectionState.EVENT_SELECTED;if(this.associatedEvents.intersectionIsEmpty(selection))
+return cess;var allContained=this.associatedEvents.every(function(event){return selection.contains(event);});if(allContained)
+cess|=CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;else
+cess|=CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;return cess;},get userFriendlyName(){return this.title+' User Expectation at '+
+tr.v.Unit.byName.timeStampInMs.format(this.start);},get stableId(){return('UserExpectation.'+
+this.parentModel.userModel.expectations.indexOf(this));},get typeInfo(){if(!this.typeInfo_)
+this.typeInfo_=UserExpectation.findTypeInfo(this.constructor);if(!this.typeInfo_)
+throw new Error('Unregistered UserExpectation');return this.typeInfo_;},get colorId(){return this.typeInfo.metadata.colorId;},get stageTitle(){return this.typeInfo.metadata.stageTitle;},get initiatorTitle(){return this.initiatorTitle_;},get title(){if(!this.initiatorTitle)
+return this.stageTitle;return this.initiatorTitle+' '+this.stageTitle;},get totalCpuMs(){var cpuMs=0;this.associatedEvents.forEach(function(event){if(event.cpuSelfTime)
+cpuMs+=event.cpuSelfTime;});return cpuMs;}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(UserExpectation,options);UserExpectation.addEventListener('will-register',function(e){var metadata=e.typeInfo.metadata;if(metadata.stageTitle===undefined){throw new Error('Registered UserExpectations must provide '+'stageTitle');}
+if(metadata.colorId===undefined){throw new Error('Registered UserExpectations must provide '+'colorId');}});tr.model.EventRegistry.register(UserExpectation,{name:'user-expectation',pluralName:'user-expectations',singleViewElementName:'tr-ui-a-single-user-expectation-sub-view',multiViewElementName:'tr-ui-a-multi-user-expectation-sub-view'});return{UserExpectation:UserExpectation};});'use strict';tr.exportTo('tr.model.um',function(){function ResponseExpectation(parentModel,initiatorTitle,start,duration,opt_isAnimationBegin){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.isAnimationBegin=opt_isAnimationBegin||false;}
+ResponseExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:ResponseExpectation};tr.model.um.UserExpectation.register(ResponseExpectation,{stageTitle:'Response',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_response')});return{ResponseExpectation:ResponseExpectation};});'use strict';tr.exportTo('tr.v',function(){var Range=tr.b.Range;var MAX_SOURCE_INFOS=16;function NumericBase(unit){if(!(unit instanceof tr.v.Unit))
+throw new Error('Expected provided unit to be instance of Unit');this.unit=unit;}
+NumericBase.prototype={asDict:function(){var d={unit:this.unit.asJSON()};this.asDictInto_(d);return d;}};NumericBase.fromDict=function(d){if(d.type==='scalar')
+return ScalarNumeric.fromDict(d);throw new Error('Not implemented');};function NumericBin(parentNumeric,opt_range){this.parentNumeric=parentNumeric;this.range=opt_range||(new tr.b.Range());this.count=0;this.sourceInfos=[];}
+NumericBin.fromDict=function(parentNumeric,d){var n=new NumericBin(parentNumeric);n.range.min=d.min;n.range.max=d.max;n.count=d.count;n.sourceInfos=d.sourceInfos;return n;};NumericBin.prototype={add:function(value,sourceInfo){this.count+=1;tr.b.Statistics.uniformlySampleStream(this.sourceInfos,this.count,sourceInfo,MAX_SOURCE_INFOS);},addBin:function(other){if(!this.range.equals(other.range))
+throw new Error('Merging incompatible Numeric bins.');tr.b.Statistics.mergeSampledStreams(this.sourceInfos,this.count,other.sourceInfos,other.count,MAX_SOURCE_INFOS);this.count+=other.count;},asDict:function(){return{min:this.range.min,max:this.range.max,count:this.count,sourceInfos:this.sourceInfos.slice(0)};},asJSON:function(){return this.asDict();}};function Numeric(unit,range,binInfo){NumericBase.call(this,unit);this.range=range;this.numNans=0;this.nanSourceInfos=[];this.runningSum=0;this.maxCount_=0;this.underflowBin=binInfo.underflowBin;this.centralBins=binInfo.centralBins;this.centralBinWidth=binInfo.centralBinWidth;this.overflowBin=binInfo.overflowBin;this.allBins=[];this.allBins.push(this.underflowBin);this.allBins.push.apply(this.allBins,this.centralBins);this.allBins.push(this.overflowBin);this.allBins.forEach(function(bin){if(bin.count>this.maxCount_)
+this.maxCount_=bin.count;},this);}
+Numeric.fromDict=function(d){var range=Range.fromExplicitRange(d.min,d.max);var binInfo={};binInfo.underflowBin=NumericBin.fromDict(undefined,d.underflowBin);binInfo.centralBins=d.centralBins.map(function(binAsDict){return NumericBin.fromDict(undefined,binAsDict);});binInfo.centralBinWidth=d.centralBinWidth;binInfo.overflowBin=NumericBin.fromDict(undefined,d.overflowBin);var n=new Numeric(tr.v.Unit.fromJSON(d.unit),range,binInfo);n.allBins.forEach(function(bin){bin.parentNumeric=n;});n.runningSum=d.runningSum;n.numNans=d.numNans;n.nanSourceInfos=d.nanSourceInfos;return n;};Numeric.createLinear=function(unit,range,numBins){if(range.isEmpty)
+throw new Error('Nope');var binInfo={};binInfo.underflowBin=new NumericBin(this,Range.fromExplicitRange(-Number.MAX_VALUE,range.min));binInfo.overflowBin=new NumericBin(this,Range.fromExplicitRange(range.max,Number.MAX_VALUE));binInfo.centralBins=[];binInfo.centralBinWidth=range.range/numBins;for(var i=0;i<numBins;i++){var lo=range.min+(binInfo.centralBinWidth*i);var hi=lo+binInfo.centralBinWidth;binInfo.centralBins.push(new NumericBin(undefined,Range.fromExplicitRange(lo,hi)));}
+var n=new Numeric(unit,range,binInfo);n.allBins.forEach(function(bin){bin.parentNumeric=n;});return n;};Numeric.prototype={__proto__:NumericBase.prototype,get numValues(){return tr.b.Statistics.sum(this.allBins,function(e){return e.count;});},get average(){return this.runningSum/this.numValues;},get maxCount(){return this.maxCount_;},getInterpolatedCountAt:function(value){var bin=this.getBinForValue(value);var idx=this.centralBins.indexOf(bin);if(idx<0){return bin.count;}
+var lesserBin=bin;var greaterBin=bin;var lesserBinCenter=undefined;var greaterBinCenter=undefined;if(value<greaterBin.range.center){if(idx>0){lesserBin=this.centralBins[idx-1];}else{lesserBin=this.underflowBin;lesserBinCenter=lesserBin.range.max;}}else{if(idx<(this.centralBins.length-1)){greaterBin=this.centralBins[idx+1];}else{greaterBin=this.overflowBin;greaterBinCenter=greaterBin.range.min;}}
+if(greaterBinCenter===undefined)
+greaterBinCenter=greaterBin.range.center;if(lesserBinCenter===undefined)
+lesserBinCenter=lesserBin.range.center;value=tr.b.normalize(value,lesserBinCenter,greaterBinCenter);return tr.b.lerp(value,lesserBin.count,greaterBin.count);},getBinForValue:function(value){if(value<this.range.min)
+return this.underflowBin;if(value>=this.range.max)
+return this.overflowBin;var binIdx=Math.floor((value-this.range.min)/this.centralBinWidth);return this.centralBins[binIdx];},add:function(value,sourceInfo){if(typeof(value)!=='number'||isNaN(value)){this.numNans++;tr.b.Statistics.uniformlySampleStream(this.nanSourceInfos,this.numNans,sourceInfo,MAX_SOURCE_INFOS);return;}
+var bin=this.getBinForValue(value);bin.add(value,sourceInfo);this.runningSum+=value;if(bin.count>this.maxCount_)
+this.maxCount_=bin.count;},addNumeric:function(other){if(!this.range.equals(other.range)||!this.unit===other.unit||this.allBins.length!==other.allBins.length){throw new Error('Merging incompatible Numerics.');}
+tr.b.Statistics.mergeSampledStreams(this.nanSourceInfos,this.numNans,other.nanSourceInfos,other.numNans,MAX_SOURCE_INFOS);this.numNans+=other.numNans;this.runningSum+=other.runningSum;for(var i=0;i<this.allBins.length;++i){this.allBins[i].addBin(other.allBins[i]);}},clone:function(){return Numeric.fromDict(this.asDict());},asDict:function(){var d={unit:this.unit.asJSON(),min:this.range.min,max:this.range.max,numNans:this.numNans,nanSourceInfos:this.nanSourceInfos,runningSum:this.runningSum,underflowBin:this.underflowBin.asDict(),centralBins:this.centralBins.map(function(bin){return bin.asDict();}),centralBinWidth:this.centralBinWidth,overflowBin:this.overflowBin.asDict()};return d;},asJSON:function(){return this.asDict();}};function ScalarNumeric(unit,value){if(!(typeof(value)=='number'))
+throw new Error('Expected value to be number');NumericBase.call(this,unit);this.value=value;}
+ScalarNumeric.prototype={__proto__:NumericBase.prototype,asDictInto_:function(d){d.type='scalar';d.value=this.value;},toString:function(){return this.unit.format(this.value);}};ScalarNumeric.fromDict=function(d){return new ScalarNumeric(tr.v.Unit.fromJSON(d.unit),d.value);};return{NumericBase:NumericBase,NumericBin:NumericBin,Numeric:Numeric,ScalarNumeric:ScalarNumeric};});'use strict';tr.exportTo('tr.e.audits',function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var Auditor=tr.c.Auditor;var AndroidModelHelper=tr.model.helpers.AndroidModelHelper;var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS=tr.model.FRAME_PERF_CLASS;var Alert=tr.model.Alert;var EventInfo=tr.model.EventInfo;var ScalarNumeric=tr.v.ScalarNumeric;var timeDurationInMs=tr.v.Unit.byName.timeDurationInMs;var EXPECTED_FRAME_TIME_MS=16.67;function getStart(e){return e.start;}
+function getDuration(e){return e.duration;}
+function getCpuDuration(e){return(e.cpuDuration!==undefined)?e.cpuDuration:e.duration;}
+function frameIsActivityStart(frame){for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='activityStart')
+return true;}
+return false;}
+function frameMissedDeadline(frame){return frame.args['deadline']&&frame.args['deadline']<frame.end;}
+function DocLinkBuilder(){this.docLinks=[];}
+DocLinkBuilder.prototype={addAppVideo:function(name,videoId){this.docLinks.push({label:'Video Link',textContent:('Android Performance Patterns: '+name),href:'https://www.youtube.com/watch?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&v='+videoId});return this;},addDacRef:function(name,link){this.docLinks.push({label:'Doc Link',textContent:(name+' documentation'),href:'https://developer.android.com/reference/'+link});return this;},build:function(){return this.docLinks;}};function AndroidAuditor(model){Auditor.call(this,model);var helper=model.getOrCreateHelper(AndroidModelHelper);if(helper.apps.length||helper.surfaceFlinger)
+this.helper=helper;};AndroidAuditor.viewAlphaAlertInfo_=new EventInfo('Inefficient View alpha usage','Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('View#setAlpha()','android/view/View.html#setAlpha(float)').build());AndroidAuditor.saveLayerAlertInfo_=new EventInfo('Expensive rendering with Canvas#saveLayer()','Canvas#saveLayer() incurs extremely high rendering cost. They disrupt the rendering pipeline when drawn, forcing a flush of drawing content. Instead use View hardware layers, or static Bitmaps. This enables the offscreen buffers to be reused in between frames, and avoids the disruptive render target switch.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('Canvas#saveLayerAlpha()','android/graphics/Canvas.html#saveLayerAlpha(android.graphics.RectF, int, int)').build());AndroidAuditor.getSaveLayerAlerts_=function(frame){var badAlphaRegEx=/^(.+) alpha caused (unclipped )?saveLayer (\d+)x(\d+)$/;var saveLayerRegEx=/^(unclipped )?saveLayer (\d+)x(\d+)$/;var ret=[];var events=[];frame.associatedEvents.forEach(function(slice){var match=badAlphaRegEx.exec(slice.title);if(match){var args={'view name':match[1],width:parseInt(match[3]),height:parseInt(match[4])};ret.push(new Alert(AndroidAuditor.viewAlphaAlertInfo_,slice.start,[slice],args));}else if(saveLayerRegEx.test(slice.title))
+events.push(slice);},this);if(events.length>ret.length){var unclippedSeen=Statistics.sum(events,function(slice){return saveLayerRegEx.exec(slice.title)[1]?1:0;});var clippedSeen=events.length-unclippedSeen;var earliestStart=Statistics.min(events,function(slice){return slice.start;});var args={'Unclipped saveLayer count (especially bad!)':unclippedSeen,'Clipped saveLayer count':clippedSeen};events.push(frame);ret.push(new Alert(AndroidAuditor.saveLayerAlertInfo_,earliestStart,events,args));}
+return ret;};AndroidAuditor.pathAlertInfo_=new EventInfo('Path texture churn','Paths are drawn with a mask texture, so when a path is modified / newly drawn, that texture must be generated and uploaded to the GPU. Ensure that you cache paths between frames and do not unnecessarily call Path#reset(). You can cut down on this cost by sharing Path object instances between drawables/views.');AndroidAuditor.getPathAlert_=function(frame){var uploadRegEx=/^Generate Path Texture$/;var events=frame.associatedEvents.filter(function(event){return event.title=='Generate Path Texture';});var start=Statistics.min(events,getStart);var duration=Statistics.sum(events,getDuration);if(duration<3)
+return undefined;events.push(frame);return new Alert(AndroidAuditor.pathAlertInfo_,start,events,{'Time spent':new ScalarNumeric(timeDurationInMs,duration)});};AndroidAuditor.uploadAlertInfo_=new EventInfo('Expensive Bitmap uploads','Bitmaps that have been modified / newly drawn must be uploaded to the GPU. Since this is expensive if the total number of pixels uploaded is large, reduce the amount of Bitmap churn in this animation/context, per frame.');AndroidAuditor.getUploadAlert_=function(frame){var uploadRegEx=/^Upload (\d+)x(\d+) Texture$/;var events=[];var start=Number.POSITIVE_INFINITY;var duration=0;var pixelsUploaded=0;frame.associatedEvents.forEach(function(event){var match=uploadRegEx.exec(event.title);if(match){events.push(event);start=Math.min(start,event.start);duration+=event.duration;pixelsUploaded+=parseInt(match[1])*parseInt(match[2]);}});if(events.length==0||duration<3)
+return undefined;var mPixels=(pixelsUploaded/1000000).toFixed(2)+' million';var args={'Pixels uploaded':mPixels,'Time spent':new ScalarNumeric(timeDurationInMs,duration)};events.push(frame);return new Alert(AndroidAuditor.uploadAlertInfo_,start,events,args);};AndroidAuditor.ListViewInflateAlertInfo_=new EventInfo('Inflation during ListView recycling','ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.');AndroidAuditor.ListViewBindAlertInfo_=new EventInfo('Inefficient ListView recycling/rebinding','ListView recycling taking too much time per frame. Ensure your Adapter#getView() binds data efficiently.');AndroidAuditor.getListViewAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='obtainView'||event.title=='setupListItem';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
+return undefined;var hasInflation=false;for(var i=0;i<events.length;i++){if(events[i]instanceof tr.model.Slice&&events[i].findDescendentSlice('inflate')){hasInflation=true;break;}}
+var start=Statistics.min(events,getStart);var args={'Time spent':new ScalarNumeric(timeDurationInMs,duration)};args['ListView items '+(hasInflation?'inflated':'rebound')]=events.length/2;var eventInfo=hasInflation?AndroidAuditor.ListViewInflateAlertInfo_:AndroidAuditor.ListViewBindAlertInfo_;events.push(frame);return new Alert(eventInfo,start,events,args);};AndroidAuditor.measureLayoutAlertInfo_=new EventInfo('Expensive measure/layout pass','Measure/Layout took a significant time, contributing to jank. Avoid triggering layout during animations.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').build());AndroidAuditor.getMeasureLayoutAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='measure'||event.title=='layout';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
+return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.measureLayoutAlertInfo_,start,events,{'Time spent':new ScalarNumeric(timeDurationInMs,duration)});};AndroidAuditor.viewDrawAlertInfo_=new EventInfo('Long View#draw()','Recording the drawing commands of invalidated Views took a long time. Avoid significant work in View or Drawable custom drawing, especially allocations or drawing to Bitmaps.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getViewDrawAlert_=function(frame){var slice=undefined;for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='getDisplayList'||frame.associatedEvents[i].title=='Record View#draw()'){slice=frame.associatedEvents[i];break;}}
+if(!slice||getCpuDuration(slice)<3)
+return undefined;return new Alert(AndroidAuditor.viewDrawAlertInfo_,slice.start,[slice,frame],{'Time spent':new ScalarNumeric(timeDurationInMs,getCpuDuration(slice))});};AndroidAuditor.blockingGcAlertInfo_=new EventInfo('Blocking Garbage Collection','Blocking GCs are caused by object churn, and made worse by having large numbers of objects in the heap. Avoid allocating objects during animations/scrolling, and recycle Bitmaps to avoid triggering garbage collection.',new DocLinkBuilder().addAppVideo('Garbage Collection in Android','pzfzz50W5Uo').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getBlockingGcAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='DVM Suspend'||event.title=='GC: Wait For Concurrent';});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<3)
+return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.blockingGcAlertInfo_,start,events,{'Blocked duration':new ScalarNumeric(timeDurationInMs,blockedDuration)});};AndroidAuditor.lockContentionAlertInfo_=new EventInfo('Lock contention','UI thread lock contention is caused when another thread holds a lock that the UI thread is trying to use. UI thread progress is blocked until the lock is released. Inspect locking done within the UI thread, and ensure critical sections are short.');AndroidAuditor.getLockContentionAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return/^Lock Contention on /.test(event.title);});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<1)
+return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.lockContentionAlertInfo_,start,events,{'Blocked duration':new ScalarNumeric(timeDurationInMs,blockedDuration)});};AndroidAuditor.schedulingAlertInfo_=new EventInfo('Scheduling delay','Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn\'t block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.');AndroidAuditor.getSchedulingAlert_=function(frame){var totalDuration=0;var totalStats={};frame.threadTimeRanges.forEach(function(ttr){var stats=ttr.thread.getSchedulingStatsForRange(ttr.start,ttr.end);tr.b.iterItems(stats,function(key,value){if(!(key in totalStats))
+totalStats[key]=0;totalStats[key]+=value;totalDuration+=value;});});if(!(SCHEDULING_STATE.RUNNING in totalStats)||totalDuration==0||totalDuration-totalStats[SCHEDULING_STATE.RUNNING]<3)
+return;var args={};tr.b.iterItems(totalStats,function(key,value){if(key===SCHEDULING_STATE.RUNNABLE)
+key='Not scheduled, but runnable';else if(key===SCHEDULING_STATE.UNINTR_SLEEP)
+key='Blocking I/O delay';args[key]=new ScalarNumeric(timeDurationInMs,value);});return new Alert(AndroidAuditor.schedulingAlertInfo_,frame.start,[frame],args);};AndroidAuditor.prototype={__proto__:Auditor.prototype,renameAndSort_:function(){this.model.kernel.important=false;this.model.getAllProcesses().forEach(function(process){if(this.helper.surfaceFlinger&&process==this.helper.surfaceFlinger.process){if(!process.name)
+process.name='SurfaceFlinger';process.sortIndex=Number.NEGATIVE_INFINITY;process.important=false;return;}
+var uiThread=process.getThread(process.pid);if(!process.name&&uiThread&&uiThread.name){if(/^ndroid\./.test(uiThread.name))
+uiThread.name='a'+uiThread.name;process.name=uiThread.name;uiThread.name='UI Thread';}
+process.sortIndex=0;for(var tid in process.threads){process.sortIndex-=process.threads[tid].sliceGroup.slices.length;}},this);this.model.getAllThreads().forEach(function(thread){if(thread.tid==thread.parent.pid)
+thread.sortIndex=-3;if(thread.name=='RenderThread')
+thread.sortIndex=-2;if(/^hwuiTask/.test(thread.name))
+thread.sortIndex=-1;});},pushFramesAndJudgeJank_:function(){var badFramesObserved=0;var framesObserved=0;var surfaceFlinger=this.helper.surfaceFlinger;this.helper.apps.forEach(function(app){app.process.frames=app.getFrames();app.process.frames.forEach(function(frame){if(frame.totalDuration>EXPECTED_FRAME_TIME_MS*2){badFramesObserved+=2;frame.perfClass=FRAME_PERF_CLASS.TERRIBLE;}else if(frame.totalDuration>EXPECTED_FRAME_TIME_MS||frameMissedDeadline(frame)){badFramesObserved++;frame.perfClass=FRAME_PERF_CLASS.BAD;}else{frame.perfClass=FRAME_PERF_CLASS.GOOD;}});framesObserved+=app.process.frames.length;});if(framesObserved){var portionBad=badFramesObserved/framesObserved;if(portionBad>0.3)
+this.model.faviconHue='red';else if(portionBad>0.05)
+this.model.faviconHue='yellow';else
+this.model.faviconHue='green';}},pushEventInfo_:function(){var appAnnotator=new AppAnnotator();this.helper.apps.forEach(function(app){if(app.uiThread)
+appAnnotator.applyEventInfos(app.uiThread.sliceGroup);if(app.renderThread)
+appAnnotator.applyEventInfos(app.renderThread.sliceGroup);});},runAnnotate:function(){if(!this.helper)
+return;this.renameAndSort_();this.pushFramesAndJudgeJank_();this.pushEventInfo_();this.helper.iterateImportantSlices(function(slice){slice.important=true;});},runAudit:function(){if(!this.helper)
+return;var alerts=this.model.alerts;this.helper.apps.forEach(function(app){app.getFrames().forEach(function(frame){alerts.push.apply(alerts,AndroidAuditor.getSaveLayerAlerts_(frame));if(frame.perfClass==FRAME_PERF_CLASS.NEUTRAL||frame.perfClass==FRAME_PERF_CLASS.GOOD)
+return;var alert=AndroidAuditor.getPathAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getUploadAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getListViewAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getMeasureLayoutAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getViewDrawAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getBlockingGcAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getLockContentionAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getSchedulingAlert_(frame);if(alert)
+alerts.push(alert);});},this);this.addRenderingInteractionRecords();this.addInputInteractionRecords();},addRenderingInteractionRecords:function(){var events=[];this.helper.apps.forEach(function(app){events.push.apply(events,app.getAnimationAsyncSlices());events.push.apply(events,app.getFrames());});var mergerFunction=function(events){var ir=new tr.model.um.ResponseExpectation(this.model,'Rendering',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);tr.b.mergeRanges(tr.b.convertEventsToRanges(events),30,mergerFunction);},addInputInteractionRecords:function(){var inputSamples=[];this.helper.apps.forEach(function(app){inputSamples.push.apply(inputSamples,app.getInputSamples());});var mergerFunction=function(events){var ir=new tr.model.um.ResponseExpectation(this.model,'Input',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);var inputRanges=inputSamples.map(function(sample){return tr.b.Range.fromExplicitRange(sample.timestamp,sample.timestamp);});tr.b.mergeRanges(inputRanges,30,mergerFunction);}};Auditor.register(AndroidAuditor);function AppAnnotator(){this.titleInfoLookup={};this.titleParentLookup={};this.build_();}
+AppAnnotator.prototype={build_:function(){var registerEventInfo=function(dict){this.titleInfoLookup[dict.title]=new EventInfo(dict.title,dict.description,dict.docLinks);if(dict.parents)
+this.titleParentLookup[dict.title]=dict.parents;}.bind(this);registerEventInfo({title:'inflate',description:'Constructing a View hierarchy from pre-processed XML via LayoutInflater#layout. This includes constructing all of the View objects in the hierarchy, and applying styled attributes.'});registerEventInfo({title:'obtainView',description:'Adapter#getView() called to bind content to a recycled View that is being presented.'});registerEventInfo({title:'setupListItem',description:'Attached a newly-bound, recycled View to its parent ListView.'});registerEventInfo({title:'setupGridItem',description:'Attached a newly-bound, recycled View to its parent GridView.'});var choreographerLinks=new DocLinkBuilder().addDacRef('Choreographer','android/view/Choreographer.html').build();registerEventInfo({title:'Choreographer#doFrame',docLinks:choreographerLinks,description:'Choreographer executes frame callbacks for inputs, animations, and rendering traversals. When this work is done, a frame will be presented to the user.'});registerEventInfo({title:'input',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Input callbacks are processed. This generally encompasses dispatching input to Views, as well as any work the Views do to process this input/gesture.'});registerEventInfo({title:'animation',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Animation callbacks are processed. This is generally minimal work, as animations determine progress for the frame, and push new state to animated objects (such as setting View properties).'});registerEventInfo({title:'traversals',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Primary draw traversals. This is the primary traversal of the View hierarchy, including layout and draw passes.'});var traversalParents=['Choreographer#doFrame','performTraversals'];var layoutLinks=new DocLinkBuilder().addDacRef('View#Layout','android/view/View.html#Layout').build();registerEventInfo({title:'performTraversals',description:'A drawing traversal of the View hierarchy, comprised of all layout and drawing needed to produce the frame.'});registerEventInfo({title:'measure',parents:traversalParents,docLinks:layoutLinks,description:'First of two phases in view hierarchy layout. Views are asked to size themselves according to constraints supplied by their parent. Some ViewGroups may measure a child more than once to help satisfy their own constraints. Nesting ViewGroups that measure children more than once can lead to excessive and repeated work.'});registerEventInfo({title:'layout',parents:traversalParents,docLinks:layoutLinks,description:'Second of two phases in view hierarchy layout, repositioning content and child Views into their new locations.'});var drawString='Draw pass over the View hierarchy. Every invalidated View will have its drawing commands recorded. On Android versions prior to Lollipop, this would also include the issuing of draw commands to the GPU. Starting with Lollipop, it only includes the recording of commands, and syncing that information to the RenderThread.';registerEventInfo({title:'draw',parents:traversalParents,description:drawString});var recordString='Every invalidated View\'s drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded.';registerEventInfo({title:'getDisplayList',parents:['draw'],description:recordString});registerEventInfo({title:'Record View#draw()',parents:['draw'],description:recordString});registerEventInfo({title:'drawDisplayList',parents:['draw'],description:'Execution of recorded draw commands to generate a frame. This represents the actual formation and issuing of drawing commands to the GPU. On Android L and higher devices, this work is done on a dedicated RenderThread, instead of on the UI Thread.'});registerEventInfo({title:'DrawFrame',description:'RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.'});registerEventInfo({title:'doFrame',description:'RenderThread animation frame. Represents drawing work done by the RenderThread on a frame where the UI thread did not produce new drawing content.'});registerEventInfo({title:'syncFrameState',description:'Sync stage between the UI thread and the RenderThread, where the UI thread hands off a frame (including information about modified Views). Time in this method primarily consists of uploading modified Bitmaps to the GPU. After this sync is completed, the UI thread is unblocked, and the RenderThread starts to render the frame.'});registerEventInfo({title:'flush drawing commands',description:'Issuing the now complete drawing commands to the GPU.'});registerEventInfo({title:'eglSwapBuffers',description:'Complete GPU rendering of the frame.'});registerEventInfo({title:'RV Scroll',description:'RecyclerView is calculating a scroll. If there are too many of these in Systrace, some Views inside RecyclerView might be causing it. Try to avoid using EditText, focusable views or handle them with care.'});registerEventInfo({title:'RV OnLayout',description:'OnLayout has been called by the View system. If this shows up too many times in Systrace, make sure the children of RecyclerView do not update themselves directly. This will cause a full re-layout but when it happens via the Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.'});registerEventInfo({title:'RV FullInvalidate',description:'NotifyDataSetChanged or equal has been called. If this is taking a long time, try sending granular notify adapter changes instead of just calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter might help.'});registerEventInfo({title:'RV PartialInvalidate',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV OnBindView',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV CreateView',description:'RecyclerView is creating a new View. If too many of these are present: 1) There might be a problem in Recycling (e.g. custom Animations that set transient state and prevent recycling or ItemAnimator not implementing the contract properly. See Adapter#onFailedToRecycleView(ViewHolder). 2) There may be too many item view types. Try merging them. 3) There might be too many itemChange animations and not enough space in RecyclerPool. Try increasing your pool size and item cache size.'});registerEventInfo({title:'eglSwapBuffers',description:'The CPU has finished producing drawing commands, and is flushing drawing work to the GPU, and posting that buffer to the consumer (which is often SurfaceFlinger window composition). Once this is completed, the GPU can produce the frame content without any involvement from the CPU.'});},applyEventInfosRecursive_:function(parentNames,slice){var checkExpectedParentNames=function(expectedParentNames){if(!expectedParentNames)
+return true;return expectedParentNames.some(function(name){return name in parentNames;});};if(slice.title in this.titleInfoLookup){if(checkExpectedParentNames(this.titleParentLookup[slice.title]))
+slice.info=this.titleInfoLookup[slice.title];}
+if(slice.subSlices.length>0){if(!(slice.title in parentNames))
+parentNames[slice.title]=0;parentNames[slice.title]++;slice.subSlices.forEach(function(subSlice){this.applyEventInfosRecursive_(parentNames,subSlice);},this);parentNames[slice.title]--;if(parentNames[slice.title]==0)
+delete parentNames[slice.title];}},applyEventInfos:function(sliceGroup){sliceGroup.topLevelSlices.forEach(function(slice){this.applyEventInfosRecursive_({},slice);},this);}};return{AndroidAuditor:AndroidAuditor};});'use strict';tr.exportTo('tr.model.helpers',function(){var MAIN_FRAMETIME_TYPE='main_frametime_type';var IMPL_FRAMETIME_TYPE='impl_frametime_type';var MAIN_RENDERING_STATS='BenchmarkInstrumentation::MainThreadRenderingStats';var IMPL_RENDERING_STATS='BenchmarkInstrumentation::ImplThreadRenderingStats';function getSlicesIntersectingRange(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end))
+slicesInFilterRange.push(slice);}
+return slicesInFilterRange;}
+function ChromeProcessHelper(modelHelper,process){this.modelHelper=modelHelper;this.process=process;}
+ChromeProcessHelper.prototype={get pid(){return this.process.pid;},getFrameEventsInRange:function(frametimeType,range){var titleToGet;if(frametimeType==MAIN_FRAMETIME_TYPE)
+titleToGet=MAIN_RENDERING_STATS;else
+titleToGet=IMPL_RENDERING_STATS;var frameEvents=[];this.process.iterateAllEvents(function(event){if(event.title!==titleToGet)
+return;if(range.intersectsExplicitRangeInclusive(event.start,event.end))
+frameEvents.push(event);});frameEvents.sort(function(a,b){return a.start-b.start});return frameEvents;}};function getFrametimeDataFromEvents(frameEvents){var frametimeData=[];for(var i=1;i<frameEvents.length;i++){var diff=frameEvents[i].start-frameEvents[i-1].start;frametimeData.push({'x':frameEvents[i].start,'frametime':diff});}
+return frametimeData;}
+return{ChromeProcessHelper:ChromeProcessHelper,MAIN_FRAMETIME_TYPE:MAIN_FRAMETIME_TYPE,IMPL_FRAMETIME_TYPE:IMPL_FRAMETIME_TYPE,MAIN_RENDERING_STATS:MAIN_RENDERING_STATS,IMPL_RENDERING_STATS:IMPL_RENDERING_STATS,getSlicesIntersectingRange:getSlicesIntersectingRange,getFrametimeDataFromEvents:getFrametimeDataFromEvents};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeBrowserHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrBrowserMain');}
+ChromeBrowserHelper.isBrowserProcess=function(process){return!!process.findAtMostOneThreadNamed('CrBrowserMain');};ChromeBrowserHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get rendererHelpers(){return this.modelHelper.rendererHelpers;},getLoadingEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title.indexOf('WebContentsImpl Loading')===0&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getCommitProvisionalLoadEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title==='RenderFrameImpl::didCommitProvisionalLoad'&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},get hasLatencyEvents(){var hasLatency=false;this.modelHelper.model.getAllThreads().some(function(thread){thread.iterateAllEvents(function(event){if(!event.isTopLevel)
+return;if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice))
+return;hasLatency=true;});return hasLatency;});return hasLatency;},getLatencyEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return(slice.title.indexOf('InputLatency')===0)&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getAllAsyncSlicesMatching:function(pred,opt_this){var events=[];this.iterAllThreads(function(thread){thread.iterateAllEvents(function(slice){if(pred.call(opt_this,slice))
+events.push(slice);});});return events;},getAllNetworkEventsInRange:function(rangeOfInterest){var networkEvents=[];this.modelHelper.model.getAllThreads().forEach(function(thread){thread.asyncSliceGroup.slices.forEach(function(slice){var match=false;if(slice.category=='net'||slice.category=='disabled-by-default-netlog'||slice.category=='netlog'){match=true;}
+if(!match)
+return;if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end))
+networkEvents.push(slice);});});return networkEvents;},iterAllThreads:function(func,opt_this){tr.b.iterItems(this.process.threads,function(tid,thread){func.call(opt_this,thread);});tr.b.iterItems(this.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;tr.b.iterItems(rendererProcess.threads,function(tid,thread){func.call(opt_this,thread);});},this);}};return{ChromeBrowserHelper:ChromeBrowserHelper};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeGpuHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.isGpuProcess=function(process){if(process.findAtMostOneThreadNamed('CrBrowserMain')||process.findAtMostOneThreadNamed('CrRendererMain'))
+return false;return process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;}};return{ChromeGpuHelper:ChromeGpuHelper};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeRendererHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)
+return false;if(t.name.indexOf('CompositorTileWorker')===0)
+return true;if(t.name.indexOf('CompositorRasterWorker')===0)
+return true;return false;});};ChromeRendererHelper.isRenderProcess=function(process){if(!process.findAtMostOneThreadNamed('CrRendererMain'))
+return false;if(!process.findAtMostOneThreadNamed('Compositor'))
+return false;return true;};ChromeRendererHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;}};return{ChromeRendererHelper:ChromeRendererHelper};});'use strict';tr.exportTo('tr.model.helpers',function(){function findChromeBrowserProcess(model){var browserProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.model.helpers.ChromeBrowserHelper.isBrowserProcess(process))
+return;browserProcesses.push(process);},this);if(browserProcesses.length===0)
+return undefined;if(browserProcesses.length>1)
+return undefined;return browserProcesses[0];}
+function findChromeRenderProcesses(model){var rendererProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.model.helpers.ChromeRendererHelper.isRenderProcess(process))
+return;rendererProcesses.push(process);});return rendererProcesses;}
+function findChromeGpuProcess(model){var gpuProcesses=model.getAllProcesses().filter(tr.model.helpers.ChromeGpuHelper.isGpuProcess);if(gpuProcesses.length!=1)
+return undefined;return gpuProcesses[0];}
+function ChromeModelHelper(model){this.model_=model;this.browserProcess_=findChromeBrowserProcess(model);if(this.browserProcess_){this.browserHelper_=new tr.model.helpers.ChromeBrowserHelper(this,this.browserProcess_);}else{this.browserHelper_=undefined;}
+var gpuProcess=findChromeGpuProcess(model);if(gpuProcess){this.gpuHelper_=new tr.model.helpers.ChromeGpuHelper(this,gpuProcess);}else{this.gpuHelper_=undefined;}
+var rendererProcesses_=findChromeRenderProcesses(model);this.rendererHelpers_={};rendererProcesses_.forEach(function(renderProcess){var rendererHelper=new tr.model.helpers.ChromeRendererHelper(this,renderProcess);this.rendererHelpers_[rendererHelper.pid]=rendererHelper;},this);}
+ChromeModelHelper.guid=tr.b.GUID.allocate();ChromeModelHelper.supportsModel=function(model){if(findChromeBrowserProcess(model)!==undefined)
+return true;if(findChromeRenderProcesses(model).length)
+return true;return false;};ChromeModelHelper.prototype={get pid(){throw new Error('woah');},get process(){throw new Error('woah');},get model(){return this.model_;},get browserProcess(){return this.browserProcess_;},get browserHelper(){return this.browserHelper_;},get gpuHelper(){return this.gpuHelper_;},get rendererHelpers(){return this.rendererHelpers_;}};return{ChromeModelHelper:ChromeModelHelper};});'use strict';tr.exportTo('tr.model',function(){function AsyncSlice(category,title,colorId,start,args,duration,opt_isTopLevel,opt_cpuStart,opt_cpuDuration,opt_argsStripped){tr.model.TimedEvent.call(this,start);this.category=category||'';this.originalTitle=title;this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.important=false;this.subSlices=[];this.parentContainer_=undefined;this.id=undefined;this.startThread=undefined;this.endThread=undefined;this.cpuStart=undefined;this.cpuDuration=undefined;this.argsStripped=false;this.startStackFrame=undefined;this.endStackFrame=undefined;this.duration=duration;this.isTopLevel=(opt_isTopLevel===true);if(opt_cpuStart!==undefined)
+this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
+this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
+this.argsStripped=opt_argsStripped;};AsyncSlice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get parentContainer(){return this.parentContainer_;},set parentContainer(parentContainer){this.parentContainer_=parentContainer;for(var i=0;i<this.subSlices.length;i++){var subSlice=this.subSlices[i];if(subSlice.parentContainer===undefined)
+subSlice.parentContainer=parentContainer;}},get viewSubGroupTitle(){return this.title;},get userFriendlyName(){return'Async slice '+this.title+' at '+
+tr.v.Unit.byName.timeStampInMs.format(this.start);},get stableId(){var parentAsyncSliceGroup=this.parentContainer.asyncSliceGroup;return parentAsyncSliceGroup.stableId+'.'+
+parentAsyncSliceGroup.slices.indexOf(this);},findDescendentSlice:function(targetTitle){if(!this.subSlices)
+return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
+return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},compareTo:function(that){return this.title.localeCompare(that.title);}};tr.model.EventRegistry.register(AsyncSlice,{name:'asyncSlice',pluralName:'asyncSlices',singleViewElementName:'tr-ui-a-single-async-slice-sub-view',multiViewElementName:'tr-ui-a-multi-async-slice-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=AsyncSlice;options.defaultConstructor=AsyncSlice;tr.b.decorateExtensionRegistry(AsyncSlice,options);return{AsyncSlice:AsyncSlice};});'use strict';tr.exportTo('tr.e.cc',function(){var AsyncSlice=tr.model.AsyncSlice;var EventSet=tr.model.EventSet;var UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';var ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';var BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';var END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';var MAIN_RENDERER_THREAD_NAME='CrRendererMain';var COMPOSITOR_THREAD_NAME='Compositor';var POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';var IPC_FLOW_EVENT='disabled-by-default-ipc.flow';var INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent)
+this.determineModernTypeName_();}
+InputLatencyAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get isLegacyEvent(){return this.title==='InputLatency';},get typeName(){if(!this.typeName_)
+this.determineLegacyTypeName_();return this.typeName_;},checkTypeName_:function(){if(!this.typeName_)
+throw'Unable to determine typeName';var found=false;for(var type_name in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[type_name]){found=true;break;}}
+if(!found)
+this.typeName_=INPUT_EVENT_TYPE_NAMES.UNKNOWN;},determineModernTypeName_:function(){var lastColonIndex=this.title.lastIndexOf(':');if(lastColonIndex<0)
+return;var characterAfterLastColonIndex=lastColonIndex+1;this.typeName_=this.title.slice(characterAfterLastColonIndex);this.checkTypeName_();},determineLegacyTypeName_:function(){this.iterateAllDescendents(function(subSlice){var subSliceIsAInputLatencyAsyncSlice=(subSlice instanceof InputLatencyAsyncSlice);if(!subSliceIsAInputLatencyAsyncSlice)
+return;if(!subSlice.typeName)
+return;if(this.typeName_&&subSlice.typeName_){var subSliceHasDifferentTypeName=(this.typeName_!==subSlice.typeName_);if(subSliceHasDifferentTypeName){throw'InputLatencyAsyncSlice.determineLegacyTypeName_() '+' found multiple typeNames';}}
+this.typeName_=subSlice.typeName_;},this);if(!this.typeName_)
+throw'InputLatencyAsyncSlice.determineLegacyTypeName_() failed';this.checkTypeName_();},getRendererHelper:function(sourceSlices){var traceModel=this.startThread.parent.model;var modelHelper=traceModel.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper)
+return undefined;var mainThread=undefined;var compositorThread=undefined;for(var i in sourceSlices){if(sourceSlices[i].parentContainer.name===MAIN_RENDERER_THREAD_NAME)
+mainThread=sourceSlices[i].parentContainer;else if(sourceSlices[i].parentContainer.name===COMPOSITOR_THREAD_NAME)
+compositorThread=sourceSlices[i].parentContainer;if(mainThread&&compositorThread)
+break;}
+var rendererHelpers=modelHelper.rendererHelpers;var pids=Object.keys(rendererHelpers);for(var i=0;i<pids.length;i++){var pid=pids[i];var rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread)
+return rendererHelper;}
+return undefined;},addEntireSliceHierarchy:function(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents:function(flowEvents){var slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);var newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1)
+slices.push(newSource);},this);var lastFlowEvent=flowEvents[flowEvents.length-1];var lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1)
+slices.push(lastSource);return slices;},addScrollUpdateEvents:function(rendererHelper){if(!rendererHelper||!rendererHelper.compositorThread)
+return;var compositorThread=rendererHelper.compositorThread;var gestureScrollUpdateStart=this.start;var gestureScrollUpdateEnd=this.end;var allCompositorAsyncSlices=compositorThread.asyncSliceGroup.slices;for(var i in allCompositorAsyncSlices){var slice=allCompositorAsyncSlices[i];if(slice.title!=='Latency::ScrollUpdate')
+continue;var parentId=slice.args.data.INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.sequence_number;if(parentId===undefined){if(slice.start<gestureScrollUpdateStart||slice.start>=gestureScrollUpdateEnd)
+continue;}else{if(parseInt(parentId)!==parseInt(this.id))
+continue;}
+slice.associatedEvents.forEach(function(event){this.associatedEvents_.push(event);},this);break;}},belongToOtherInputs:function(slice,flowEvents){var fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)
+return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)
+return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1)
+fromOtherInputs=true;}},this);},this);return fromOtherInputs;},triggerOtherInputs:function(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0)
+return false;var flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice)
+return false;var endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents))
+return true;return false;},followSubsequentSlices:function(event,queue,visited,flowEvents){var stopFollowing=false;var inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)
+return;if(slice.title==='TaskQueueManager::RunTask')
+return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame')
+return;if(slice.title==='Scheduler::ScheduleBeginImplFrameDeadline'){if(this.triggerOtherInputs(slice,flowEvents))
+return;}
+if(slice.title==='CompositorImpl::PostComposite'){if(this.triggerOtherInputs(slice,flowEvents))
+return;}
+if(slice.title==='InputRouterImpl::ProcessInputEventAck')
+inputAck=true;if(inputAck&&slice.title==='InputRouterImpl::FilterAndSendWebInputEvent')
+stopFollowing=true;this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice:function(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);var nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw:function(beginImplFrame,visited){var pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){var nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices:function(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start)
+return a.start-b.start;return a.guid-b.guid;});},addRasterizationEvents:function(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)
+return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads)
+return;var rasterWorkerThreads=rendererHelper.rasterWorkerThreads;var prepare_tile_id=prepareTiles.args.prepare_tiles_id;var pendingEventQueue=[];if(sortedRasterizerSlices.length===0)
+this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);var numFinishedTasks=0;var RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';var IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';var FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(var i=0;i<sortedRasterizerSlices.length;i++){var task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepare_tile_id)
+this.addEntireSliceHierarchy(task.mostTopLevelSlice);}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)
+break;}}}
+while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followSubsequentSlices(event,pendingEventQueue,visited,flowEvents);}},addOtherCausallyRelatedEvents:function(rendererHelper,sourceSlices,flowEvents,sortedRasterizerSlices){var pendingEventQueue=[];var visitedEvents=new EventSet();var beginImplFrame=undefined;var prepareTiles=undefined;var sortedRasterizerSlices=[];sourceSlices.forEach(function(sourceSlice){if(!visitedEvents.contains(sourceSlice)){visitedEvents.push(sourceSlice);pendingEventQueue.push(sourceSlice);}},this);while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followCurrentSlice(event,pendingEventQueue,visitedEvents);this.followSubsequentSlices(event,pendingEventQueue,visitedEvents,flowEvents);var COMPOSITOR_PREPARE_TILES='TileManager::PrepareTiles';prepareTiles=event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);if(prepareTiles)
+this.addRasterizationEvents(prepareTiles,rendererHelper,visitedEvents,flowEvents,sortedRasterizerSlices);var COMPOSITOR_ON_BIFD='Scheduler::OnBeginImplFrameDeadline';beginImplFrame=event.findDescendentSlice(COMPOSITOR_ON_BIFD);if(beginImplFrame)
+this.backtraceFromDraw(beginImplFrame,visitedEvents);}
+var INPUT_GSU='InputLatency::GestureScrollUpdate';if(this.title===INPUT_GSU)
+this.addScrollUpdateEvents(rendererHelper);},get associatedEvents(){if(this.associatedEvents_.length!==0)
+return this.associatedEvents_;var modelIndices=this.startThread.parent.model.modelIndices;var flowEvents=modelIndices.getFlowEventsWithId(this.id);if(flowEvents.length===0)
+return this.associatedEvents_;var sourceSlices=this.addDirectlyAssociatedEvents(flowEvents);var rendererHelper=this.getRendererHelper(sourceSlices);this.addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents);return this.associatedEvents_;},get inputLatency(){if(!('data'in this.args))
+return undefined;var data=this.args.data;if(!(END_COMP_NAME in data))
+return undefined;var latency=0;var endTime=data[END_COMP_NAME].time;if(ORIGINAL_COMP_NAME in data){latency=endTime-data[ORIGINAL_COMP_NAME].time;}else if(UI_COMP_NAME in data){latency=endTime-data[UI_COMP_NAME].time;}else if(BEGIN_COMP_NAME in data){latency=endTime-data[BEGIN_COMP_NAME].time;}else{throw new Error('No valid begin latency component');}
+return latency;}};var eventTypeNames=['Char','ContextMenu','GestureClick','GestureFlingCancel','GestureFlingStart','GestureScrollBegin','GestureScrollEnd','GestureScrollUpdate','GestureShowPress','GestureTap','GestureTapCancel','GestureTapDown','GesturePinchBegin','GesturePinchEnd','GesturePinchUpdate','KeyDown','KeyUp','MouseDown','MouseEnter','MouseLeave','MouseMove','MouseUp','MouseWheel','RawKeyDown','ScrollUpdate','TouchCancel','TouchEnd','TouchMove','TouchStart'];var allTypeNames=['InputLatency'];eventTypeNames.forEach(function(eventTypeName){allTypeNames.push('InputLatency:'+eventTypeName);allTypeNames.push('InputLatency::'+eventTypeName);});AsyncSlice.register(InputLatencyAsyncSlice,{typeNames:allTypeNames,categoryParts:['latencyInfo']});return{InputLatencyAsyncSlice:InputLatencyAsyncSlice,INPUT_EVENT_TYPE_NAMES:INPUT_EVENT_TYPE_NAMES};});'use strict';tr.exportTo('tr.e.chrome',function(){var SAME_AS_PARENT='same-as-parent';var TITLES_FOR_USER_FRIENDLY_CATEGORY={composite:['CompositingInputsUpdater::update','ThreadProxy::SetNeedsUpdateLayers','LayerTreeHost::UpdateLayers::CalcDrawProps','UpdateLayerTree'],gc:['minorGC','majorGC','MajorGC','MinorGC','V8.GCScavenger','V8.GCIncrementalMarking','V8.GCIdleNotification','V8.GCContext','V8.GCCompactor','V8GCController::traceDOMWrappers'],iframe_creation:['WebLocalFrameImpl::createChildframe'],imageDecode:['Decode Image','ImageFrameGenerator::decode','ImageFrameGenerator::decodeAndScale'],input:['HitTest','ScrollableArea::scrollPositionChanged','EventHandler::handleMouseMoveEvent'],layout:['FrameView::invalidateTree','FrameView::layout','FrameView::performLayout','FrameView::performPostLayoutTasks','FrameView::performPreLayoutTasks','Layer::updateLayerPositionsAfterLayout','Layout','LayoutView::hitTest','ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities','WebViewImpl::layout'],parseHTML:['ParseHTML','HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser','HTMLDocumentParser::processParsedChunkFromBackgroundParser'],raster:['DisplayListRasterSource::PerformSolidColorAnalysis','Picture::Raster','RasterBufferImpl::Playback','RasterTask','RasterizerTaskImpl::RunOnWorkerThread','SkCanvas::drawImageRect()','SkCanvas::drawPicture()','SkCanvas::drawTextBlob()','TileTaskWorkerPool::PlaybackToMemory'],record:['ContentLayerDelegate::paintContents','DeprecatedPaintLayerCompositor::updateIfNeededRecursive','DeprecatedPaintLayerCompositor::updateLayerPositionsAfterLayout','Paint','Picture::Record','PictureLayer::Update','RenderLayer::updateLayerPositionsAfterLayout'],script:['EvaluateScript','FunctionCall','ScheduledAction::execute','Script','V8.Execute','v8.run','v8.callModuleMethod','v8.callFunction','WindowProxy::initialize'],style:['CSSParserImpl::parseStyleSheet.parse','CSSParserImpl::parseStyleSheet.tokenize','Document::updateStyle','Document::updateStyleInvalidationIfNeeded','ParseAuthorStyleSheet','RuleSet::addRulesFromSheet','StyleElement::processStyleSheet','StyleEngine::createResolver','StyleSheetContents::parseAuthorStyleSheet','UpdateLayoutTree'],script_parse_and_compile:['V8.RecompileSynchronous','V8.RecompileConcurrent','V8.PreParseMicroSeconds','v8.parseOnBackground','V8.ParseMicroSeconds','V8.ParseLazyMicroSeconds','V8.CompileScriptMicroSeconds','V8.CompileMicroSeconds','V8.CompileFullCode','V8.CompileEvalMicroSeconds','v8.compile'],script_parse:['V8Test.ParseScript','V8Test.ParseFunction',],script_compile:['V8Test.Compile','V8Test.CompileFullCode',],resource_loading:['ResourceFetcher::requestResource','ResourceDispatcher::OnReceivedData','ResourceDispatcher::OnRequestComplete','ResourceDispatcher::OnReceivedResponse','Resource::appendData'],renderer_misc:['DecodeFont','ThreadState::completeSweep'],[SAME_AS_PARENT]:['SyncChannel::Send']};var USER_FRIENDLY_CATEGORY_FOR_TITLE={};for(var category in TITLES_FOR_USER_FRIENDLY_CATEGORY){TITLES_FOR_USER_FRIENDLY_CATEGORY[category].forEach(function(title){USER_FRIENDLY_CATEGORY_FOR_TITLE[title]=category;});}
+var USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY={netlog:'net',overhead:'overhead',startup:'startup',gpu:'gpu'};function ChromeUserFriendlyCategoryDriver(){}
+ChromeUserFriendlyCategoryDriver.fromEvent=function(event){var userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_TITLE[event.title];if(userFriendlyCategory){if(userFriendlyCategory==SAME_AS_PARENT){if(event.parentSlice)
+return ChromeUserFriendlyCategoryDriver.fromEvent(event.parentSlice);}else{return userFriendlyCategory;}}
+var eventCategoryParts=tr.b.getCategoryParts(event.category);for(var i=0;i<eventCategoryParts.length;++i){var eventCategory=eventCategoryParts[i];userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY[eventCategory];if(userFriendlyCategory)
+return userFriendlyCategory;}
+return undefined;};return{ChromeUserFriendlyCategoryDriver:ChromeUserFriendlyCategoryDriver};});'use strict';tr.exportTo('tr.model',function(){return{BROWSER_PROCESS_PID_REF:-1,OBJECT_DEFAULT_SCOPE:'ptr'};});'use strict';tr.exportTo('tr.e.audits',function(){var Auditor=tr.c.Auditor;function ChromeAuditor(model){Auditor.call(this,model);var modelHelper=this.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper&&modelHelper.browserHelper){this.modelHelper=modelHelper;}else{this.modelHelper=undefined;}};ChromeAuditor.prototype={__proto__:Auditor.prototype,runAnnotate:function(){if(!this.modelHelper)
+return;this.model.getAllProcesses().forEach(function(process){if(process.labels!==undefined&&process.labels.length==1&&process.labels[0]=='chrome://tracing')
+process.important=false;});},installUserFriendlyCategoryDriverIfNeeded:function(){this.model.addUserFriendlyCategoryDriver(tr.e.chrome.ChromeUserFriendlyCategoryDriver);},runAudit:function(){if(!this.modelHelper)
+return;this.model.replacePIDRefsInPatchups(tr.model.BROWSER_PROCESS_PID_REF,this.modelHelper.browserProcess.pid);this.model.applyObjectRefPatchups();}};Auditor.register(ChromeAuditor);return{ChromeAuditor:ChromeAuditor};});'use strict';tr.exportTo('tr.model',function(){function ObjectSnapshot(objectInstance,ts,args){tr.model.Event.call(this);this.objectInstance=objectInstance;this.ts=ts;this.args=args;}
+ObjectSnapshot.prototype={__proto__:tr.model.Event.prototype,preInitialize:function(){},initialize:function(){},addBoundsToRange:function(range){range.addValue(this.ts);},get userFriendlyName(){return'Snapshot of '+
+this.objectInstance.typeName+' '+
+this.objectInstance.id+' @ '+
+tr.v.Unit.byName.timeStampInMs.format(this.ts);}};tr.model.EventRegistry.register(ObjectSnapshot,{name:'objectSnapshot',pluralName:'objectSnapshots',singleViewElementName:'tr-ui-a-single-object-snapshot-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshot;options.defaultConstructor=ObjectSnapshot;tr.b.decorateExtensionRegistry(ObjectSnapshot,options);return{ObjectSnapshot:ObjectSnapshot};});'use strict';tr.exportTo('tr.model',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectInstance(parent,scopedId,category,name,creationTs,opt_baseTypeName){tr.model.Event.call(this);this.parent=parent;this.scopedId=scopedId;this.category=category;this.baseTypeName=opt_baseTypeName?opt_baseTypeName:name;this.name=name;this.creationTs=creationTs;this.creationTsWasExplicit=false;this.deletionTs=Number.MAX_VALUE;this.deletionTsWasExplicit=false;this.colorId=0;this.bounds=new tr.b.Range();this.snapshots=[];this.hasImplicitSnapshots=false;}
+ObjectInstance.prototype={__proto__:tr.model.Event.prototype,get typeName(){return this.name;},addBoundsToRange:function(range){range.addRange(this.bounds);},addSnapshot:function(ts,args,opt_name,opt_baseTypeName){if(ts<this.creationTs)
+throw new Error('Snapshots must be >= instance.creationTs');if(ts>=this.deletionTs)
+throw new Error('Snapshots cannot be added after '+'an objects deletion timestamp.');var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts==ts)
+throw new Error('Snapshots already exists at this time!');if(ts<lastSnapshot.ts){throw new Error('Snapshots must be added in increasing timestamp order');}}
+if(opt_name&&(this.name!=opt_name)){if(!opt_baseTypeName)
+throw new Error('Must provide base type name for name update');if(this.baseTypeName!=opt_baseTypeName)
+throw new Error('Cannot update type name: base types dont match');this.name=opt_name;}
+var snapshotConstructor=tr.model.ObjectSnapshot.getConstructor(this.category,this.name);var snapshot=new snapshotConstructor(this,ts,args);this.snapshots.push(snapshot);return snapshot;},wasDeleted:function(ts){var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts>ts)
+throw new Error('Instance cannot be deleted at ts='+
+ts+'. A snapshot exists that is older.');}
+this.deletionTs=ts;this.deletionTsWasExplicit=true;},preInitialize:function(){for(var i=0;i<this.snapshots.length;i++)
+this.snapshots[i].preInitialize();},initialize:function(){for(var i=0;i<this.snapshots.length;i++)
+this.snapshots[i].initialize();},getSnapshotAt:function(ts){if(ts<this.creationTs){if(this.creationTsWasExplicit)
+throw new Error('ts must be within lifetime of this instance');return this.snapshots[0];}
+if(ts>this.deletionTs)
+throw new Error('ts must be within lifetime of this instance');var snapshots=this.snapshots;var i=tr.b.findIndexInSortedIntervals(snapshots,function(snapshot){return snapshot.ts;},function(snapshot,i){if(i==snapshots.length-1)
+return snapshots[i].objectInstance.deletionTs;return snapshots[i+1].ts-snapshots[i].ts;},ts);if(i<0){return this.snapshots[0];}
+if(i>=this.snapshots.length)
+return this.snapshots[this.snapshots.length-1];return this.snapshots[i];},updateBounds:function(){this.bounds.reset();this.bounds.addValue(this.creationTs);if(this.deletionTs!=Number.MAX_VALUE)
+this.bounds.addValue(this.deletionTs);else if(this.snapshots.length>0)
+this.bounds.addValue(this.snapshots[this.snapshots.length-1].ts);},shiftTimestampsForward:function(amount){this.creationTs+=amount;if(this.deletionTs!=Number.MAX_VALUE)
+this.deletionTs+=amount;this.snapshots.forEach(function(snapshot){snapshot.ts+=amount;});},get userFriendlyName(){return this.typeName+' object '+this.scopedId;}};tr.model.EventRegistry.register(ObjectInstance,{name:'objectInstance',pluralName:'objectInstances',singleViewElementName:'tr-ui-a-single-object-instance-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstance;options.defaultConstructor=ObjectInstance;tr.b.decorateExtensionRegistry(ObjectInstance,options);return{ObjectInstance:ObjectInstance};});'use strict';tr.exportTo('tr.e.chrome',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function FrameTreeNodeSnapshot(){ObjectSnapshot.apply(this,arguments);}
+FrameTreeNodeSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){},initialize:function(){},get userFriendlyName(){return'FrameTreeNode';}};ObjectSnapshot.register(FrameTreeNodeSnapshot,{typeName:'FrameTreeNode'});function FrameTreeNodeInstance(){ObjectInstance.apply(this,arguments);}
+FrameTreeNodeInstance.prototype={__proto__:ObjectInstance.prototype};ObjectInstance.register(FrameTreeNodeInstance,{typeName:'FrameTreeNode'});return{FrameTreeNodeSnapshot:FrameTreeNodeSnapshot,FrameTreeNodeInstance:FrameTreeNodeInstance};});'use strict';tr.exportTo('tr.e.chrome',function(){var KNOWN_PROPERTIES={absX:1,absY:1,address:1,anonymous:1,childNeeds:1,children:1,classNames:1,col:1,colSpan:1,float:1,height:1,htmlId:1,name:1,posChildNeeds:1,positioned:1,positionedMovement:1,relX:1,relY:1,relativePositioned:1,row:1,rowSpan:1,selfNeeds:1,stickyPositioned:1,tag:1,width:1};function LayoutObject(snapshot,args){this.snapshot_=snapshot;this.id_=args.address;this.name_=args.name;this.childLayoutObjects_=[];this.otherProperties_={};this.tag_=args.tag;this.relativeRect_=tr.b.Rect.fromXYWH(args.relX,args.relY,args.width,args.height);this.absoluteRect_=tr.b.Rect.fromXYWH(args.absX,args.absY,args.width,args.height);this.isFloat_=args.float;this.isStickyPositioned_=args.stickyPositioned;this.isPositioned_=args.positioned;this.isRelativePositioned_=args.relativePositioned;this.isAnonymous_=args.anonymous;this.htmlId_=args.htmlId;this.classNames_=args.classNames;this.needsLayoutReasons_=[];if(args.selfNeeds)
+this.needsLayoutReasons_.push('self');if(args.childNeeds)
+this.needsLayoutReasons_.push('child');if(args.posChildNeeds)
+this.needsLayoutReasons_.push('positionedChild');if(args.positionedMovement)
+this.needsLayoutReasons_.push('positionedMovement');this.tableRow_=args.row;this.tableCol_=args.col;this.tableRowSpan_=args.rowSpan;this.tableColSpan_=args.colSpan;if(args.children){args.children.forEach(function(child){this.childLayoutObjects_.push(new LayoutObject(snapshot,child));}.bind(this));}
+for(var property in args){if(!KNOWN_PROPERTIES[property])
+this.otherProperties_[property]=args[property];}}
+LayoutObject.prototype={get snapshot(){return this.snapshot_;},get id(){return this.id_;},get name(){return this.name_;},get tag(){return this.tag_;},get relativeRect(){return this.relativeRect_;},get absoluteRect(){return this.absoluteRect_;},get isPositioned(){return this.isPositioned_;},get isFloat(){return this.isFloat_;},get isStickyPositioned(){return this.isStickyPositioned_;},get isRelativePositioned(){return this.isRelativePositioned_;},get isAnonymous(){return this.isAnonymous_;},get tableRow(){return this.tableRow_;},get tableCol(){return this.tableCol_;},get tableRowSpan(){return this.tableRowSpan_;},get tableColSpan(){return this.tableColSpan_;},get htmlId(){return this.htmlId_;},get classNames(){return this.classNames_;},get needsLayoutReasons(){return this.needsLayoutReasons_;},get hasChildLayoutObjects(){return this.childLayoutObjects_.length>0;},get childLayoutObjects(){return this.childLayoutObjects_;},traverseTree:function(cb,opt_this){cb.call(opt_this,this);if(!this.hasChildLayoutObjects)
+return;this.childLayoutObjects.forEach(function(child){child.traverseTree(cb,opt_this);});},get otherPropertyNames(){var names=[];for(var name in this.otherProperties_){names.push(name);}
+return names;},getProperty:function(name){return this.otherProperties_[name];},get previousSnapshotLayoutObject(){if(!this.snapshot.previousSnapshot)
+return undefined;return this.snapshot.previousSnapshot.getLayoutObjectById(this.id);},get nextSnapshotLayoutObject(){if(!this.snapshot.nextSnapshot)
+return undefined;return this.snapshot.nextSnapshot.getLayoutObjectById(this.id);}};return{LayoutObject:LayoutObject};});'use strict';tr.exportTo('tr.e.chrome',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayoutTreeInstance(){ObjectInstance.apply(this,arguments);}
+LayoutTreeInstance.prototype={__proto__:ObjectInstance.prototype,};ObjectInstance.register(LayoutTreeInstance,{typeName:'LayoutTree'});function LayoutTreeSnapshot(){ObjectSnapshot.apply(this,arguments);this.rootLayoutObject=new tr.e.chrome.LayoutObject(this,this.args);}
+LayoutTreeSnapshot.prototype={__proto__:ObjectSnapshot.prototype,};ObjectSnapshot.register(LayoutTreeSnapshot,{typeName:'LayoutTree'});tr.model.EventRegistry.register(LayoutTreeSnapshot,{name:'layoutTree',pluralName:'layoutTrees',singleViewElementName:'tr-ui-a-layout-tree-sub-view',multiViewElementName:'tr-ui-a-layout-tree-sub-view'});return{LayoutTreeInstance:LayoutTreeInstance,LayoutTreeSnapshot:LayoutTreeSnapshot};});'use strict';tr.exportTo('tr.e.chrome',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function RenderFrameSnapshot(){ObjectSnapshot.apply(this,arguments);}
+RenderFrameSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){},initialize:function(){},get userFriendlyName(){return'RenderFrame';}};ObjectSnapshot.register(RenderFrameSnapshot,{typeName:'RenderFrame'});function RenderFrameInstance(){ObjectInstance.apply(this,arguments);}
+RenderFrameInstance.prototype={__proto__:ObjectInstance.prototype};ObjectInstance.register(RenderFrameInstance,{typeName:'RenderFrame'});return{RenderFrameSnapshot:RenderFrameSnapshot,RenderFrameInstance:RenderFrameInstance};});'use strict';tr.exportTo('tr.b',function(){function Base64(){}
+function b64ToUint6(nChr){if(nChr>64&&nChr<91)
+return nChr-65;if(nChr>96&&nChr<123)
+return nChr-71;if(nChr>47&&nChr<58)
+return nChr+4;if(nChr===43)
+return 62;if(nChr===47)
+return 63;return 0;}
+Base64.getDecodedBufferLength=function(input){return input.length*3+1>>2;};Base64.EncodeArrayBufferToString=function(input){var binary='';var bytes=new Uint8Array(input);var len=bytes.byteLength;for(var i=0;i<len;i++)
+binary+=String.fromCharCode(bytes[i]);return btoa(binary);};Base64.DecodeToTypedArray=function(input,output){var nInLen=input.length;var nOutLen=nInLen*3+1>>2;var nMod3=0;var nMod4=0;var nUint24=0;var nOutIdx=0;if(nOutLen>output.byteLength)
+throw new Error('Output buffer too small to decode.');for(var nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(input.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){output.setUint8(nOutIdx,nUint24>>>(16>>>nMod3&24)&255);}
+nUint24=0;}}
+return nOutIdx-1;};Base64.btoa=function(input){return btoa(input);};Base64.atob=function(input){return atob(input);};return{Base64:Base64};});'use strict';tr.exportTo('tr.e.importer.etw',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
+Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser:Parser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='68FDD900-4A3E-11D1-84F4-0000F80464E3';var kEventTraceHeaderOpcode=0;function EventTraceParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kEventTraceHeaderOpcode,EventTraceParser.prototype.decodeHeader.bind(this));}
+EventTraceParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version!=2)
+throw new Error('Incompatible EventTrace event version.');var bufferSize=decoder.decodeUInt32();var version=decoder.decodeUInt32();var providerVersion=decoder.decodeUInt32();var numberOfProcessors=decoder.decodeUInt32();var endTime=decoder.decodeUInt64ToString();var timerResolution=decoder.decodeUInt32();var maxFileSize=decoder.decodeUInt32();var logFileMode=decoder.decodeUInt32();var buffersWritten=decoder.decodeUInt32();var startBuffers=decoder.decodeUInt32();var pointerSize=decoder.decodeUInt32();var eventsLost=decoder.decodeUInt32();var cpuSpeed=decoder.decodeUInt32();var loggerName=decoder.decodeUInteger(header.is64);var logFileName=decoder.decodeUInteger(header.is64);var timeZoneInformation=decoder.decodeTimeZoneInformation();var padding=decoder.decodeUInt32();var bootTime=decoder.decodeUInt64ToString();var perfFreq=decoder.decodeUInt64ToString();var startTime=decoder.decodeUInt64ToString();var reservedFlags=decoder.decodeUInt32();var buffersLost=decoder.decodeUInt32();var sessionNameString=decoder.decodeW16String();var logFileNameString=decoder.decodeW16String();return{bufferSize:bufferSize,version:version,providerVersion:providerVersion,numberOfProcessors:numberOfProcessors,endTime:endTime,timerResolution:timerResolution,maxFileSize:maxFileSize,logFileMode:logFileMode,buffersWritten:buffersWritten,startBuffers:startBuffers,pointerSize:pointerSize,eventsLost:eventsLost,cpuSpeed:cpuSpeed,loggerName:loggerName,logFileName:logFileName,timeZoneInformation:timeZoneInformation,bootTime:bootTime,perfFreq:perfFreq,startTime:startTime,reservedFlags:reservedFlags,buffersLost:buffersLost,sessionNameString:sessionNameString,logFileNameString:logFileNameString};},decodeHeader:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(EventTraceParser);return{EventTraceParser:EventTraceParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';var kProcessStartOpcode=1;var kProcessEndOpcode=2;var kProcessDCStartOpcode=3;var kProcessDCEndOpcode=4;var kProcessDefunctOpcode=39;function ProcessParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kProcessStartOpcode,ProcessParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kProcessEndOpcode,ProcessParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kProcessDCStartOpcode,ProcessParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kProcessDCEndOpcode,ProcessParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kProcessDefunctOpcode,ProcessParser.prototype.decodeDefunct.bind(this));}
+ProcessParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>5)
+throw new Error('Incompatible Process event version.');var pageDirectoryBase;if(header.version==1)
+pageDirectoryBase=decoder.decodeUInteger(header.is64);var uniqueProcessKey;if(header.version>=2)
+uniqueProcessKey=decoder.decodeUInteger(header.is64);var processId=decoder.decodeUInt32();var parentId=decoder.decodeUInt32();var sessionId;var exitStatus;if(header.version>=1){sessionId=decoder.decodeUInt32();exitStatus=decoder.decodeInt32();}
+var directoryTableBase;if(header.version>=3)
+directoryTableBase=decoder.decodeUInteger(header.is64);var flags;if(header.version>=4)
+flags=decoder.decodeUInt32();var userSID=decoder.decodeSID(header.is64);var imageFileName;if(header.version>=1)
+imageFileName=decoder.decodeString();var commandLine;if(header.version>=2)
+commandLine=decoder.decodeW16String();var packageFullName;var applicationId;if(header.version>=4){packageFullName=decoder.decodeW16String();applicationId=decoder.decodeW16String();}
+var exitTime;if(header.version==5&&header.opcode==kProcessDefunctOpcode)
+exitTime=decoder.decodeUInt64ToString();return{pageDirectoryBase:pageDirectoryBase,uniqueProcessKey:uniqueProcessKey,processId:processId,parentId:parentId,sessionId:sessionId,exitStatus:exitStatus,directoryTableBase:directoryTableBase,flags:flags,userSID:userSID,imageFileName:imageFileName,commandLine:commandLine,packageFullName:packageFullName,applicationId:applicationId,exitTime:exitTime};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
+process.name=fields.imageFileName;return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended'))
+throw new Error('Process clash detected.');process.name=fields.imageFileName;return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDefunct:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(ProcessParser);return{ProcessParser:ProcessParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadStartOpcode=1;var kThreadEndOpcode=2;var kThreadDCStartOpcode=3;var kThreadDCEndOpcode=4;var kThreadCSwitchOpcode=36;function ThreadParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kThreadStartOpcode,ThreadParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kThreadEndOpcode,ThreadParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kThreadDCStartOpcode,ThreadParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kThreadDCEndOpcode,ThreadParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kThreadCSwitchOpcode,ThreadParser.prototype.decodeCSwitch.bind(this));}
+ThreadParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>3)
+throw new Error('Incompatible Thread event version.');var processId=decoder.decodeUInt32();var threadId=decoder.decodeUInt32();var stackBase;var stackLimit;var userStackBase;var userStackLimit;var affinity;var startAddr;var win32StartAddr;var tebBase;var subProcessTag;var basePriority;var pagePriority;var ioPriority;var threadFlags;var waitMode;if(header.version==1){if(header.opcode==kThreadStartOpcode||header.opcode==kThreadDCStartOpcode){stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);startAddr=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);waitMode=decoder.decodeInt8();decoder.skip(3);}}else{stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);if(header.version==2)
+startAddr=decoder.decodeUInteger(header.is64);else
+affinity=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);tebBase=decoder.decodeUInteger(header.is64);subProcessTag=decoder.decodeUInt32();if(header.version==3){basePriority=decoder.decodeUInt8();pagePriority=decoder.decodeUInt8();ioPriority=decoder.decodeUInt8();threadFlags=decoder.decodeUInt8();}}
+return{processId:processId,threadId:threadId,stackBase:stackBase,stackLimit:stackLimit,userStackBase:userStackBase,userStackLimit:userStackLimit,affinity:affinity,startAddr:startAddr,win32StartAddr:win32StartAddr,tebBase:tebBase,subProcessTag:subProcessTag,waitMode:waitMode,basePriority:basePriority,pagePriority:pagePriority,ioPriority:ioPriority,threadFlags:threadFlags};},decodeCSwitchFields:function(header,decoder){if(header.version!=2)
+throw new Error('Incompatible Thread event version.');var newThreadId=decoder.decodeUInt32();var oldThreadId=decoder.decodeUInt32();var newThreadPriority=decoder.decodeInt8();var oldThreadPriority=decoder.decodeInt8();var previousCState=decoder.decodeUInt8();var spareByte=decoder.decodeInt8();var oldThreadWaitReason=decoder.decodeInt8();var oldThreadWaitMode=decoder.decodeInt8();var oldThreadState=decoder.decodeInt8();var oldThreadWaitIdealProcessor=decoder.decodeInt8();var newThreadWaitTime=decoder.decodeUInt32();var reserved=decoder.decodeUInt32();return{newThreadId:newThreadId,oldThreadId:oldThreadId,newThreadPriority:newThreadPriority,oldThreadPriority:oldThreadPriority,previousCState:previousCState,spareByte:spareByte,oldThreadWaitReason:oldThreadWaitReason,oldThreadWaitMode:oldThreadWaitMode,oldThreadState:oldThreadState,oldThreadWaitIdealProcessor:oldThreadWaitIdealProcessor,newThreadWaitTime:newThreadWaitTime,reserved:reserved};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeCSwitch:function(header,decoder){var fields=this.decodeCSwitchFields(header,decoder);var cpu=this.importer.getOrCreateCpu(header.cpu);var new_thread=this.importer.getThreadFromWindowsTid(fields.newThreadId);var new_thread_name;if(new_thread&&new_thread.userFriendlyName){new_thread_name=new_thread.userFriendlyName;}else{var new_process_id=this.importer.getPidFromWindowsTid(fields.newThreadId);var new_process=this.model.getProcess(new_process_id);var new_process_name;if(new_process)
+new_process_name=new_process.name;else
+new_process_name='Unknown process';new_thread_name=new_process_name+' (tid '+fields.newThreadId+')';}
+cpu.switchActiveThread(header.timestamp,{},fields.newThreadId,new_thread_name,fields);return true;}};Parser.register(ThreadParser);return{ThreadParser:ThreadParser};});'use strict';tr.exportTo('tr.b',function(){function max(a,b){if(a===undefined)
+return b;if(b===undefined)
+return a;return Math.max(a,b);}
+function IntervalTree(beginPositionCb,endPositionCb){this.beginPositionCb_=beginPositionCb;this.endPositionCb_=endPositionCb;this.root_=undefined;this.size_=0;}
+IntervalTree.prototype={insert:function(datum){var startPosition=this.beginPositionCb_(datum);var endPosition=this.endPositionCb_(datum);var node=new IntervalTreeNode(datum,startPosition,endPosition);this.size_++;this.root_=this.insertNode_(this.root_,node);this.root_.colour=Colour.BLACK;return datum;},insertNode_:function(root,node){if(root===undefined)
+return node;if(root.leftNode&&root.leftNode.isRed&&root.rightNode&&root.rightNode.isRed)
+this.flipNodeColour_(root);if(node.key<root.key)
+root.leftNode=this.insertNode_(root.leftNode,node);else if(node.key===root.key)
+root.merge(node);else
+root.rightNode=this.insertNode_(root.rightNode,node);if(root.rightNode&&root.rightNode.isRed&&(root.leftNode===undefined||!root.leftNode.isRed))
+root=this.rotateLeft_(root);if(root.leftNode&&root.leftNode.isRed&&root.leftNode.leftNode&&root.leftNode.leftNode.isRed)
+root=this.rotateRight_(root);return root;},rotateRight_:function(node){var sibling=node.leftNode;node.leftNode=sibling.rightNode;sibling.rightNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},rotateLeft_:function(node){var sibling=node.rightNode;node.rightNode=sibling.leftNode;sibling.leftNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},flipNodeColour_:function(node){node.colour=this.flipColour_(node.colour);node.leftNode.colour=this.flipColour_(node.leftNode.colour);node.rightNode.colour=this.flipColour_(node.rightNode.colour);},flipColour_:function(colour){return colour===Colour.RED?Colour.BLACK:Colour.RED;},updateHighValues:function(){this.updateHighValues_(this.root_);},updateHighValues_:function(node){if(node===undefined)
+return undefined;node.maxHighLeft=this.updateHighValues_(node.leftNode);node.maxHighRight=this.updateHighValues_(node.rightNode);return max(max(node.maxHighLeft,node.highValue),node.maxHighRight);},validateFindArguments_:function(queryLow,queryHigh){if(queryLow===undefined||queryHigh===undefined)
+throw new Error('queryLow and queryHigh must be defined');if((typeof queryLow!=='number')||(typeof queryHigh!=='number'))
+throw new Error('queryLow and queryHigh must be numbers');},findIntersection:function(queryLow,queryHigh){this.validateFindArguments_(queryLow,queryHigh);if(this.root_===undefined)
+return[];var ret=[];this.root_.appendIntersectionsInto_(ret,queryLow,queryHigh);return ret;},get size(){return this.size_;},get root(){return this.root_;},dump_:function(){if(this.root_===undefined)
+return[];return this.root_.dump();}};var Colour={RED:'red',BLACK:'black'};function IntervalTreeNode(datum,lowValue,highValue){this.lowValue_=lowValue;this.data_=[{datum:datum,high:highValue,low:lowValue}];this.colour_=Colour.RED;this.parentNode_=undefined;this.leftNode_=undefined;this.rightNode_=undefined;this.maxHighLeft_=undefined;this.maxHighRight_=undefined;}
+IntervalTreeNode.prototype={appendIntersectionsInto_:function(ret,queryLow,queryHigh){if(this.lowValue_>=queryHigh){if(!this.leftNode_)
+return;return this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+if(this.maxHighLeft_>queryLow){this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+if(this.highValue>queryLow){for(var i=(this.data.length-1);i>=0;--i){if(this.data[i].high<queryLow)
+break;ret.push(this.data[i].datum);}}
+if(this.rightNode_){this.rightNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}},get colour(){return this.colour_;},set colour(colour){this.colour_=colour;},get key(){return this.lowValue_;},get lowValue(){return this.lowValue_;},get highValue(){return this.data_[this.data_.length-1].high;},set leftNode(left){this.leftNode_=left;},get leftNode(){return this.leftNode_;},get hasLeftNode(){return this.leftNode_!==undefined;},set rightNode(right){this.rightNode_=right;},get rightNode(){return this.rightNode_;},get hasRightNode(){return this.rightNode_!==undefined;},set parentNode(parent){this.parentNode_=parent;},get parentNode(){return this.parentNode_;},get isRootNode(){return this.parentNode_===undefined;},set maxHighLeft(high){this.maxHighLeft_=high;},get maxHighLeft(){return this.maxHighLeft_;},set maxHighRight(high){this.maxHighRight_=high;},get maxHighRight(){return this.maxHighRight_;},get data(){return this.data_;},get isRed(){return this.colour_===Colour.RED;},merge:function(node){for(var i=0;i<node.data.length;i++)
+this.data_.push(node.data[i]);this.data_.sort(function(a,b){return a.high-b.high;});},dump:function(){var ret={};if(this.leftNode_)
+ret['left']=this.leftNode_.dump();ret['data']=this.data_.map(function(d){return[d.low,d.high];});if(this.rightNode_)
+ret['right']=this.rightNode_.dump();return ret;}};return{IntervalTree:IntervalTree};});!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define(n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={exports:{},id:a,loaded:!1};return t[a].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){n.glMatrix=r(1),n.mat2=r(2),n.mat2d=r(3),n.mat3=r(4),n.mat4=r(5),n.quat=r(6),n.vec2=r(9),n.vec3=r(7),n.vec4=r(8)},function(t,n,r){var a={};a.EPSILON=1e-6,a.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,a.RANDOM=Math.random,a.setMatrixArrayType=function(t){GLMAT_ARRAY_TYPE=t};var e=Math.PI/180;a.toRadian=function(t){return t*e},t.exports=a},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;return o?(o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t):null},e.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},e.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*i+u*c,t[1]=e*i+o*c,t[2]=a*f+u*s,t[3]=e*f+o*s,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+u*i,t[1]=e*c+o*i,t[2]=a*-i+u*c,t[3]=e*-i+o*c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*c,t[3]=o*c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},e.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},e.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=r*u-a*e;return c?(c=1/c,t[0]=u*c,t[1]=-a*c,t[2]=-e*c,t[3]=r*c,t[4]=(e*i-u*o)*c,t[5]=(a*o-r*i)*c,t):null},e.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1],h=r[2],M=r[3],l=r[4],v=r[5];return t[0]=a*f+u*s,t[1]=e*f+o*s,t[2]=a*h+u*M,t[3]=e*h+o*M,t[4]=a*l+u*v+i,t[5]=e*l+o*v+c,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*f,t[1]=e*s+o*f,t[2]=a*-f+u*s,t[3]=e*-f+o*s,t[4]=i,t[5]=c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a*f,t[1]=e*f,t[2]=u*s,t[3]=o*s,t[4]=i,t[5]=c,t},e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*f+u*s+i,t[5]=e*f+o*s+c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},e.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},e.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=s*o-i*f,M=-s*u+i*c,l=f*u-o*c,v=r*h+a*M+e*l;return v?(v=1/v,t[0]=h*v,t[1]=(-s*a+e*f)*v,t[2]=(i*a-e*o)*v,t[3]=M*v,t[4]=(s*r-e*c)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-f*r+a*c)*v,t[8]=(o*r-a*u)*v,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8];return t[0]=o*s-i*f,t[1]=e*f-a*s,t[2]=a*i-e*o,t[3]=i*c-u*s,t[4]=r*s-e*c,t[5]=e*u-r*i,t[6]=u*f-o*c,t[7]=a*c-r*f,t[8]=r*o-a*u,t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8];return n*(f*u-o*c)+r*(-f*e+o*i)+a*(c*e-u*i)},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1],v=r[2],m=r[3],p=r[4],d=r[5],A=r[6],R=r[7],w=r[8];return t[0]=M*a+l*o+v*f,t[1]=M*e+l*i+v*s,t[2]=M*u+l*c+v*h,t[3]=m*a+p*o+d*f,t[4]=m*e+p*i+d*s,t[5]=m*u+p*c+d*h,t[6]=A*a+R*o+w*f,t[7]=A*e+R*i+w*s,t[8]=A*u+R*c+w*h,t},e.mul=e.multiply,e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=M*a+l*o+f,t[7]=M*e+l*i+s,t[8]=M*u+l*c+h,t},e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=Math.sin(r),l=Math.cos(r);return t[0]=l*a+M*o,t[1]=l*e+M*i,t[2]=l*u+M*c,t[3]=l*o-M*a,t[4]=l*i-M*e,t[5]=l*c-M*u,t[6]=f,t[7]=s,t[8]=h,t},e.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[3]=s-d,t[6]=M+p,t[1]=s+d,t[4]=1-f-v,t[7]=l-m,t[2]=M-p,t[5]=l+m,t[8]=1-f-h,t},e.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(c*P-o*b-f*x)*D,t[2]=(o*T-i*P+f*y)*D,t[3]=(e*T-a*b-u*E)*D,t[4]=(r*b-e*P+u*x)*D,t[5]=(a*P-r*T-u*y)*D,t[6]=(m*g-p*Y+d*q)*D,t[7]=(p*w-v*g-d*R)*D,t[8]=(v*Y-m*w+d*A)*D,t):null},e.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(e*T-a*b-u*E)*D,t[2]=(m*g-p*Y+d*q)*D,t[3]=(M*Y-h*g-l*q)*D,t[4]=(c*P-o*b-f*x)*D,t[5]=(r*b-e*P+u*x)*D,t[6]=(p*w-v*g-d*R)*D,t[7]=(s*g-M*w+l*R)*D,t[8]=(o*T-i*P+f*y)*D,t[9]=(a*P-r*T-u*y)*D,t[10]=(v*Y-m*w+d*A)*D,t[11]=(h*w-s*Y-l*A)*D,t[12]=(i*x-o*E-c*y)*D,t[13]=(r*E-a*x+e*y)*D,t[14]=(m*R-v*q-p*A)*D,t[15]=(s*q-h*R+M*A)*D,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15];return t[0]=i*(M*d-l*p)-h*(c*d-f*p)+m*(c*l-f*M),t[1]=-(a*(M*d-l*p)-h*(e*d-u*p)+m*(e*l-u*M)),t[2]=a*(c*d-f*p)-i*(e*d-u*p)+m*(e*f-u*c),t[3]=-(a*(c*l-f*M)-i*(e*l-u*M)+h*(e*f-u*c)),t[4]=-(o*(M*d-l*p)-s*(c*d-f*p)+v*(c*l-f*M)),t[5]=r*(M*d-l*p)-s*(e*d-u*p)+v*(e*l-u*M),t[6]=-(r*(c*d-f*p)-o*(e*d-u*p)+v*(e*f-u*c)),t[7]=r*(c*l-f*M)-o*(e*l-u*M)+s*(e*f-u*c),t[8]=o*(h*d-l*m)-s*(i*d-f*m)+v*(i*l-f*h),t[9]=-(r*(h*d-l*m)-s*(a*d-u*m)+v*(a*l-u*h)),t[10]=r*(i*d-f*m)-o*(a*d-u*m)+v*(a*f-u*i),t[11]=-(r*(i*l-f*h)-o*(a*l-u*h)+s*(a*f-u*i)),t[12]=-(o*(h*p-M*m)-s*(i*p-c*m)+v*(i*M-c*h)),t[13]=r*(h*p-M*m)-s*(a*p-e*m)+v*(a*M-e*h),t[14]=-(r*(i*p-c*m)-o*(a*p-e*m)+v*(a*c-e*i)),t[15]=r*(i*M-c*h)-o*(a*M-e*h)+s*(a*c-e*i),t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8],s=t[9],h=t[10],M=t[11],l=t[12],v=t[13],m=t[14],p=t[15],d=n*o-r*u,A=n*i-a*u,R=n*c-e*u,w=r*i-a*o,q=r*c-e*o,Y=a*c-e*i,g=f*v-s*l,y=f*m-h*l,x=f*p-M*l,P=s*m-h*v,E=s*p-M*v,T=h*p-M*m;return d*T-A*E+R*P+w*x-q*y+Y*g},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],m=n[12],p=n[13],d=n[14],A=n[15],R=r[0],w=r[1],q=r[2],Y=r[3];return t[0]=R*a+w*i+q*h+Y*m,t[1]=R*e+w*c+q*M+Y*p,t[2]=R*u+w*f+q*l+Y*d,t[3]=R*o+w*s+q*v+Y*A,R=r[4],w=r[5],q=r[6],Y=r[7],t[4]=R*a+w*i+q*h+Y*m,t[5]=R*e+w*c+q*M+Y*p,t[6]=R*u+w*f+q*l+Y*d,t[7]=R*o+w*s+q*v+Y*A,R=r[8],w=r[9],q=r[10],Y=r[11],t[8]=R*a+w*i+q*h+Y*m,t[9]=R*e+w*c+q*M+Y*p,t[10]=R*u+w*f+q*l+Y*d,t[11]=R*o+w*s+q*v+Y*A,R=r[12],w=r[13],q=r[14],Y=r[15],t[12]=R*a+w*i+q*h+Y*m,t[13]=R*e+w*c+q*M+Y*p,t[14]=R*u+w*f+q*l+Y*d,t[15]=R*o+w*s+q*v+Y*A,t},e.mul=e.multiply,e.translate=function(t,n,r){var a,e,u,o,i,c,f,s,h,M,l,v,m=r[0],p=r[1],d=r[2];return n===t?(t[12]=n[0]*m+n[4]*p+n[8]*d+n[12],t[13]=n[1]*m+n[5]*p+n[9]*d+n[13],t[14]=n[2]*m+n[6]*p+n[10]*d+n[14],t[15]=n[3]*m+n[7]*p+n[11]*d+n[15]):(a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=f,t[7]=s,t[8]=h,t[9]=M,t[10]=l,t[11]=v,t[12]=a*m+i*p+h*d+n[12],t[13]=e*m+c*p+M*d+n[13],t[14]=u*m+f*p+l*d+n[14],t[15]=o*m+s*p+v*d+n[15]),t},e.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.rotate=function(t,n,r,e){var u,o,i,c,f,s,h,M,l,v,m,p,d,A,R,w,q,Y,g,y,x,P,E,T,b=e[0],D=e[1],L=e[2],_=Math.sqrt(b*b+D*D+L*L);return Math.abs(_)<a.EPSILON?null:(_=1/_,b*=_,D*=_,L*=_,u=Math.sin(r),o=Math.cos(r),i=1-o,c=n[0],f=n[1],s=n[2],h=n[3],M=n[4],l=n[5],v=n[6],m=n[7],p=n[8],d=n[9],A=n[10],R=n[11],w=b*b*i+o,q=D*b*i+L*u,Y=L*b*i-D*u,g=b*D*i-L*u,y=D*D*i+o,x=L*D*i+b*u,P=b*L*i+D*u,E=D*L*i-b*u,T=L*L*i+o,t[0]=c*w+M*q+p*Y,t[1]=f*w+l*q+d*Y,t[2]=s*w+v*q+A*Y,t[3]=h*w+m*q+R*Y,t[4]=c*g+M*y+p*x,t[5]=f*g+l*y+d*x,t[6]=s*g+v*y+A*x,t[7]=h*g+m*y+R*x,t[8]=c*P+M*E+p*T,t[9]=f*P+l*E+d*T,t[10]=s*P+v*E+A*T,t[11]=h*P+m*E+R*T,n!==t&&(t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t)},e.rotateX=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[4],o=n[5],i=n[6],c=n[7],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[4]=u*e+f*a,t[5]=o*e+s*a,t[6]=i*e+h*a,t[7]=c*e+M*a,t[8]=f*e-u*a,t[9]=s*e-o*a,t[10]=h*e-i*a,t[11]=M*e-c*a,t},e.rotateY=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e-f*a,t[1]=o*e-s*a,t[2]=i*e-h*a,t[3]=c*e-M*a,t[8]=u*a+f*e,t[9]=o*a+s*e,t[10]=i*a+h*e,t[11]=c*a+M*e,t},e.rotateZ=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[4],s=n[5],h=n[6],M=n[7];return n!==t&&(t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e+f*a,t[1]=o*e+s*a,t[2]=i*e+h*a,t[3]=c*e+M*a,t[4]=f*e-u*a,t[5]=s*e-o*a,t[6]=h*e-i*a,t[7]=M*e-c*a,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=n[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=n[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotation=function(t,n,r){var e,u,o,i=r[0],c=r[1],f=r[2],s=Math.sqrt(i*i+c*c+f*f);return Math.abs(s)<a.EPSILON?null:(s=1/s,i*=s,c*=s,f*=s,e=Math.sin(n),u=Math.cos(n),o=1-u,t[0]=i*i*o+u,t[1]=c*i*o+f*e,t[2]=f*i*o-c*e,t[3]=0,t[4]=i*c*o-f*e,t[5]=c*c*o+u,t[6]=f*c*o+i*e,t[7]=0,t[8]=i*f*o+c*e,t[9]=c*f*o-i*e,t[10]=f*f*o+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.fromXRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=r,t[7]=0,t[8]=0,t[9]=-r,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromYRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=0,t[2]=-r,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=r,t[9]=0,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromZRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=0,t[4]=-r,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotationTranslation=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,c=e+e,f=u+u,s=a*i,h=a*c,M=a*f,l=e*c,v=e*f,m=u*f,p=o*i,d=o*c,A=o*f;return t[0]=1-(l+m),t[1]=h+A,t[2]=M-d,t[3]=0,t[4]=h-A,t[5]=1-(s+m),t[6]=v+p,t[7]=0,t[8]=M+d,t[9]=v-p,t[10]=1-(s+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],c=e+e,f=u+u,s=o+o,h=e*c,M=e*f,l=e*s,v=u*f,m=u*s,p=o*s,d=i*c,A=i*f,R=i*s,w=a[0],q=a[1],Y=a[2];return t[0]=(1-(v+p))*w,t[1]=(M+R)*w,t[2]=(l-A)*w,t[3]=0,t[4]=(M-R)*q,t[5]=(1-(h+p))*q,t[6]=(m+d)*q,t[7]=0,t[8]=(l+A)*Y,t[9]=(m-d)*Y,t[10]=(1-(h+v))*Y,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],c=n[3],f=u+u,s=o+o,h=i+i,M=u*f,l=u*s,v=u*h,m=o*s,p=o*h,d=i*h,A=c*f,R=c*s,w=c*h,q=a[0],Y=a[1],g=a[2],y=e[0],x=e[1],P=e[2];return t[0]=(1-(m+d))*q,t[1]=(l+w)*q,t[2]=(v-R)*q,t[3]=0,t[4]=(l-w)*Y,t[5]=(1-(M+d))*Y,t[6]=(p+A)*Y,t[7]=0,t[8]=(v+R)*g,t[9]=(p-A)*g,t[10]=(1-(M+m))*g,t[11]=0,t[12]=r[0]+y-(t[0]*y+t[4]*x+t[8]*P),t[13]=r[1]+x-(t[1]*y+t[5]*x+t[9]*P),t[14]=r[2]+P-(t[2]*y+t[6]*x+t[10]*P),t[15]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[1]=s+d,t[2]=M-p,t[3]=0,t[4]=s-d,t[5]=1-f-v,t[6]=l+m,t[7]=0,t[8]=M+p,t[9]=l-m,t[10]=1-f-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),c=1/(e-a),f=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*c,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*c,t[10]=(o+u)*f,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*f,t[15]=0,t},e.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t},e.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),f=2/(e+u);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=-((o-i)*c*.5),t[9]=(e-u)*f*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},e.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),c=1/(a-e),f=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*c,t[14]=(o+u)*f,t[15]=1,t},e.lookAt=function(t,n,r,u){var o,i,c,f,s,h,M,l,v,m,p=n[0],d=n[1],A=n[2],R=u[0],w=u[1],q=u[2],Y=r[0],g=r[1],y=r[2];return Math.abs(p-Y)<a.EPSILON&&Math.abs(d-g)<a.EPSILON&&Math.abs(A-y)<a.EPSILON?e.identity(t):(M=p-Y,l=d-g,v=A-y,m=1/Math.sqrt(M*M+l*l+v*v),M*=m,l*=m,v*=m,o=w*v-q*l,i=q*M-R*v,c=R*l-w*M,m=Math.sqrt(o*o+i*i+c*c),m?(m=1/m,o*=m,i*=m,c*=m):(o=0,i=0,c=0),f=l*c-v*i,s=v*o-M*c,h=M*i-l*o,m=Math.sqrt(f*f+s*s+h*h),m?(m=1/m,f*=m,s*=m,h*=m):(f=0,s=0,h=0),t[0]=o,t[1]=f,t[2]=M,t[3]=0,t[4]=i,t[5]=s,t[6]=l,t[7]=0,t[8]=c,t[9]=h,t[10]=v,t[11]=0,t[12]=-(o*p+i*d+c*A),t[13]=-(f*p+s*d+h*A),t[14]=-(M*p+l*d+v*A),t[15]=1,t)},e.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},t.exports=e},function(t,n,r){var a=r(1),e=r(4),u=r(7),o=r(8),i={};i.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var c=u.dot(e,o);return-.999999>c?(u.cross(t,n,e),u.length(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),i.setAxisAngle(a,t,Math.PI),a):c>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+c,i.normalize(a,a))}}(),i.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],i.normalize(n,i.fromMat3(n,t))}}(),i.clone=o.clone,i.fromValues=o.fromValues,i.copy=o.copy,i.set=o.set,i.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.setAxisAngle=function(t,n,r){r=.5*r;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t},i.add=o.add,i.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*s+o*i+e*f-u*c,t[1]=e*s+o*c+u*i-a*f,t[2]=u*s+o*f+a*c-e*i,t[3]=o*s-a*i-e*c-u*f,t},i.mul=i.multiply,i.scale=o.scale,i.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+o*i,t[1]=e*c+u*i,t[2]=u*c-e*i,t[3]=o*c-a*i,t},i.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c-u*i,t[1]=e*c+o*i,t[2]=u*c+a*i,t[3]=o*c-e*i,t},i.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+e*i,t[1]=e*c-a*i,t[2]=u*c+o*i,t[3]=o*c-u*i,t},i.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},i.dot=o.dot,i.lerp=o.lerp,i.slerp=function(t,n,r,a){var e,u,o,i,c,f=n[0],s=n[1],h=n[2],M=n[3],l=r[0],v=r[1],m=r[2],p=r[3];return u=f*l+s*v+h*m+M*p,0>u&&(u=-u,l=-l,v=-v,m=-m,p=-p),1-u>1e-6?(e=Math.acos(u),o=Math.sin(e),i=Math.sin((1-a)*e)/o,c=Math.sin(a*e)/o):(i=1-a,c=a),t[0]=i*f+c*l,t[1]=i*s+c*v,t[2]=i*h+c*m,t[3]=i*M+c*p,t},i.sqlerp=function(){var t=i.create(),n=i.create();return function(r,a,e,u,o,c){return i.slerp(t,a,o,c),i.slerp(n,e,u,c),i.slerp(r,t,n,2*c*(1-c)),r}}(),i.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},i.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},i.length=o.length,i.len=i.length,i.squaredLength=o.squaredLength,i.sqrLen=i.squaredLength,i.normalize=o.normalize,i.fromMat3=function(t,n){var r,a=n[0]+n[4]+n[8];if(a>0)r=Math.sqrt(a+1),t[3]=.5*r,r=.5/r,t[0]=(n[5]-n[7])*r,t[1]=(n[6]-n[2])*r,t[2]=(n[1]-n[3])*r;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;r=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*r,r=.5/r,t[3]=(n[3*u+o]-n[3*o+u])*r,t[u]=(n[3*u+e]+n[3*e+u])*r,t[o]=(n[3*o+e]+n[3*e+o])*r}return t},i.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=i},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},e.fromValues=function(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t},e.set=function(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},e.cross=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2];return t[0]=e*c-u*i,t[1]=u*o-a*c,t[2]=a*i-e*o,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t},e.hermite=function(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,c=o*(u-2)+u,f=o*(u-1),s=o*(3-2*u);return t[0]=n[0]*i+r[0]*c+a[0]*f+e[0]*s,t[1]=n[1]*i+r[1]*c+a[1]*f+e[1]*s,t[2]=n[2]*i+r[2]*c+a[2]*f+e[2]*s,t},e.bezier=function(t,n,r,a,e,u){var o=1-u,i=o*o,c=u*u,f=i*o,s=3*u*i,h=3*c*o,M=c*u;return t[0]=n[0]*f+r[0]*s+a[0]*h+e[0]*M,t[1]=n[1]*f+r[1]*s+a[1]*h+e[1]*M,t[2]=n[2]*f+r[2]*s+a[2]*h+e[2]*M,t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI,e=2*a.RANDOM()-1,u=Math.sqrt(1-e*e)*n;return t[0]=Math.cos(r)*u,t[1]=Math.sin(r)*u,t[2]=e*n,t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t},e.rotateX=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateY=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateZ=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=3),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2];return n}}(),e.angle=function(t,n){var r=e.fromValues(t[0],t[1],t[2]),a=e.fromValues(n[0],n[1],n[2]);e.normalize(r,r),e.normalize(a,a);var u=e.dot(r,a);return u>1?0:Math.acos(u)},e.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;return o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},e.random=function(t,n){return n=n||1,t[0]=a.RANDOM(),t[1]=a.RANDOM(),t[2]=a.RANDOM(),t[3]=a.RANDOM(),e.normalize(t,t),e.scale(t,t,n),t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t[3]=n[3],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=4),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],t[3]=n[i+3],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2],n[i+3]=t[3];return n}}(),e.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},e.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},e.set=function(t,n,r){return t[0]=n,t[1]=r,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1];return n*n+r*r},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},e.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},e.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},e.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=2),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],u(t,t,o),n[i]=t[0],n[i+1]=t[1];return n}}(),e.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},t.exports=e}])});'use strict';(function(global){if(tr.isNode){var glMatrixAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/gl-matrix-min.js');var glMatrixModule=require(glMatrixAbsPath);for(var exportName in glMatrixModule){global[exportName]=glMatrixModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b',function(){function clamp(x,lo,hi){return Math.min(Math.max(x,lo),hi);}
+function lerp(percentage,lo,hi){var range=hi-lo;return lo+percentage*range;}
+function normalize(value,lo,hi){return(value-lo)/(hi-lo);}
+function deg2rad(deg){return(Math.PI*deg)/180.0;}
+var tmp_vec2=vec2.create();var tmp_vec2b=vec2.create();var tmp_vec4=vec4.create();var tmp_mat2d=mat2d.create();vec2.createFromArray=function(arr){if(arr.length!=2)
+throw new Error('Should be length 2');var v=vec2.create();vec2.set(v,arr[0],arr[1]);return v;};vec2.createXY=function(x,y){var v=vec2.create();vec2.set(v,x,y);return v;};vec2.toString=function(a){return'['+a[0]+', '+a[1]+']';};vec2.addTwoScaledUnitVectors=function(out,u1,scale1,u2,scale2){vec2.scale(tmp_vec2,u1,scale1);vec2.scale(tmp_vec2b,u2,scale2);vec2.add(out,tmp_vec2,tmp_vec2b);};vec2.interpolatePiecewiseFunction=function(points,x){if(x<points[0][0])
+return points[0][1];for(var i=1;i<points.length;++i){if(x<points[i][0]){var percent=normalize(x,points[i-1][0],points[i][0]);return lerp(percent,points[i-1][1],points[i][1]);}}
+return points[points.length-1][1];};vec3.createXYZ=function(x,y,z){var v=vec3.create();vec3.set(v,x,y,z);return v;};vec3.toString=function(a){return'vec3('+a[0]+', '+a[1]+', '+a[2]+')';};mat2d.translateXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.translate(out,out,tmp_vec2);};mat2d.scaleXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.scale(out,out,tmp_vec2);};vec4.unitize=function(out,a){out[0]=a[0]/a[3];out[1]=a[1]/a[3];out[2]=a[2]/a[3];out[3]=1;return out;};vec2.copyFromVec4=function(out,a){vec4.unitize(tmp_vec4,a);vec2.copy(out,tmp_vec4);};return{clamp:clamp,lerp:lerp,normalize:normalize,deg2rad:deg2rad};});'use strict';tr.exportTo('tr.b',function(){var tmpVec2s=[];for(var i=0;i<8;i++)
+tmpVec2s[i]=vec2.create();var tmpVec2a=vec4.create();var tmpVec4a=vec4.create();var tmpVec4b=vec4.create();var tmpMat4=mat4.create();var tmpMat4b=mat4.create();var p00=vec2.createXY(0,0);var p10=vec2.createXY(1,0);var p01=vec2.createXY(0,1);var p11=vec2.createXY(1,1);var lerpingVecA=vec2.create();var lerpingVecB=vec2.create();function lerpVec2(out,a,b,amt){vec2.scale(lerpingVecA,a,amt);vec2.scale(lerpingVecB,b,1-amt);vec2.add(out,lerpingVecA,lerpingVecB);vec2.normalize(out,out);return out;}
+function Quad(){this.p1=vec2.create();this.p2=vec2.create();this.p3=vec2.create();this.p4=vec2.create();}
+Quad.fromXYWH=function(x,y,w,h){var q=new Quad();vec2.set(q.p1,x,y);vec2.set(q.p2,x+w,y);vec2.set(q.p3,x+w,y+h);vec2.set(q.p4,x,y+h);return q;}
+Quad.fromRect=function(r){return new Quad.fromXYWH(r.x,r.y,r.width,r.height);}
+Quad.from4Vecs=function(p1,p2,p3,p4){var q=new Quad();vec2.set(q.p1,p1[0],p1[1]);vec2.set(q.p2,p2[0],p2[1]);vec2.set(q.p3,p3[0],p3[1]);vec2.set(q.p4,p4[0],p4[1]);return q;}
+Quad.from8Array=function(arr){if(arr.length!=8)
+throw new Error('Array must be 8 long');var q=new Quad();q.p1[0]=arr[0];q.p1[1]=arr[1];q.p2[0]=arr[2];q.p2[1]=arr[3];q.p3[0]=arr[4];q.p3[1]=arr[5];q.p4[0]=arr[6];q.p4[1]=arr[7];return q;};Quad.prototype={pointInside:function(point){return pointInImplicitQuad(point,this.p1,this.p2,this.p3,this.p4);},boundingRect:function(){var x0=Math.min(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y0=Math.min(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);var x1=Math.max(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y1=Math.max(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);return new tr.b.Rect.fromXYWH(x0,y0,x1-x0,y1-y0);},clone:function(){var q=new Quad();vec2.copy(q.p1,this.p1);vec2.copy(q.p2,this.p2);vec2.copy(q.p3,this.p3);vec2.copy(q.p4,this.p4);return q;},scale:function(s){var q=new Quad();this.scaleFast(q,s);return q;},scaleFast:function(dstQuad,s){vec2.copy(dstQuad.p1,this.p1,s);vec2.copy(dstQuad.p2,this.p2,s);vec2.copy(dstQuad.p3,this.p3,s);vec2.copy(dstQuad.p3,this.p3,s);},isRectangle:function(){var bounds=this.boundingRect();return(bounds.x==this.p1[0]&&bounds.y==this.p1[1]&&bounds.width==this.p2[0]-this.p1[0]&&bounds.y==this.p2[1]&&bounds.width==this.p3[0]-this.p1[0]&&bounds.height==this.p3[1]-this.p2[1]&&bounds.x==this.p4[0]&&bounds.height==this.p4[1]-this.p2[1]);},projectUnitRect:function(rect){var q=new Quad();this.projectUnitRectFast(q,rect);return q;},projectUnitRectFast:function(dstQuad,rect){var v12=tmpVec2s[0];var v14=tmpVec2s[1];var v23=tmpVec2s[2];var v43=tmpVec2s[3];var l12,l14,l23,l43;vec2.sub(v12,this.p2,this.p1);l12=vec2.length(v12);vec2.scale(v12,v12,1/l12);vec2.sub(v14,this.p4,this.p1);l14=vec2.length(v14);vec2.scale(v14,v14,1/l14);vec2.sub(v23,this.p3,this.p2);l23=vec2.length(v23);vec2.scale(v23,v23,1/l23);vec2.sub(v43,this.p3,this.p4);l43=vec2.length(v43);vec2.scale(v43,v43,1/l43);var b12=tmpVec2s[0];var b14=tmpVec2s[1];var b23=tmpVec2s[2];var b43=tmpVec2s[3];lerpVec2(b12,v12,v43,rect.y);lerpVec2(b43,v12,v43,1-rect.bottom);lerpVec2(b14,v14,v23,rect.x);lerpVec2(b23,v14,v23,1-rect.right);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*rect.x,b14,l14*rect.y);vec2.add(dstQuad.p1,this.p1,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*-(1.0-rect.right),b23,l23*rect.y);vec2.add(dstQuad.p2,this.p2,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*-(1.0-rect.right),b23,l23*-(1.0-rect.bottom));vec2.add(dstQuad.p3,this.p3,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*rect.left,b14,l14*-(1.0-rect.bottom));vec2.add(dstQuad.p4,this.p4,tmpVec2a);},toString:function(){return'Quad('+
+vec2.toString(this.p1)+', '+
+vec2.toString(this.p2)+', '+
+vec2.toString(this.p3)+', '+
+vec2.toString(this.p4)+')';}};function sign(p1,p2,p3){return(p1[0]-p3[0])*(p2[1]-p3[1])-
+(p2[0]-p3[0])*(p1[1]-p3[1]);}
+function pointInTriangle2(pt,p1,p2,p3){var b1=sign(pt,p1,p2)<0.0;var b2=sign(pt,p2,p3)<0.0;var b3=sign(pt,p3,p1)<0.0;return((b1==b2)&&(b2==b3));}
+function pointInImplicitQuad(point,p1,p2,p3,p4){return pointInTriangle2(point,p1,p2,p3)||pointInTriangle2(point,p1,p3,p4);}
+return{pointInTriangle2:pointInTriangle2,pointInImplicitQuad:pointInImplicitQuad,Quad:Quad};});'use strict';tr.exportTo('tr.b',function(){function addSingletonGetter(ctor){ctor.getInstance=function(){return ctor.instance_||(ctor.instance_=new ctor());};}
+function deepCopy(value){if(!(value instanceof Object)){if(value===undefined||value===null)
+return value;if(typeof value=='string')
+return value.substring();if(typeof value=='boolean')
+return value;if(typeof value=='number')
+return value;throw new Error('Unrecognized: '+typeof value);}
+var object=value;if(object instanceof Array){var res=new Array(object.length);for(var i=0;i<object.length;i++)
+res[i]=deepCopy(object[i]);return res;}
+if(object.__proto__!=Object.prototype)
+throw new Error('Can only clone simple types');var res={};for(var key in object){res[key]=deepCopy(object[key]);}
+return res;}
+function normalizeException(e){if(e===undefined||e===null){return{typeName:'UndefinedError',message:'Unknown: null or undefined exception',stack:'Unknown'};}
+if(typeof(e)=='string'){return{typeName:'StringError',message:e,stack:[e]};}
+var typeName;if(e.name){typeName=e.name;}else if(e.constructor){if(e.constructor.name){typeName=e.constructor.name;}else{typeName='AnonymousError';}}else{typeName='ErrorWithNoConstructor';}
+var msg=e.message?e.message:'Unknown';return{typeName:typeName,message:msg,stack:e.stack?e.stack:[msg]};}
+function stackTraceAsString(){return new Error().stack+'';}
+function stackTrace(){var stack=stackTraceAsString();stack=stack.split('\n');return stack.slice(2);}
+function getUsingPath(path,from_dict){var parts=path.split('.');var cur=from_dict;for(var part;parts.length&&(part=parts.shift());){if(!parts.length){return cur[part];}else if(part in cur){cur=cur[part];}else{return undefined;}}
+return undefined;}
+return{addSingletonGetter:addSingletonGetter,deepCopy:deepCopy,normalizeException:normalizeException,stackTrace:stackTrace,stackTraceAsString:stackTraceAsString,getUsingPath:getUsingPath};});'use strict';tr.exportTo('tr.b',function(){var ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS=10;var REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS=100;var recordRAFStacks=false;var pendingPreAFs=[];var pendingRAFs=[];var pendingIdleCallbacks=[];var currentRAFDispatchList=undefined;var rafScheduled=false;var idleWorkScheduled=false;function scheduleRAF(){if(rafScheduled)
+return;rafScheduled=true;if(tr.isHeadless){Promise.resolve().then(function(){processRequests(false,0);},function(e){console.log(e.stack);throw e;});}else{if(window.requestAnimationFrame){window.requestAnimationFrame(processRequests.bind(this,false));}else{var delta=Date.now()-window.performance.now();window.webkitRequestAnimationFrame(function(domTimeStamp){processRequests(false,domTimeStamp-delta);});}}}
+function nativeRequestIdleCallbackSupported(){return!tr.isHeadless&&window.requestIdleCallback;}
+function scheduleIdleWork(){if(idleWorkScheduled)
+return;if(!nativeRequestIdleCallbackSupported()){scheduleRAF();return;}
+idleWorkScheduled=true;window.requestIdleCallback(function(deadline,didTimeout){processIdleWork(false,deadline);},{timeout:REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS});}
+function onAnimationFrameError(e,opt_stack){console.log(e.stack);if(tr.isHeadless)
+throw e;if(opt_stack)
+console.log(opt_stack);if(e.message)
+console.error(e.message,e.stack);else
+console.error(e);}
+function runTask(task,frameBeginTime){try{task.callback.call(task.context,frameBeginTime);}catch(e){tr.b.onAnimationFrameError(e,task.stack);}}
+function processRequests(forceAllTasksToRun,frameBeginTime){rafScheduled=false;var currentPreAFs=pendingPreAFs;currentRAFDispatchList=pendingRAFs;pendingPreAFs=[];pendingRAFs=[];var hasRAFTasks=currentPreAFs.length||currentRAFDispatchList.length;for(var i=0;i<currentPreAFs.length;i++)
+runTask(currentPreAFs[i],frameBeginTime);while(currentRAFDispatchList.length>0)
+runTask(currentRAFDispatchList.shift(),frameBeginTime);currentRAFDispatchList=undefined;if((!hasRAFTasks&&!nativeRequestIdleCallbackSupported())||forceAllTasksToRun){var rafCompletionDeadline=frameBeginTime+ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS;processIdleWork(forceAllTasksToRun,{timeRemaining:function(){return rafCompletionDeadline-window.performance.now();}});}
+if(pendingIdleCallbacks.length>0)
+scheduleIdleWork();}
+function processIdleWork(forceAllTasksToRun,deadline){idleWorkScheduled=false;while(pendingIdleCallbacks.length>0){runTask(pendingIdleCallbacks.shift());if(!forceAllTasksToRun&&(tr.isHeadless||deadline.timeRemaining()<=0)){break;}}
+if(pendingIdleCallbacks.length>0)
+scheduleIdleWork();}
+function getStack_(){if(!recordRAFStacks)
+return'';var stackLines=tr.b.stackTrace();stackLines.shift();return stackLines.join('\n');}
+function requestPreAnimationFrame(callback,opt_this){pendingPreAFs.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
+function requestAnimationFrameInThisFrameIfPossible(callback,opt_this){if(!currentRAFDispatchList){requestAnimationFrame(callback,opt_this);return;}
+currentRAFDispatchList.push({callback:callback,context:opt_this||global,stack:getStack_()});return;}
+function requestAnimationFrame(callback,opt_this){pendingRAFs.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
+function requestIdleCallback(callback,opt_this){pendingIdleCallbacks.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleIdleWork();}
+function forcePendingRAFTasksToRun(frameBeginTime){if(!rafScheduled)
+return;processRequests(false,frameBeginTime);}
+function forceAllPendingTasksToRunForTest(){if(!rafScheduled&&!idleWorkScheduled)
+return;processRequests(true,0);}
+return{onAnimationFrameError:onAnimationFrameError,requestPreAnimationFrame:requestPreAnimationFrame,requestAnimationFrame:requestAnimationFrame,requestAnimationFrameInThisFrameIfPossible:requestAnimationFrameInThisFrameIfPossible,requestIdleCallback:requestIdleCallback,forcePendingRAFTasksToRun:forcePendingRAFTasksToRun,forceAllPendingTasksToRunForTest:forceAllPendingTasksToRunForTest};});'use strict';tr.exportTo('tr.b',function(){var Base64=tr.b.Base64;function computeUserTimingMarkName(groupName,functionName,opt_args){if(groupName===undefined)
+throw new Error('getMeasureString should have group name');if(functionName===undefined)
+throw new Error('getMeasureString should have function name');var userTimingMarkName=groupName+':'+functionName;if(opt_args!==undefined){userTimingMarkName+='/';userTimingMarkName+=Base64.btoa(JSON.stringify(opt_args));}
+return userTimingMarkName;}
+function Timing(){}
+Timing.nextMarkNumber=0;Timing.mark=function(groupName,functionName,opt_args){if(tr.isHeadless){return{end:function(){}};}
+var userTimingMarkName=computeUserTimingMarkName(groupName,functionName,opt_args);var markBeginName='tvcm.mark'+Timing.nextMarkNumber++;var markEndName='tvcm.mark'+Timing.nextMarkNumber++;window.performance.mark(markBeginName);return{end:function(){window.performance.mark(markEndName);window.performance.measure(userTimingMarkName,markBeginName,markEndName);}};};Timing.wrap=function(groupName,callback,opt_args){if(groupName===undefined)
+throw new Error('Timing.wrap should have group name');if(callback.name==='')
+throw new Error('Anonymous function is not allowed');return Timing.wrapNamedFunction(groupName,callback.name,callback,opt_args);};Timing.wrapNamedFunction=function(groupName,functionName,callback,opt_args){function timedNamedFunction(){var markedTime=Timing.mark(groupName,functionName,opt_args);try{callback.apply(this,arguments);}finally{markedTime.end();}}
+return timedNamedFunction;};function TimedNamedPromise(groupName,name,executor,opt_args){var markedTime=Timing.mark(groupName,name,opt_args);var promise=new Promise(executor);promise.then(function(result){markedTime.end();return result;},function(e){markedTime.end();throw e;});return promise;}
+return{_computeUserTimingMarkName:computeUserTimingMarkName,TimedNamedPromise:TimedNamedPromise,Timing:Timing};});'use strict';tr.exportTo('tr.b',function(){var Timing=tr.b.Timing;function Task(runCb,thisArg){if(runCb!==undefined&&thisArg===undefined)
+throw new Error('Almost certainly, you meant to pass a thisArg.');this.runCb_=runCb;this.thisArg_=thisArg;this.afterTask_=undefined;this.subTasks_=[];}
+Task.prototype={get name(){return this.runCb_.name;},subTask:function(cb,thisArg){if(cb instanceof Task)
+this.subTasks_.push(cb);else
+this.subTasks_.push(new Task(cb,thisArg));return this.subTasks_[this.subTasks_.length-1];},run:function(){if(this.runCb_!==undefined)
+this.runCb_.call(this.thisArg_,this);var subTasks=this.subTasks_;this.subTasks_=undefined;if(!subTasks.length)
+return this.afterTask_;for(var i=1;i<subTasks.length;i++)
+subTasks[i-1].afterTask_=subTasks[i];subTasks[subTasks.length-1].afterTask_=this.afterTask_;return subTasks[0];},after:function(cb,thisArg){if(this.afterTask_)
+throw new Error('Has an after task already');if(cb instanceof Task)
+this.afterTask_=cb;else
+this.afterTask_=new Task(cb,thisArg);return this.afterTask_;},timedAfter:function(groupName,cb,thisArg,opt_args){if(cb.name==='')
+throw new Error('Anonymous Task is not allowed');return this.namedTimedAfter(groupName,cb.name,cb,thisArg,opt_args);},namedTimedAfter:function(groupName,name,cb,thisArg,opt_args){if(this.afterTask_)
+throw new Error('Has an after task already');var realTask;if(cb instanceof Task)
+realTask=cb;else
+realTask=new Task(cb,thisArg);this.afterTask_=new Task(function(task){var markedTask=Timing.mark(groupName,name,opt_args);task.subTask(realTask,thisArg);task.subTask(function(){markedTask.end();},thisArg);},thisArg);return this.afterTask_;},enqueue:function(cb,thisArg){var lastTask=this;while(lastTask.afterTask_)
+lastTask=lastTask.afterTask_;return lastTask.after(cb,thisArg);}};Task.RunSynchronously=function(task){var curTask=task;while(curTask)
+curTask=curTask.run();}
+Task.RunWhenIdle=function(task){return new Promise(function(resolve,reject){var curTask=task;function runAnother(){try{curTask=curTask.run();}catch(e){reject(e);console.error(e.stack);return;}
+if(curTask){tr.b.requestIdleCallback(runAnother);return;}
+resolve();}
+tr.b.requestIdleCallback(runAnother);});}
+return{Task:Task};});'use strict';tr.exportTo('tr.c',function(){function makeCaseInsensitiveRegex(pattern){pattern=pattern.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');return new RegExp(pattern,'i');}
+function Filter(){}
+Filter.prototype={__proto__:Object.prototype,matchCounter:function(counter){return true;},matchCpu:function(cpu){return true;},matchProcess:function(process){return true;},matchSlice:function(slice){return true;},matchThread:function(thread){return true;}};function TitleOrCategoryFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);if(!text.length)
+throw new Error('Filter text is empty.');}
+TitleOrCategoryFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){if(slice.title===undefined&&slice.category===undefined)
+return false;return this.regex_.test(slice.title)||(!!slice.category&&this.regex_.test(slice.category));}};function ExactTitleFilter(text){Filter.call(this);this.text_=text;if(!text.length)
+throw new Error('Filter text is empty.');}
+ExactTitleFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){return slice.title===this.text_;}};function FullTextFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);this.titleOrCategoryFilter_=new TitleOrCategoryFilter(text);}
+FullTextFilter.prototype={__proto__:Filter.prototype,matchObject_:function(obj){for(var key in obj){if(!obj.hasOwnProperty(key))
+continue;if(this.regex_.test(key))
+return true;if(this.regex_.test(obj[key]))
+return true;}
+return false;},matchSlice:function(slice){if(this.titleOrCategoryFilter_.matchSlice(slice))
+return true;return this.matchObject_(slice.args);}};return{Filter:Filter,TitleOrCategoryFilter:TitleOrCategoryFilter,ExactTitleFilter:ExactTitleFilter,FullTextFilter:FullTextFilter};});'use strict';tr.exportTo('tr.model',function(){var ClockDomainId={BATTOR:'battor',TRACE_EVENT_IMPORTER:'trace_event_importer'};function ClockSyncManager(){this.connectorBySyncId_={};this.modelDomainId_=undefined;this.modelTimeTransformerByDomainId_=undefined;}
+ClockSyncManager.prototype={addClockSyncMarker:function(domainId,syncId,startTs,opt_endTs){if(tr.b.dictionaryValues(ClockDomainId).indexOf(domainId)<0){throw new Error('"'+domainId+'" is not in the list of known '+'clock domain IDs.');}
+if(this.modelDomainId_!==undefined){throw new Error('Cannot add new clock sync markers after getting '+'a model time transformer.');}
+var marker=new ClockSyncMarker(domainId,startTs,opt_endTs);var connector=this.connectorBySyncId_[syncId];if(connector===undefined){this.connectorBySyncId_[syncId]=new ClockSyncConnector(marker);return;}
+if(connector.marker2!==undefined){throw new Error('Clock sync with ID "'+syncId+'" is already '+'complete - cannot add a third clock sync marker to it.');}
+if(connector.marker1.domainId===domainId)
+throw new Error('A clock domain cannot sync with itself.');if(this.getConnectorBetween_(connector.marker1.domainId,domainId)!==undefined){throw new Error('Cannot add multiple connectors between the same '+'clock domains.');}
+connector.marker2=marker;},getModelTimeTransformer:function(domainId){if(this.modelTimeTransformerByDomainId_===undefined)
+this.buildModelTimeTransformerMap_();var transformer=this.modelTimeTransformerByDomainId_[domainId];if(transformer===undefined){throw new Error('No clock sync markers exist pairing clock domain "'+
+domainId+'" '+'with model clock domain "'+
+this.modelDomainId_+'".');}
+return transformer;},buildModelTimeTransformerMap_(){var completeConnectorsByDomainId=this.getCompleteConnectorsByDomainId_();var uniqueDomainIds=tr.b.dictionaryKeys(completeConnectorsByDomainId);uniqueDomainIds.sort();var isFullyConnected=function(domainId){return completeConnectorsByDomainId[domainId].length===uniqueDomainIds.length-1;};var eligibleModelDomainIds=uniqueDomainIds.filter(isFullyConnected);var traceEventImporterDomainExists=eligibleModelDomainIds.indexOf(ClockDomainId.TRACE_EVENT_IMPORTER)>=0;this.modelDomainId_=traceEventImporterDomainExists?ClockDomainId.TRACE_EVENT_IMPORTER:eligibleModelDomainIds[0];if(this.modelDomainId_===undefined){throw new Error('Unable to select a master clock domain because no '+'clock domain is directly connected to all others.');}
+this.modelTimeTransformerByDomainId_={};this.modelTimeTransformerByDomainId_[this.modelDomainId_]=tr.b.identity;var modelConnectors=completeConnectorsByDomainId[this.modelDomainId_];for(var i=0;i<modelConnectors.length;i++){var conn=modelConnectors[i];if(conn.marker1.domainId===this.modelDomainId_){this.modelTimeTransformerByDomainId_[conn.marker2.domainId]=conn.getTransformer(conn.marker2.domainId,conn.marker1.domainId);}else{this.modelTimeTransformerByDomainId_[conn.marker1.domainId]=conn.getTransformer(conn.marker1.domainId,conn.marker2.domainId);}}},getCompleteConnectorsByDomainId_:function(){var completeConnectorsByDomainId={};for(var syncId in this.connectorBySyncId_){var conn=this.connectorBySyncId_[syncId];var domain1=conn.marker1.domainId;if(completeConnectorsByDomainId[domain1]===undefined)
+completeConnectorsByDomainId[domain1]=[];if(conn.marker2===undefined)
+continue;var domain2=conn.marker2.domainId;if(completeConnectorsByDomainId[domain2]===undefined)
+completeConnectorsByDomainId[domain2]=[];completeConnectorsByDomainId[domain1].push(conn);completeConnectorsByDomainId[domain2].push(conn);}
+return completeConnectorsByDomainId;},getConnectorBetween_(domain1Id,domain2Id){for(var syncId in this.connectorBySyncId_){var connector=this.connectorBySyncId_[syncId];if(connector.isBetween(domain1Id,domain2Id))
+return connector;}
+return undefined;}};function ClockSyncMarker(domainId,startTs,opt_endTs){this.domainId=domainId;this.startTs=startTs;this.endTs=opt_endTs===undefined?startTs:opt_endTs;}
+ClockSyncMarker.prototype={get ts(){return(this.startTs+this.endTs)/2;}};function ClockSyncConnector(opt_marker1,opt_marker2){this.marker1=opt_marker1;this.marker2=opt_marker2;}
+ClockSyncConnector.prototype={getTransformer:function(fromDomainId,toDomainId){if(!this.isBetween(fromDomainId,toDomainId))
+throw new Error('This connector cannot perform this transformation.');var fromMarker,toMarker;if(this.marker1.domainId===fromDomainId){fromMarker=this.marker1;toMarker=this.marker2;}else{fromMarker=this.marker2;toMarker=this.marker1;}
+var fromTs=fromMarker.ts,toTs=toMarker.ts;if(fromDomainId==ClockDomainId.BATTOR&&toDomainId==ClockDomainId.TRACE_EVENT_IMPORTER){toTs=toMarker.startTs;}else if(fromDomainId==ClockDomainId.TRACE_EVENT_IMPORTER&&toDomainId==ClockDomainId.BATTOR){fromTs=fromMarker.startTs;}
+var tsShift=toTs-fromTs;return function(ts){return ts+tsShift;};},isBetween:function(domain1Id,domain2Id){if(this.marker1===undefined||this.marker2===undefined)
+return false;if(this.marker1.domainId===domain1Id&&this.marker2.domainId===domain2Id){return true;}
+if(this.marker1.domainId===domain2Id&&this.marker2.domainId===domain1Id){return true;}
+return false;}};return{ClockDomainId:ClockDomainId,ClockSyncManager:ClockSyncManager};});'use strict';tr.exportTo('tr.model',function(){function EventContainer(){this.guid_=tr.b.GUID.allocate();this.important=true;this.bounds_=new tr.b.Range();}
+EventContainer.prototype={get guid(){return this.guid_;},get stableId(){throw new Error('Not implemented');},get bounds(){return this.bounds_;},updateBounds:function(){throw new Error('Not implemented');},shiftTimestampsForward:function(amount){throw new Error('Not implemented');},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){throw new Error('Not implemented');},iterateAllChildEventContainers:function(callback,opt_this){throw new Error('Not implemented');},iterateAllEvents:function(callback,opt_this){this.iterateAllEventContainers(function(ec){ec.iterateAllEventsInThisContainer(function(eventType){return true;},callback,opt_this);});},iterateAllEventContainers:function(callback,opt_this){function visit(ec){callback.call(opt_this,ec);ec.iterateAllChildEventContainers(visit);}
+visit(this);}};return{EventContainer:EventContainer};});'use strict';tr.exportTo('tr.model',function(){var Event=tr.model.Event;var EventRegistry=tr.model.EventRegistry;function PowerSample(series,start,power){Event.call(this);this.series_=series;this.start_=start;this.power_=power;}
+PowerSample.prototype={__proto__:Event.prototype,get series(){return this.series_;},get start(){return this.start_;},set start(value){this.start_=value;},get power(){return this.power_;},set power(value){this.power_=value;},addBoundsToRange:function(range){range.addValue(this.start);}};EventRegistry.register(PowerSample,{name:'powerSample',pluralName:'powerSamples',singleViewElementName:'tr-ui-a-single-power-sample-sub-view',multiViewElementName:'tr-ui-a-multi-power-sample-sub-view'});return{PowerSample:PowerSample};});'use strict';tr.exportTo('tr.model',function(){var PowerSample=tr.model.PowerSample;function PowerSeries(device){tr.model.EventContainer.call(this);this.device_=device;this.samples_=[];}
+PowerSeries.prototype={__proto__:tr.model.EventContainer.prototype,get device(){return this.device_;},get samples(){return this.samples_;},get stableId(){return this.device_.stableId+'.PowerSeries';},addPowerSample:function(ts,val){var sample=new PowerSample(this,ts,val);this.samples_.push(sample);return sample;},getEnergyConsumed:function(start,end){var measurementRange=tr.b.Range.fromExplicitRange(start,end);var energyConsumed=0;for(var i=0;i<this.samples.length;i++){var sample=this.samples[i];var nextSample=this.samples[i+1];var sampleRange=new tr.b.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:Infinity);var timeIntersection=measurementRange.findIntersection(sampleRange);var powerInWatts=sample.power/1000.0;var durationInSeconds=timeIntersection.duration/1000;energyConsumed+=durationInSeconds*powerInWatts;}
+return energyConsumed;},shiftTimestampsForward:function(amount){for(var i=0;i<this.samples_.length;++i)
+this.samples_[i].start+=amount;},updateBounds:function(){this.bounds.reset();if(this.samples_.length===0)
+return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,PowerSample))
+this.samples_.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){}};return{PowerSeries:PowerSeries};});'use strict';tr.exportTo('tr.model',function(){function Device(model){if(!model)
+throw new Error('Must provide a model.');tr.model.EventContainer.call(this);this.powerSeries_=undefined;this.vSyncTimestamps_=[];};Device.compare=function(x,y){return x.guid-y.guid;};Device.prototype={__proto__:tr.model.EventContainer.prototype,compareTo:function(that){return Device.compare(this,that);},get userFriendlyName(){return'Device';},get userFriendlyDetails(){return'Device';},get stableId(){return'Device';},getSettingsKey:function(){return'device';},get powerSeries(){return this.powerSeries_;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;},get vSyncTimestamps(){return this.vSyncTimestamps_;},set vSyncTimestamps(value){this.vSyncTimestamps_=value;},updateBounds:function(){this.bounds.reset();this.iterateAllChildEventContainers(function(child){child.updateBounds();this.bounds.addRange(child.bounds);},this);},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});for(var i=0;i<this.vSyncTimestamps_.length;i++)
+this.vSyncTimestamps_[i]+=amount;},addCategoriesToDict:function(categoriesDict){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){if(this.powerSeries_)
+callback.call(opt_this,this.powerSeries_);}};return{Device:Device};});'use strict';tr.exportTo('tr.model',function(){function FlowEvent(category,id,title,colorId,start,args,opt_duration){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.id=id;this.startSlice=undefined;this.endSlice=undefined;this.startStackFrame=undefined;this.endStackFrame=undefined;if(opt_duration!==undefined)
+this.duration=opt_duration;}
+FlowEvent.prototype={__proto__:tr.model.TimedEvent.prototype,get userFriendlyName(){return'Flow event named '+this.title+' at '+
+tr.v.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(FlowEvent,{name:'flowEvent',pluralName:'flowEvents',singleViewElementName:'tr-ui-a-single-flow-event-sub-view',multiViewElementName:'tr-ui-a-multi-flow-event-sub-view'});return{FlowEvent:FlowEvent};});'use strict';tr.exportTo('tr.model',function(){function ContainerMemoryDump(start){tr.model.TimedEvent.call(this,start);this.levelOfDetail=undefined;this.memoryAllocatorDumps_=undefined;this.memoryAllocatorDumpsByFullName_=undefined;};ContainerMemoryDump.LevelOfDetail={LIGHT:0,DETAILED:1};ContainerMemoryDump.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();},getMemoryAllocatorDumpByFullName:function(fullName){if(this.memoryAllocatorDumps_===undefined)
+return undefined;if(this.memoryAllocatorDumpsByFullName_===undefined){var index={};function addDumpsToIndex(dumps){dumps.forEach(function(dump){index[dump.fullName]=dump;addDumpsToIndex(dump.children);});};addDumpsToIndex(this.memoryAllocatorDumps_);this.memoryAllocatorDumpsByFullName_=index;}
+return this.memoryAllocatorDumpsByFullName_[fullName];},forceRebuildingMemoryAllocatorDumpByFullNameIndex:function(){this.memoryAllocatorDumpsByFullName_=undefined;},iterateRootAllocatorDumps:function(fn,opt_this){if(this.memoryAllocatorDumps===undefined)
+return;this.memoryAllocatorDumps.forEach(fn,opt_this||this);}};return{ContainerMemoryDump:ContainerMemoryDump};});'use strict';tr.exportTo('tr.model',function(){function MemoryAllocatorDump(containerMemoryDump,fullName,opt_guid){this.fullName=fullName;this.parent=undefined;this.children=[];this.numerics={};this.diagnostics={};this.containerMemoryDump=containerMemoryDump;this.owns=undefined;this.ownedBy=[];this.ownedBySiblingSizes=new Map();this.retains=[];this.retainedBy=[];this.weak=false;this.infos=[];this.guid=opt_guid;};MemoryAllocatorDump.SIZE_NUMERIC_NAME='size';MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME='effective_size';MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME='resident_size';MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME=MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;MemoryAllocatorDump.prototype={get name(){return this.fullName.substring(this.fullName.lastIndexOf('/')+1);},get quantifiedName(){return'\''+this.fullName+'\' in '+
+this.containerMemoryDump.containerName;},isDescendantOf:function(otherDump){var dump=this;while(dump!==undefined){if(dump===otherDump)
+return true;dump=dump.parent;}
+return false;},addNumeric:function(name,numeric){if(!(numeric instanceof tr.v.ScalarNumeric))
+throw new Error('Numeric value must be an instance of ScalarNumeric.');if(name in this.numerics)
+throw new Error('Duplicate numeric name: '+name+'.');this.numerics[name]=numeric;},addDiagnostic:function(name,text){if(typeof text!=='string')
+throw new Error('Diagnostic text must be a string.');if(name in this.diagnostics)
+throw new Error('Duplicate diagnostic name: '+name+'.');this.diagnostics[name]=text;},aggregateNumericsRecursively:function(opt_model){var numericNames=new Set();this.children.forEach(function(child){child.aggregateNumericsRecursively(opt_model);tr.b.iterItems(child.numerics,numericNames.add,numericNames);},this);numericNames.forEach(function(numericName){if(numericName===MemoryAllocatorDump.SIZE_NUMERIC_NAME||numericName===MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME||this.numerics[numericName]!==undefined){return;}
+this.numerics[numericName]=MemoryAllocatorDump.aggregateNumerics(this.children.map(function(child){return child.numerics[numericName];}),opt_model);},this);}};MemoryAllocatorDump.aggregateNumerics=function(numerics,opt_model){var shouldLogWarning=!!opt_model;var aggregatedUnit=undefined;var aggregatedValue=0;numerics.forEach(function(numeric){if(numeric===undefined)
+return;var unit=numeric.unit;if(aggregatedUnit===undefined){aggregatedUnit=unit;}else if(aggregatedUnit!==unit){if(shouldLogWarning){opt_model.importWarning({type:'numeric_parse_error',message:'Multiple units provided for numeric: \''+
+aggregatedUnit.unitName+'\' and \''+unit.unitName+'\'.'});shouldLogWarning=false;}
+aggregatedUnit=tr.v.Unit.byName.unitlessNumber_smallerIsBetter;}
+aggregatedValue+=numeric.value;},this);if(aggregatedUnit===undefined)
+return undefined;return new tr.v.ScalarNumeric(aggregatedUnit,aggregatedValue);};function MemoryAllocatorDumpLink(source,target,opt_importance){this.source=source;this.target=target;this.importance=opt_importance;this.size=undefined;}
+var MemoryAllocatorDumpInfoType={PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:0,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:1};return{MemoryAllocatorDump:MemoryAllocatorDump,MemoryAllocatorDumpLink:MemoryAllocatorDumpLink,MemoryAllocatorDumpInfoType:MemoryAllocatorDumpInfoType};});'use strict';tr.exportTo('tr.model',function(){function GlobalMemoryDump(model,start){tr.model.ContainerMemoryDump.call(this,start);this.model=model;this.processMemoryDumps={};}
+var SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;var EFFECTIVE_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;var MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;var PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;var PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;function inPlaceFilter(array,predicate,opt_this){opt_this=opt_this||this;var nextPosition=0;for(var i=0;i<array.length;i++){if(!predicate.call(opt_this,array[i],i))
+continue;if(nextPosition<i)
+array[nextPosition]=array[i];nextPosition++;}
+if(nextPosition<array.length)
+array.length=nextPosition;}
+function getSize(dump){var numeric=dump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)
+return 0;return numeric.value;}
+function hasSize(dump){return dump.numerics[SIZE_NUMERIC_NAME]!==undefined;}
+function optional(value,defaultValue){if(value===undefined)
+return defaultValue;return value;}
+GlobalMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Global memory dump at '+
+tr.v.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return'global space';},finalizeGraph:function(){this.removeWeakDumps();this.setUpTracingOverheadOwnership();this.aggregateNumerics();this.calculateSizes();this.calculateEffectiveSizes();this.discountTracingOverheadFromVmRegions();this.forceRebuildingMemoryAllocatorDumpByFullNameIndices();},removeWeakDumps:function(){this.traverseAllocatorDumpsInDepthFirstPreOrder(function(dump){if(dump.weak)
+return;if((dump.owns!==undefined&&dump.owns.target.weak)||(dump.parent!==undefined&&dump.parent.weak)){dump.weak=true;}});function removeWeakDumpsFromListRecursively(dumps){inPlaceFilter(dumps,function(dump){if(dump.weak){return false;}
+removeWeakDumpsFromListRecursively(dump.children);inPlaceFilter(dump.ownedBy,function(ownershipLink){return!ownershipLink.source.weak;});return true;});}
+this.iterateContainerDumps(function(containerDump){var memoryAllocatorDumps=containerDump.memoryAllocatorDumps;if(memoryAllocatorDumps!==undefined)
+removeWeakDumpsFromListRecursively(memoryAllocatorDumps);});},calculateSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateMemoryAllocatorDumpSize_.bind(this));},calculateMemoryAllocatorDumpSize_:function(dump){var shouldDefineSize=false;function getDependencySize(dependencyDump){var numeric=dependencyDump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)
+return 0;shouldDefineSize=true;return numeric.value;}
+var sizeNumeric=dump.numerics[SIZE_NUMERIC_NAME];var size=0;var checkDependencySizeIsConsistent=function(){};if(sizeNumeric!==undefined){size=sizeNumeric.value;shouldDefineSize=true;if(sizeNumeric.unit!==tr.v.Unit.byName.sizeInBytes_smallerIsBetter){this.model.importWarning({type:'memory_dump_parse_error',message:'Invalid unit of \'size\' numeric of memory allocator '+'dump '+dump.quantifiedName+': '+
+sizeNumeric.unit.unitName+'.'});}
+checkDependencySizeIsConsistent=function(dependencySize,dependencyInfoType,dependencyName){if(size>=dependencySize)
+return;this.model.importWarning({type:'memory_dump_parse_error',message:'Size provided by memory allocator dump \''+
+dump.fullName+'\''+
+tr.v.Unit.byName.sizeInBytes.format(size)+') is less than '+dependencyName+' ('+
+tr.v.Unit.byName.sizeInBytes.format(dependencySize)+').'});dump.infos.push({type:dependencyInfoType,providedSize:size,dependencySize:dependencySize});}.bind(this);}
+var aggregatedChildrenSize=0;var allOverlaps={};dump.children.forEach(function(childDump){function aggregateDescendantDump(descendantDump){var ownedDumpLink=descendantDump.owns;if(ownedDumpLink!==undefined&&ownedDumpLink.target.isDescendantOf(dump)){var ownedChildDump=ownedDumpLink.target;while(ownedChildDump.parent!==dump)
+ownedChildDump=ownedChildDump.parent;if(childDump!==ownedChildDump){var ownedBySiblingSize=getDependencySize(descendantDump);if(ownedBySiblingSize>0){var previousTotalOwnedBySiblingSize=ownedChildDump.ownedBySiblingSizes.get(childDump)||0;var updatedTotalOwnedBySiblingSize=previousTotalOwnedBySiblingSize+ownedBySiblingSize;ownedChildDump.ownedBySiblingSizes.set(childDump,updatedTotalOwnedBySiblingSize);}}
+return;}
+if(descendantDump.children.length===0){aggregatedChildrenSize+=getDependencySize(descendantDump);return;}
+descendantDump.children.forEach(aggregateDescendantDump);}
+aggregateDescendantDump(childDump);});checkDependencySizeIsConsistent(aggregatedChildrenSize,PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN,'the aggregated size of its children');var largestOwnerSize=0;dump.ownedBy.forEach(function(ownershipLink){var owner=ownershipLink.source;var ownerSize=getDependencySize(owner);largestOwnerSize=Math.max(largestOwnerSize,ownerSize);});checkDependencySizeIsConsistent(largestOwnerSize,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER,'the size of its largest owner');if(!shouldDefineSize){delete dump.numerics[SIZE_NUMERIC_NAME];return;}
+size=Math.max(size,aggregatedChildrenSize,largestOwnerSize);dump.numerics[SIZE_NUMERIC_NAME]=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,size);if(aggregatedChildrenSize<size&&dump.children!==undefined&&dump.children.length>0){var virtualChild=new tr.model.MemoryAllocatorDump(dump.containerMemoryDump,dump.fullName+'/<unspecified>');virtualChild.parent=dump;dump.children.unshift(virtualChild);virtualChild.numerics[SIZE_NUMERIC_NAME]=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,size-aggregatedChildrenSize);}},calculateEffectiveSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpSubSizes_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPreOrder(this.calculateDumpCumulativeOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpEffectiveSize_.bind(this));},calculateDumpSubSizes_:function(dump){if(!hasSize(dump))
+return;if(dump.children===undefined||dump.children.length===0){var size=getSize(dump);dump.notOwningSubSize_=size;dump.notOwnedSubSize_=size;return;}
+var notOwningSubSize=0;dump.children.forEach(function(childDump){if(childDump.owns!==undefined)
+return;notOwningSubSize+=optional(childDump.notOwningSubSize_,0);});dump.notOwningSubSize_=notOwningSubSize;var notOwnedSubSize=0;dump.children.forEach(function(childDump){if(childDump.ownedBy.length===0){notOwnedSubSize+=optional(childDump.notOwnedSubSize_,0);return;}
+var largestChildOwnerSize=0;childDump.ownedBy.forEach(function(ownershipLink){largestChildOwnerSize=Math.max(largestChildOwnerSize,getSize(ownershipLink.source));});notOwnedSubSize+=getSize(childDump)-largestChildOwnerSize;});dump.notOwnedSubSize_=notOwnedSubSize;},calculateDumpOwnershipCoefficient_:function(dump){if(!hasSize(dump))
+return;if(dump.ownedBy.length===0)
+return;var owners=dump.ownedBy.map(function(ownershipLink){return{dump:ownershipLink.source,importance:optional(ownershipLink.importance,0),notOwningSubSize:optional(ownershipLink.source.notOwningSubSize_,0)};});owners.sort(function(a,b){if(a.importance===b.importance)
+return a.notOwningSubSize-b.notOwningSubSize;return b.importance-a.importance;});var currentImportanceStartPos=0;var alreadyAttributedSubSize=0;while(currentImportanceStartPos<owners.length){var currentImportance=owners[currentImportanceStartPos].importance;var nextImportanceStartPos=currentImportanceStartPos+1;while(nextImportanceStartPos<owners.length&&owners[nextImportanceStartPos].importance===currentImportance){nextImportanceStartPos++;}
+var attributedNotOwningSubSize=0;for(var pos=currentImportanceStartPos;pos<nextImportanceStartPos;pos++){var owner=owners[pos];var notOwningSubSize=owner.notOwningSubSize;if(notOwningSubSize>alreadyAttributedSubSize){attributedNotOwningSubSize+=(notOwningSubSize-alreadyAttributedSubSize)/(nextImportanceStartPos-pos);alreadyAttributedSubSize=notOwningSubSize;}
+var owningCoefficient=0;if(notOwningSubSize!==0)
+owningCoefficient=attributedNotOwningSubSize/notOwningSubSize;owner.dump.owningCoefficient_=owningCoefficient;}
+currentImportanceStartPos=nextImportanceStartPos;}
+var notOwnedSubSize=optional(dump.notOwnedSubSize_,0);var remainderSubSize=notOwnedSubSize-alreadyAttributedSubSize;var ownedCoefficient=0;if(notOwnedSubSize!==0)
+ownedCoefficient=remainderSubSize/notOwnedSubSize;dump.ownedCoefficient_=ownedCoefficient;},calculateDumpCumulativeOwnershipCoefficient_:function(dump){if(!hasSize(dump))
+return;var cumulativeOwnedCoefficient=optional(dump.ownedCoefficient_,1);var parent=dump.parent;if(dump.parent!==undefined)
+cumulativeOwnedCoefficient*=dump.parent.cumulativeOwnedCoefficient_;dump.cumulativeOwnedCoefficient_=cumulativeOwnedCoefficient;var cumulativeOwningCoefficient;if(dump.owns!==undefined){cumulativeOwningCoefficient=dump.owningCoefficient_*dump.owns.target.cumulativeOwningCoefficient_;}else if(dump.parent!==undefined){cumulativeOwningCoefficient=dump.parent.cumulativeOwningCoefficient_;}else{cumulativeOwningCoefficient=1;}
+dump.cumulativeOwningCoefficient_=cumulativeOwningCoefficient;},calculateDumpEffectiveSize_:function(dump){if(!hasSize(dump)){delete dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME];return;}
+var effectiveSize;if(dump.children===undefined||dump.children.length===0){effectiveSize=getSize(dump)*dump.cumulativeOwningCoefficient_*dump.cumulativeOwnedCoefficient_;}else{effectiveSize=0;dump.children.forEach(function(childDump){if(!hasSize(childDump))
+return;effectiveSize+=childDump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME].value;});}
+dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME]=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,effectiveSize);},aggregateNumerics:function(){this.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);});this.iterateRootAllocatorDumps(this.propagateNumericsAndDiagnosticsRecursively);tr.b.iterItems(this.processMemoryDumps,function(pid,processMemoryDump){processMemoryDump.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);},this);},this);},propagateNumericsAndDiagnosticsRecursively:function(globalAllocatorDump){['numerics','diagnostics'].forEach(function(field){tr.b.iterItems(globalAllocatorDump[field],function(name,value){globalAllocatorDump.ownedBy.forEach(function(ownershipLink){var processAllocatorDump=ownershipLink.source;if(processAllocatorDump[field][name]!==undefined){return;}
+processAllocatorDump[field][name]=value;});});});globalAllocatorDump.children.forEach(this.propagateNumericsAndDiagnosticsRecursively,this);},setUpTracingOverheadOwnership:function(){tr.b.iterItems(this.processMemoryDumps,function(pid,dump){dump.setUpTracingOverheadOwnership(this.model);},this);},discountTracingOverheadFromVmRegions:function(){tr.b.iterItems(this.processMemoryDumps,function(pid,dump){dump.discountTracingOverheadFromVmRegions(this.model);},this);},forceRebuildingMemoryAllocatorDumpByFullNameIndices:function(){this.iterateContainerDumps(function(containerDump){containerDump.forceRebuildingMemoryAllocatorDumpByFullNameIndex();});},iterateContainerDumps:function(fn){fn.call(this,this);tr.b.iterItems(this.processMemoryDumps,function(pid,processDump){fn.call(this,processDump);},this);},iterateAllRootAllocatorDumps:function(fn){this.iterateContainerDumps(function(containerDump){containerDump.iterateRootAllocatorDumps(fn,this);});},traverseAllocatorDumpsInDepthFirstPostOrder:function(fn){var visitedDumps=new WeakSet();var openDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
+return;if(openDumps.has(dump))
+throw new Error(dump.userFriendlyName+' contains a cycle');openDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);fn.call(this,dump);visitedDumps.add(dump);openDumps.delete(dump);}
+this.iterateAllRootAllocatorDumps(visit);},traverseAllocatorDumpsInDepthFirstPreOrder:function(fn){var visitedDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
+return;if(dump.owns!==undefined&&!visitedDumps.has(dump.owns.target))
+return;if(dump.parent!==undefined&&!visitedDumps.has(dump.parent))
+return;fn.call(this,dump);visitedDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);}
+this.iterateAllRootAllocatorDumps(visit);}};tr.model.EventRegistry.register(GlobalMemoryDump,{name:'globalMemoryDump',pluralName:'globalMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{GlobalMemoryDump:GlobalMemoryDump};});'use strict';tr.exportTo('tr.model',function(){var InstantEventType={GLOBAL:1,PROCESS:2};function InstantEvent(category,title,colorId,start,args){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.type=undefined;};InstantEvent.prototype={__proto__:tr.model.TimedEvent.prototype};function GlobalInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.GLOBAL;};GlobalInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Global instant event '+this.title+' @ '+
+tr.v.Unit.byName.timeStampInMs.format(start);}};function ProcessInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.PROCESS;};ProcessInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Process-level instant event '+this.title+' @ '+
+tr.v.Unit.byName.timeStampInMs.format(start);}};tr.model.EventRegistry.register(InstantEvent,{name:'instantEvent',pluralName:'instantEvents',singleViewElementName:'tr-ui-a-single-instant-event-sub-view',multiViewElementName:'tr-ui-a-multi-instant-event-sub-view'});return{GlobalInstantEvent:GlobalInstantEvent,ProcessInstantEvent:ProcessInstantEvent,InstantEventType:InstantEventType,InstantEvent:InstantEvent};});'use strict';tr.exportTo('tr.model',function(){function CounterSample(series,timestamp,value){tr.model.Event.call(this);this.series_=series;this.timestamp_=timestamp;this.value_=value;}
+CounterSample.groupByTimestamp=function(samples){var samplesByTimestamp=tr.b.group(samples,function(sample){return sample.timestamp;});var timestamps=tr.b.dictionaryKeys(samplesByTimestamp);timestamps.sort();var groups=[];for(var i=0;i<timestamps.length;i++){var ts=timestamps[i];var group=samplesByTimestamp[ts];group.sort(function(x,y){return x.series.seriesIndex-y.series.seriesIndex;});groups.push(group);}
+return groups;};CounterSample.prototype={__proto__:tr.model.Event.prototype,get series(){return this.series_;},get timestamp(){return this.timestamp_;},get value(){return this.value_;},set timestamp(timestamp){this.timestamp_=timestamp;},addBoundsToRange:function(range){range.addValue(this.timestamp);},getSampleIndex:function(){return tr.b.findLowIndexInSortedArray(this.series.timestamps,function(x){return x;},this.timestamp_);},get userFriendlyName(){return'Counter sample from '+this.series_.title+' at '+
+tr.v.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(CounterSample,{name:'counterSample',pluralName:'counterSamples',singleViewElementName:'tr-ui-a-counter-sample-sub-view',multiViewElementName:'tr-ui-a-counter-sample-sub-view'});return{CounterSample:CounterSample};});'use strict';tr.exportTo('tr.model',function(){var CounterSample=tr.model.CounterSample;function CounterSeries(name,color){tr.model.EventContainer.call(this);this.name_=name;this.color_=color;this.timestamps_=[];this.samples_=[];this.counter=undefined;this.seriesIndex=undefined;}
+CounterSeries.prototype={__proto__:tr.model.EventContainer.prototype,get length(){return this.timestamps_.length;},get name(){return this.name_;},get color(){return this.color_;},get samples(){return this.samples_;},get timestamps(){return this.timestamps_;},getSample:function(idx){return this.samples_[idx];},getTimestamp:function(idx){return this.timestamps_[idx];},addCounterSample:function(ts,val){var sample=new CounterSample(this,ts,val);this.addSample(sample);return sample;},addSample:function(sample){this.timestamps_.push(sample.timestamp);this.samples_.push(sample);},getStatistics:function(sampleIndices){var sum=0;var min=Number.MAX_VALUE;var max=-Number.MAX_VALUE;for(var i=0;i<sampleIndices.length;++i){var sample=this.getSample(sampleIndices[i]).value;sum+=sample;min=Math.min(sample,min);max=Math.max(sample,max);}
+return{min:min,max:max,avg:(sum/sampleIndices.length),start:this.getSample(sampleIndices[0]).value,end:this.getSample(sampleIndices.length-1).value};},shiftTimestampsForward:function(amount){for(var i=0;i<this.timestamps_.length;++i){this.timestamps_[i]+=amount;this.samples_[i].timestamp=this.timestamps_[i];}},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.CounterSample)){this.samples_.forEach(callback,opt_this);}},iterateAllChildEventContainers:function(callback,opt_this){}};return{CounterSeries:CounterSeries};});'use strict';tr.exportTo('tr.model',function(){function Counter(parent,id,category,name){tr.model.EventContainer.call(this);this.parent_=parent;this.id_=id;this.category_=category||'';this.name_=name;this.series_=[];this.totals=[];}
+Counter.prototype={__proto__:tr.model.EventContainer.prototype,get parent(){return this.parent_;},get id(){return this.id_;},get category(){return this.category_;},get name(){return this.name_;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){for(var i=0;i<this.series_.length;i++)
+callback.call(opt_this,this.series_[i]);},set timestamps(arg){throw new Error('Bad counter API. No cookie.');},set seriesNames(arg){throw new Error('Bad counter API. No cookie.');},set seriesColors(arg){throw new Error('Bad counter API. No cookie.');},set samples(arg){throw new Error('Bad counter API. No cookie.');},addSeries:function(series){series.counter=this;series.seriesIndex=this.series_.length;this.series_.push(series);return series;},getSeries:function(idx){return this.series_[idx];},get series(){return this.series_;},get numSeries(){return this.series_.length;},get numSamples(){if(this.series_.length===0)
+return 0;return this.series_[0].length;},get timestamps(){if(this.series_.length===0)
+return[];return this.series_[0].timestamps;},getSampleStatistics:function(sampleIndices){sampleIndices.sort();var ret=[];this.series_.forEach(function(series){ret.push(series.getStatistics(sampleIndices));});return ret;},shiftTimestampsForward:function(amount){for(var i=0;i<this.series_.length;++i)
+this.series_[i].shiftTimestampsForward(amount);},updateBounds:function(){this.totals=[];this.maxTotal=0;this.bounds.reset();if(this.series_.length===0)
+return;var firstSeries=this.series_[0];var lastSeries=this.series_[this.series_.length-1];this.bounds.addValue(firstSeries.getTimestamp(0));this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length-1));var numSeries=this.numSeries;this.maxTotal=-Infinity;for(var i=0;i<firstSeries.length;++i){var total=0;this.series_.forEach(function(series){total+=series.getSample(i).value;this.totals.push(total);}.bind(this));this.maxTotal=Math.max(total,this.maxTotal);}}};Counter.compare=function(x,y){var tmp=x.parent.compareTo(y);if(tmp!=0)
+return tmp;var tmp=x.name.localeCompare(y.name);if(tmp==0)
+return x.tid-y.tid;return tmp;};return{Counter:Counter};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function CpuSlice(cat,title,colorId,start,args,opt_duration){Slice.apply(this,arguments);this.threadThatWasRunning=undefined;this.cpu=undefined;}
 CpuSlice.prototype={__proto__:Slice.prototype,get analysisTypeName(){return'tr.ui.analysis.CpuSlice';},getAssociatedTimeslice:function(){if(!this.threadThatWasRunning)
 return undefined;var timeSlices=this.threadThatWasRunning.timeSlices;for(var i=0;i<timeSlices.length;i++){var timeSlice=timeSlices[i];if(timeSlice.start!==this.start)
 continue;if(timeSlice.duration!==this.duration)
@@ -3324,61 +3869,36 @@
 stats[freqSample.value]=0;stats[freqSample.value]+=intersection.duration;}
 var freqCounter=this.getCounter('','Clock Frequency');if(freqCounter!==undefined){var freqSeries=freqCounter.getSeries(0);if(!freqSeries)
 return;tr.b.iterateOverIntersectingIntervals(freqSeries.samples_,function(x){return x.timestamp;},function(x,index){return index<freqSeries.length-1?freqSeries.samples_[index+1].timestamp:range.max;},range.min,range.max,addStatsForFreq);}
-return stats;}};Cpu.compare=function(x,y){return x.cpuNumber-y.cpuNumber;};return{Cpu:Cpu};});'use strict';tr.exportTo('tr.model',function(){function ObjectSnapshot(objectInstance,ts,args){tr.model.Event.call(this);this.objectInstance=objectInstance;this.ts=ts;this.args=args;}
-ObjectSnapshot.prototype={__proto__:tr.model.Event.prototype,preInitialize:function(){},initialize:function(){},addBoundsToRange:function(range){range.addValue(this.ts);},get userFriendlyName(){return'Snapshot of '+
-this.objectInstance.typeName+' '+
-this.objectInstance.id+' @ '+
-tr.b.u.TimeStamp.format(this.ts);}};tr.model.EventRegistry.register(ObjectSnapshot,{name:'objectSnapshot',pluralName:'objectSnapshots',singleViewElementName:'tr-ui-a-single-object-snapshot-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshot;options.defaultConstructor=ObjectSnapshot;tr.b.decorateExtensionRegistry(ObjectSnapshot,options);return{ObjectSnapshot:ObjectSnapshot};});'use strict';tr.exportTo('tr.model',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectInstance(parent,id,category,name,creationTs,opt_baseTypeName){tr.model.Event.call(this);this.parent=parent;this.id=id;this.category=category;this.baseTypeName=opt_baseTypeName?opt_baseTypeName:name;this.name=name;this.creationTs=creationTs;this.creationTsWasExplicit=false;this.deletionTs=Number.MAX_VALUE;this.deletionTsWasExplicit=false;this.colorId=0;this.bounds=new tr.b.Range();this.snapshots=[];this.hasImplicitSnapshots=false;}
-ObjectInstance.prototype={__proto__:tr.model.Event.prototype,get typeName(){return this.name;},addBoundsToRange:function(range){range.addRange(this.bounds);},addSnapshot:function(ts,args,opt_name,opt_baseTypeName){if(ts<this.creationTs)
-throw new Error('Snapshots must be >= instance.creationTs');if(ts>=this.deletionTs)
-throw new Error('Snapshots cannot be added after '+'an objects deletion timestamp.');var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts==ts)
-throw new Error('Snapshots already exists at this time!');if(ts<lastSnapshot.ts){throw new Error('Snapshots must be added in increasing timestamp order');}}
-if(opt_name&&(this.name!=opt_name)){if(!opt_baseTypeName)
-throw new Error('Must provide base type name for name update');if(this.baseTypeName!=opt_baseTypeName)
-throw new Error('Cannot update type name: base types dont match');this.name=opt_name;}
-var snapshotConstructor=tr.model.ObjectSnapshot.getConstructor(this.category,this.name);var snapshot=new snapshotConstructor(this,ts,args);this.snapshots.push(snapshot);return snapshot;},wasDeleted:function(ts){var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts>ts)
-throw new Error('Instance cannot be deleted at ts='+
-ts+'. A snapshot exists that is older.');}
-this.deletionTs=ts;this.deletionTsWasExplicit=true;},preInitialize:function(){for(var i=0;i<this.snapshots.length;i++)
-this.snapshots[i].preInitialize();},initialize:function(){for(var i=0;i<this.snapshots.length;i++)
-this.snapshots[i].initialize();},getSnapshotAt:function(ts){if(ts<this.creationTs){if(this.creationTsWasExplicit)
-throw new Error('ts must be within lifetime of this instance');return this.snapshots[0];}
-if(ts>this.deletionTs)
-throw new Error('ts must be within lifetime of this instance');var snapshots=this.snapshots;var i=tr.b.findIndexInSortedIntervals(snapshots,function(snapshot){return snapshot.ts;},function(snapshot,i){if(i==snapshots.length-1)
-return snapshots[i].objectInstance.deletionTs;return snapshots[i+1].ts-snapshots[i].ts;},ts);if(i<0){return this.snapshots[0];}
-if(i>=this.snapshots.length)
-return this.snapshots[this.snapshots.length-1];return this.snapshots[i];},updateBounds:function(){this.bounds.reset();this.bounds.addValue(this.creationTs);if(this.deletionTs!=Number.MAX_VALUE)
-this.bounds.addValue(this.deletionTs);else if(this.snapshots.length>0)
-this.bounds.addValue(this.snapshots[this.snapshots.length-1].ts);},shiftTimestampsForward:function(amount){this.creationTs+=amount;if(this.deletionTs!=Number.MAX_VALUE)
-this.deletionTs+=amount;this.snapshots.forEach(function(snapshot){snapshot.ts+=amount;});},get userFriendlyName(){return this.typeName+' object '+this.id;}};tr.model.EventRegistry.register(ObjectInstance,{name:'objectInstance',pluralName:'objectInstances',singleViewElementName:'tr-ui-a-single-object-instance-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstance;options.defaultConstructor=ObjectInstance;tr.b.decorateExtensionRegistry(ObjectInstance,options);return{ObjectInstance:ObjectInstance};});'use strict';tr.exportTo('tr.model',function(){function TimeToObjectInstanceMap(createObjectInstanceFunction,parent,id){this.createObjectInstanceFunction_=createObjectInstanceFunction;this.parent=parent;this.id=id;this.instances=[];}
-TimeToObjectInstanceMap.prototype={idWasCreated:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts));this.instances[0].creationTsWasExplicit=true;return this.instances[0];}
+return stats;}};Cpu.compare=function(x,y){return x.cpuNumber-y.cpuNumber;};return{Cpu:Cpu};});'use strict';tr.exportTo('tr.model',function(){function TimeToObjectInstanceMap(createObjectInstanceFunction,parent,scopedId){this.createObjectInstanceFunction_=createObjectInstanceFunction;this.parent=parent;this.scopedId=scopedId;this.instances=[];}
+TimeToObjectInstanceMap.prototype={idWasCreated:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));this.instances[0].creationTsWasExplicit=true;return this.instances[0];}
 var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.deletionTs){throw new Error('Mutation of the TimeToObjectInstanceMap must be '+'done in ascending timestamp order.');}
-lastInstance=this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts);lastInstance.creationTsWasExplicit=true;this.instances.push(lastInstance);return lastInstance;},addSnapshot:function(category,name,ts,args,opt_baseTypeName){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts,opt_baseTypeName));}
+lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);lastInstance.creationTsWasExplicit=true;this.instances.push(lastInstance);return lastInstance;},addSnapshot:function(category,name,ts,args,opt_baseTypeName){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName));}
 var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);var instance;if(i<0){instance=this.instances[0];if(ts>instance.deletionTs||instance.creationTsWasExplicit){throw new Error('At the provided timestamp, no instance was still alive');}
 if(instance.snapshots.length!=0){throw new Error('Cannot shift creationTs forward, '+'snapshots have been added. First snap was at ts='+
 instance.snapshots[0].ts+' and creationTs was '+
 instance.creationTs);}
-instance.creationTs=ts;}else if(i>=this.instances.length){instance=this.instances[this.instances.length-1];if(ts>=instance.deletionTs){instance=this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts,opt_baseTypeName);this.instances.push(instance);}else{var lastValidIndex;for(var i=this.instances.length-1;i>=0;i--){var tmp=this.instances[i];if(ts>=tmp.deletionTs)
+instance.creationTs=ts;}else if(i>=this.instances.length){instance=this.instances[this.instances.length-1];if(ts>=instance.deletionTs){instance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName);this.instances.push(instance);}else{var lastValidIndex;for(var i=this.instances.length-1;i>=0;i--){var tmp=this.instances[i];if(ts>=tmp.deletionTs)
 break;if(tmp.creationTsWasExplicit==false&&tmp.snapshots.length==0)
 lastValidIndex=i;}
 if(lastValidIndex===undefined){throw new Error('Cannot add snapshot. No instance was alive that was mutable.');}
 instance=this.instances[lastValidIndex];instance.creationTs=ts;}}else{instance=this.instances[i];}
 return instance.addSnapshot(ts,args,name,opt_baseTypeName);},get lastInstance(){if(this.instances.length==0)
-return undefined;return this.instances[this.instances.length-1];},idWasDeleted:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts));}
+return undefined;return this.instances[this.instances.length-1];},idWasDeleted:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));}
 var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.creationTs)
-throw new Error('Cannot delete a id before it was crated');if(lastInstance.deletionTs==Number.MAX_VALUE){lastInstance.wasDeleted(ts);return lastInstance;}
+throw new Error('Cannot delete an id before it was created');if(lastInstance.deletionTs==Number.MAX_VALUE){lastInstance.wasDeleted(ts);return lastInstance;}
 if(ts<lastInstance.deletionTs)
-throw new Error('id was already deleted earlier.');lastInstance=this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts);this.instances.push(lastInstance);lastInstance.wasDeleted(ts);return lastInstance;},getInstanceAt:function(ts){var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);if(i<0){if(this.instances[0].creationTsWasExplicit)
+throw new Error('id was already deleted earlier.');lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);this.instances.push(lastInstance);lastInstance.wasDeleted(ts);return lastInstance;},getInstanceAt:function(ts){var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);if(i<0){if(this.instances[0].creationTsWasExplicit)
 return undefined;return this.instances[0];}else if(i>=this.instances.length){return undefined;}
 return this.instances[i];},logToConsole:function(){for(var i=0;i<this.instances.length;i++){var instance=this.instances[i];var cEF='';var dEF='';if(instance.creationTsWasExplicit)
 cEF='(explicitC)';if(instance.deletionTsWasExplicit)
-dEF='(explicit)';console.log(instance.creationTs,cEF,instance.deletionTs,dEF,instance.category,instance.name,instance.snapshots.length+' snapshots');}}};return{TimeToObjectInstanceMap:TimeToObjectInstanceMap};});'use strict';tr.exportTo('tr.model',function(){var ObjectInstance=tr.model.ObjectInstance;var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectCollection(parent){tr.model.EventContainer.call(this);this.parent=parent;this.instanceMapsById_={};this.instancesByTypeName_={};this.createObjectInstance_=this.createObjectInstance_.bind(this);}
+dEF='(explicit)';console.log(instance.creationTs,cEF,instance.deletionTs,dEF,instance.category,instance.name,instance.snapshots.length+' snapshots');}}};return{TimeToObjectInstanceMap:TimeToObjectInstanceMap};});'use strict';tr.exportTo('tr.model',function(){var ObjectInstance=tr.model.ObjectInstance;var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectCollection(parent){tr.model.EventContainer.call(this);this.parent=parent;this.instanceMapsByScopedId_={};this.instancesByTypeName_={};this.createObjectInstance_=this.createObjectInstance_.bind(this);}
 ObjectCollection.prototype={__proto__:tr.model.EventContainer.prototype,iterateAllChildEventContainers:function(callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){var bI=!!eventTypePredicate.call(opt_this,ObjectInstance);var bS=!!eventTypePredicate.call(opt_this,ObjectSnapshot);if(bI===false&&bS===false)
 return;this.iterObjectInstances(function(instance){if(bI)
 callback.call(opt_this,instance);if(bS)
-instance.snapshots.forEach(callback,opt_this);},opt_this);},createObjectInstance_:function(parent,id,category,name,creationTs,opt_baseTypeName){var constructor=tr.model.ObjectInstance.getConstructor(category,name);var instance=new constructor(parent,id,category,name,creationTs,opt_baseTypeName);var typeName=instance.typeName;var instancesOfTypeName=this.instancesByTypeName_[typeName];if(!instancesOfTypeName){instancesOfTypeName=[];this.instancesByTypeName_[typeName]=instancesOfTypeName;}
-instancesOfTypeName.push(instance);return instance;},getOrCreateInstanceMap_:function(id){var instanceMap=this.instanceMapsById_[id];if(instanceMap)
-return instanceMap;instanceMap=new tr.model.TimeToObjectInstanceMap(this.createObjectInstance_,this.parent,id);this.instanceMapsById_[id]=instanceMap;return instanceMap;},idWasCreated:function(id,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(id);return instanceMap.idWasCreated(category,name,ts);},addSnapshot:function(id,category,name,ts,args,opt_baseTypeName){var instanceMap=this.getOrCreateInstanceMap_(id);var snapshot=instanceMap.addSnapshot(category,name,ts,args,opt_baseTypeName);if(snapshot.objectInstance.category!=category){var msg='Added snapshot name='+name+' with cat='+category+' impossible. It instance was created/snapshotted with cat='+
+instance.snapshots.forEach(callback,opt_this);},opt_this);},createObjectInstance_:function(parent,scopedId,category,name,creationTs,opt_baseTypeName){var constructor=tr.model.ObjectInstance.getConstructor(category,name);var instance=new constructor(parent,scopedId,category,name,creationTs,opt_baseTypeName);var typeName=instance.typeName;var instancesOfTypeName=this.instancesByTypeName_[typeName];if(!instancesOfTypeName){instancesOfTypeName=[];this.instancesByTypeName_[typeName]=instancesOfTypeName;}
+instancesOfTypeName.push(instance);return instance;},getOrCreateInstanceMap_:function(scopedId){var dict;if(scopedId.scope in this.instanceMapsByScopedId_){dict=this.instanceMapsByScopedId_[scopedId.scope];}else{dict={};this.instanceMapsByScopedId_[scopedId.scope]=dict;}
+var instanceMap=dict[scopedId.id];if(instanceMap)
+return instanceMap;instanceMap=new tr.model.TimeToObjectInstanceMap(this.createObjectInstance_,this.parent,scopedId);dict[scopedId.id]=instanceMap;return instanceMap;},idWasCreated:function(scopedId,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(scopedId);return instanceMap.idWasCreated(category,name,ts);},addSnapshot:function(scopedId,category,name,ts,args,opt_baseTypeName){var instanceMap=this.getOrCreateInstanceMap_(scopedId);var snapshot=instanceMap.addSnapshot(category,name,ts,args,opt_baseTypeName);if(snapshot.objectInstance.category!=category){var msg='Added snapshot name='+name+' with cat='+category+' impossible. It instance was created/snapshotted with cat='+
 snapshot.objectInstance.category+' name='+
 snapshot.objectInstance.name;throw new Error(msg);}
 if(opt_baseTypeName&&snapshot.objectInstance.baseTypeName!=opt_baseTypeName){throw new Error('Could not add snapshot with baseTypeName='+
@@ -3386,23 +3906,16 @@
 snapshot.objectInstance.baseTypeName);}
 if(snapshot.objectInstance.name!=name){throw new Error('Could not add snapshot with name='+name+'. It '+'was previously created with name='+
 snapshot.objectInstance.name);}
-return snapshot;},idWasDeleted:function(id,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(id);var deletedInstance=instanceMap.idWasDeleted(category,name,ts);if(!deletedInstance)
+return snapshot;},idWasDeleted:function(scopedId,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(scopedId);var deletedInstance=instanceMap.idWasDeleted(category,name,ts);if(!deletedInstance)
 return;if(deletedInstance.category!=category){var msg='Deleting object '+deletedInstance.name+' with a different category '+'than when it was created. It previous had cat='+
 deletedInstance.category+' but the delete command '+'had cat='+category;throw new Error(msg);}
 if(deletedInstance.baseTypeName!=name){throw new Error('Deletion requested for name='+
 name+' could not proceed: '+'An existing object with baseTypeName='+
-deletedInstance.baseTypeName+' existed.');}},autoDeleteObjects:function(maxTimestamp){tr.b.iterItems(this.instanceMapsById_,function(id,i2imap){var lastInstance=i2imap.lastInstance;if(lastInstance.deletionTs!=Number.MAX_VALUE)
-return;i2imap.idWasDeleted(lastInstance.category,lastInstance.name,maxTimestamp);lastInstance.deletionTsWasExplicit=false;});},getObjectInstanceAt:function(id,ts){var instanceMap=this.instanceMapsById_[id];if(!instanceMap)
-return undefined;return instanceMap.getInstanceAt(ts);},getSnapshotAt:function(id,ts){var instance=this.getObjectInstanceAt(id,ts);if(!instance)
-return undefined;return instance.getSnapshotAt(ts);},iterObjectInstances:function(iter,opt_this){opt_this=opt_this||this;tr.b.iterItems(this.instanceMapsById_,function(id,i2imap){i2imap.instances.forEach(iter,opt_this);});},getAllObjectInstances:function(){var instances=[];this.iterObjectInstances(function(i){instances.push(i);});return instances;},getAllInstancesNamed:function(name){return this.instancesByTypeName_[name];},getAllInstancesByTypeName:function(){return this.instancesByTypeName_;},preInitializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.preInitialize();});},initializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.initialize();});},initializeInstances:function(){this.iterObjectInstances(function(instance){instance.initialize();});},updateBounds:function(){this.bounds.reset();this.iterObjectInstances(function(instance){instance.updateBounds();this.bounds.addRange(instance.bounds);},this);},shiftTimestampsForward:function(amount){this.iterObjectInstances(function(instance){instance.shiftTimestampsForward(amount);});},addCategoriesToDict:function(categoriesDict){this.iterObjectInstances(function(instance){categoriesDict[instance.category]=true;});}};return{ObjectCollection:ObjectCollection};});'use strict';tr.exportTo('tr.model',function(){function AsyncSlice(category,title,colorId,start,args,duration,opt_isTopLevel,opt_cpuStart,opt_cpuDuration,opt_argsStripped){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.important=false;this.subSlices=[];this.parentContainer=undefined;this.id=undefined;this.startThread=undefined;this.endThread=undefined;this.cpuStart=undefined;this.cpuDuration=undefined;this.argsStripped=false;this.startStackFrame=undefined;this.endStackFrame=undefined;this.duration=duration;this.isTopLevel=(opt_isTopLevel===true);if(opt_cpuStart!==undefined)
-this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
-this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
-this.argsStripped=opt_argsStripped;};AsyncSlice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get viewSubGroupTitle(){return this.title;},get userFriendlyName(){return'Async slice '+this.title+' at '+
-tr.b.u.TimeStamp.format(this.start);},get stableId(){var parentAsyncSliceGroup=this.parentContainer.asyncSliceGroup;return parentAsyncSliceGroup.stableId+'.'+
-parentAsyncSliceGroup.slices.indexOf(this);},findDescendentSlice:function(targetTitle){if(!this.subSlices)
-return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
-return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
-return undefined;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},compareTo:function(that){return this.title.localeCompare(that.title);}};tr.model.EventRegistry.register(AsyncSlice,{name:'asyncSlice',pluralName:'asyncSlices',singleViewElementName:'tr-ui-a-single-async-slice-sub-view',multiViewElementName:'tr-ui-a-multi-async-slice-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=AsyncSlice;options.defaultConstructor=AsyncSlice;tr.b.decorateExtensionRegistry(AsyncSlice,options);return{AsyncSlice:AsyncSlice};});'use strict';tr.exportTo('tr.model',function(){function AsyncSliceGroup(parentContainer,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;this.slices=[];this.name_=opt_name;this.viewSubGroups_=undefined;}
+deletedInstance.baseTypeName+' existed.');}},autoDeleteObjects:function(maxTimestamp){tr.b.iterItems(this.instanceMapsByScopedId_,function(scope,imapById){tr.b.iterItems(imapById,function(id,i2imap){var lastInstance=i2imap.lastInstance;if(lastInstance.deletionTs!=Number.MAX_VALUE)
+return;i2imap.idWasDeleted(lastInstance.category,lastInstance.name,maxTimestamp);lastInstance.deletionTsWasExplicit=false;});});},getObjectInstanceAt:function(scopedId,ts){var instanceMap;if(scopedId.scope in this.instanceMapsByScopedId_)
+instanceMap=this.instanceMapsByScopedId_[scopedId.scope][scopedId.id];if(!instanceMap)
+return undefined;return instanceMap.getInstanceAt(ts);},getSnapshotAt:function(scopedId,ts){var instance=this.getObjectInstanceAt(scopedId,ts);if(!instance)
+return undefined;return instance.getSnapshotAt(ts);},iterObjectInstances:function(iter,opt_this){opt_this=opt_this||this;tr.b.iterItems(this.instanceMapsByScopedId_,function(scope,imapById){tr.b.iterItems(imapById,function(id,i2imap){i2imap.instances.forEach(iter,opt_this);});});},getAllObjectInstances:function(){var instances=[];this.iterObjectInstances(function(i){instances.push(i);});return instances;},getAllInstancesNamed:function(name){return this.instancesByTypeName_[name];},getAllInstancesByTypeName:function(){return this.instancesByTypeName_;},preInitializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.preInitialize();});},initializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.initialize();});},initializeInstances:function(){this.iterObjectInstances(function(instance){instance.initialize();});},updateBounds:function(){this.bounds.reset();this.iterObjectInstances(function(instance){instance.updateBounds();this.bounds.addRange(instance.bounds);},this);},shiftTimestampsForward:function(amount){this.iterObjectInstances(function(instance){instance.shiftTimestampsForward(amount);});},addCategoriesToDict:function(categoriesDict){this.iterObjectInstances(function(instance){categoriesDict[instance.category]=true;});}};return{ObjectCollection:ObjectCollection};});'use strict';tr.exportTo('tr.model',function(){function AsyncSliceGroup(parentContainer,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;this.slices=[];this.name_=opt_name;this.viewSubGroups_=undefined;}
 AsyncSliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.parent.model;},get stableId(){return this.parentContainer_.stableId+'.AsyncSliceGroup';},getSettingsKey:function(){if(!this.name_)
 return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)
 return undefined;return parentKey+'.'+this.name_;},push:function(slice){slice.parentContainer=this.parentContainer;this.slices.push(slice);return slice;},get length(){return this.slices.length;},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);var shiftSubSlices=function(subSlices){if(subSlices===undefined||subSlices.length===0)
@@ -3426,9 +3939,8 @@
 throw new Error('endSlice called without an open slice');var slice=this.openPartialSlices_[this.openSliceCount-1];this.openPartialSlices_.splice(this.openSliceCount-1,1);if(ts<slice.start)
 throw new Error('Slice '+slice.title+' end time is before its start.');slice.duration=ts-slice.start;slice.didNotFinish=false;slice.colorId=opt_colorId||slice.colorId;if(opt_tts&&slice.cpuStart!==undefined)
 slice.cpuDuration=opt_tts-slice.cpuStart;return slice;},pushCompleteSlice:function(category,title,ts,duration,tts,cpuDuration,opt_args,opt_argsStripped,opt_colorId,opt_bind_id){var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var slice=new this.sliceConstructor(category,title,colorId,ts,opt_args?opt_args:{},duration,tts,cpuDuration,opt_argsStripped,opt_bind_id);if(duration===undefined)
-slice.didNotFinish=true;this.pushSlice(slice);return slice;},autoCloseOpenSlices:function(opt_maxTimestamp){if(!opt_maxTimestamp){this.updateBounds();opt_maxTimestamp=this.bounds.max;}
-for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];if(slice.didNotFinish)
-slice.duration=opt_maxTimestamp-slice.start;}
+slice.didNotFinish=true;this.pushSlice(slice);return slice;},autoCloseOpenSlices:function(){this.updateBounds();var maxTimestamp=this.bounds.max;for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];if(slice.didNotFinish)
+slice.duration=maxTimestamp-slice.start;}
 this.openPartialSlices_=[];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},copySlice:function(slice){var newSlice=new this.sliceConstructor(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration,slice.cpuStart,slice.cpuDuration);newSlice.didNotFinish=slice.didNotFinish;return newSlice;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,this.sliceConstructor))
 this.slices.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){},getSlicesOfName:function(title){var slices=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].title==title){slices.push(this.slices[i]);}}
 return slices;},iterSlicesInTimeRange:function(callback,start,end){var ret=[];tr.b.iterateOverIntersectingIntervals(this.topLevelSlices,function(s){return s.start;},function(s){return s.duration;},start,end,function(topLevelSlice){callback(topLevelSlice);topLevelSlice.iterateAllDescendents(callback);});return ret;},findFirstSlice:function(){if(!this.haveTopLevelSlicesBeenBuilt)
@@ -3471,8 +3983,7 @@
 if(endB===undefined||endA<endB){splitOpenSlices(endA);openA.pop();}else{openB.pop();}}};while(idxA<slicesA.length||idxB<slicesB.length){var sA=slicesA[idxA];var sB=slicesB[idxB];var nextSlice,isFromB;if(sA===undefined||(sB!==undefined&&sA.start>sB.start)){nextSlice=result.copySlice(sB);isFromB=true;idxB++;}else{nextSlice=result.copySlice(sA);isFromB=false;idxA++;}
 closeOpenSlices(nextSlice.start);result.pushSlice(nextSlice);if(isFromB){openB.push(nextSlice);}else{splitOpenSlices(nextSlice.start);openA.push(nextSlice);}}
 closeOpenSlices();return result;};return{SliceGroup:SliceGroup};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function ThreadSlice(cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){Slice.call(this,cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id);this.subSlices=[];}
-ThreadSlice.prototype={__proto__:Slice.prototype,getProcess:function(){var thread=this.parentContainer;if(thread&&thread.getProcess)
-return thread.getProcess();return undefined;}};tr.model.EventRegistry.register(ThreadSlice,{name:'slice',pluralName:'slices',singleViewElementName:'tr-ui-a-single-thread-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-slice-sub-view'});return{ThreadSlice:ThreadSlice};});'use strict';tr.exportTo('tr.model',function(){var AsyncSlice=tr.model.AsyncSlice;var AsyncSliceGroup=tr.model.AsyncSliceGroup;var Slice=tr.model.Slice;var SliceGroup=tr.model.SliceGroup;var ThreadSlice=tr.model.ThreadSlice;var ThreadTimeSlice=tr.model.ThreadTimeSlice;function Thread(parent,tid){if(!parent)
+ThreadSlice.prototype={__proto__:Slice.prototype};tr.model.EventRegistry.register(ThreadSlice,{name:'slice',pluralName:'slices',singleViewElementName:'tr-ui-a-single-thread-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-slice-sub-view'});return{ThreadSlice:ThreadSlice};});'use strict';tr.exportTo('tr.model',function(){var AsyncSlice=tr.model.AsyncSlice;var AsyncSliceGroup=tr.model.AsyncSliceGroup;var Slice=tr.model.Slice;var SliceGroup=tr.model.SliceGroup;var ThreadSlice=tr.model.ThreadSlice;var ThreadTimeSlice=tr.model.ThreadTimeSlice;function Thread(parent,tid){if(!parent)
 throw new Error('Parent must be provided.');tr.model.EventContainer.call(this);this.parent=parent;this.sortIndex=0;this.tid=tid;this.name=undefined;this.samples_=undefined;var that=this;this.sliceGroup=new SliceGroup(this,ThreadSlice,'slices');this.timeSlices=undefined;this.kernelSliceGroup=new SliceGroup(this,ThreadSlice,'kernel-slices');this.asyncSliceGroup=new AsyncSliceGroup(this,'async-slices');}
 Thread.prototype={__proto__:tr.model.EventContainer.prototype,get model(){return this.parent.model;},get stableId(){return this.parent.stableId+'.'+this.tid;},compareTo:function(that){return Thread.compare(this,that);},iterateAllChildEventContainers:function(callback,opt_this){if(this.sliceGroup.length)
 callback.call(opt_this,this.sliceGroup);if(this.kernelSliceGroup.length)
@@ -3491,7 +4002,7 @@
 categoriesDict[this.sliceGroup.slices[i].category]=true;for(var i=0;i<this.kernelSliceGroup.length;i++)
 categoriesDict[this.kernelSliceGroup.slices[i].category]=true;for(var i=0;i<this.asyncSliceGroup.length;i++)
 categoriesDict[this.asyncSliceGroup.slices[i].category]=true;if(this.samples_){for(var i=0;i<this.samples_.length;i++)
-categoriesDict[this.samples_[i].category]=true;}},autoCloseOpenSlices:function(opt_maxTimestamp){this.sliceGroup.autoCloseOpenSlices(opt_maxTimestamp);this.kernelSliceGroup.autoCloseOpenSlices(opt_maxTimestamp);},mergeKernelWithUserland:function(){if(this.kernelSliceGroup.length>0){var newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices:function(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(function(sample){return sample.thread==this;},this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
+categoriesDict[this.samples_[i].category]=true;}},autoCloseOpenSlices:function(){this.sliceGroup.autoCloseOpenSlices();this.kernelSliceGroup.autoCloseOpenSlices();},mergeKernelWithUserland:function(){if(this.kernelSliceGroup.length>0){var newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices:function(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(function(sample){return sample.thread==this;},this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
 (this.name?', name: '+this.name:'');},getSettingsKey:function(){if(!this.name)
 return undefined;var parentKey=this.parent.getSettingsKey();if(!parentKey)
 return undefined;return parentKey+'.'+this.name;},getProcess:function(){return this.parent;},indexOfTimeSlice:function(timeSlice){var i=tr.b.findLowIndexInSortedArray(this.timeSlices,function(slice){return slice.start;},timeSlice.start);if(this.timeSlices[i]!==timeSlice)
@@ -3508,7 +4019,7 @@
 callback.call(opt_this,this.threads[tid]);for(var id in this.counters)
 callback.call(opt_this,this.counters[id]);callback.call(opt_this,this.objects);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllPersistableObjects:function(cb){cb(this);for(var tid in this.threads)
 this.threads[tid].iterateAllPersistableObjects(cb);},get numThreads(){var n=0;for(var p in this.threads){n++;}
-return n;},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});},autoCloseOpenSlices:function(opt_maxTimestamp){for(var tid in this.threads){var thread=this.threads[tid];thread.autoCloseOpenSlices(opt_maxTimestamp);}},autoDeleteObjects:function(maxTimestamp){this.objects.autoDeleteObjects(maxTimestamp);},preInitializeObjects:function(){this.objects.preInitializeAllObjects();},initializeObjects:function(){this.objects.initializeAllObjects();},mergeKernelWithUserland:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.mergeKernelWithUserland();}},updateBounds:function(){this.bounds.reset();for(var tid in this.threads){this.threads[tid].updateBounds();this.bounds.addRange(this.threads[tid].bounds);}
+return n;},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});},autoCloseOpenSlices:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.autoCloseOpenSlices();}},autoDeleteObjects:function(maxTimestamp){this.objects.autoDeleteObjects(maxTimestamp);},preInitializeObjects:function(){this.objects.preInitializeAllObjects();},initializeObjects:function(){this.objects.initializeAllObjects();},mergeKernelWithUserland:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.mergeKernelWithUserland();}},updateBounds:function(){this.bounds.reset();for(var tid in this.threads){this.threads[tid].updateBounds();this.bounds.addRange(this.threads[tid].bounds);}
 for(var id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
 this.objects.updateBounds();this.bounds.addRange(this.objects.bounds);},addCategoriesToDict:function(categoriesDict){for(var tid in this.threads)
 this.threads[tid].addCategoriesToDict(categoriesDict);for(var id in this.counters)
@@ -3531,34 +4042,56 @@
 this.flowEventsById_[fe.id].push(fe);}},this);}
 ModelIndices.prototype={addEventWithId:function(id,event){if(!this.flowEventsById_.hasOwnProperty(id)){this.flowEventsById_[id]=new Array();}
 this.flowEventsById_[id].push(event);},getFlowEventsWithId:function(id){if(!this.flowEventsById_.hasOwnProperty(id))
-return[];return this.flowEventsById_[id];}};return{ModelIndices:ModelIndices};});'use strict';tr.exportTo('tr.model',function(){var DISCOUNTED_ALLOCATOR_NAMES=['winheap','malloc'];var SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME;var EFFECTIVE_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME;function ProcessMemoryDump(globalMemoryDump,process,start){tr.model.ContainerMemoryDump.call(this,start);this.process=process;this.globalMemoryDump=globalMemoryDump;this.totals=undefined;this.vmRegions_=undefined;this.heapDumps=undefined;this.tracingMemoryDiscounted_=false;};ProcessMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Process memory dump at '+
-tr.b.u.TimeStamp.format(this.start);},get containerName(){return this.process.userFriendlyName;},get processMemoryDumps(){var dumps={};dumps[this.process.pid]=this;return dumps;},get vmRegions(){throw new Error('VM regions must be accessed through the mostRecentVmRegions field');},set vmRegions(vmRegions){this.vmRegions_=vmRegions;},get hasOwnVmRegions(){return this.vmRegions_!==undefined;},getMostRecentTotalVmRegionStat:function(statName){if(this.mostRecentVmRegions===undefined)
-return undefined;var total=0;this.mostRecentVmRegions.forEach(function(vmRegion){var statValue=vmRegion.byteStats[statName];if(statValue===undefined)
-return;total+=statValue;});return total;},discountTracingOverhead:function(opt_model){if(this.tracingMemoryDiscounted_)
-return;this.tracingMemoryDiscounted_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined)
-return;function getDiscountedSize(sizeAttrName){var sizeAttr=tracingDump.getValidSizeAttributeOrUndefined(sizeAttrName,opt_model);if(sizeAttr===undefined)
-return 0;return sizeAttr.value;}
-var discountedSize=getDiscountedSize(SIZE_ATTRIBUTE_NAME);var discountedEffectiveSize=getDiscountedSize(EFFECTIVE_SIZE_ATTRIBUTE_NAME);var discountedResidentSize=getDiscountedSize('resident_size');if(discountedResidentSize>0){if(this.totals!==undefined){if(this.totals.residentBytes!==undefined)
-this.totals.residentBytes-=discountedResidentSize;if(this.totals.peakResidentBytes!==undefined)
-this.totals.peakResidentBytes-=discountedResidentSize;}
-if(this.vmRegions_!==undefined){var hasPrivateDirtyResident=false;var hasProportionalResident=false;for(var i=0;i<this.vmRegions_.length;i++){var byteStats=this.vmRegions_[i].byteStats;if(byteStats.privateDirtyResident!==undefined)
-hasPrivateDirtyResident=true;if(byteStats.proportionalResident!==undefined)
-hasProportionalResident=true;if(hasPrivateDirtyResident&&hasProportionalResident)
-break;}
-if(hasPrivateDirtyResident||hasProportionalResident){this.vmRegions_.push(VMRegion.fromDict({mappedFile:'[discounted tracing overhead]',byteStats:{privateDirtyResident:hasPrivateDirtyResident?-discountedResidentSize:undefined,proportionalResident:hasProportionalResident?-discountedResidentSize:undefined}}));}}}
-if(discountedSize>0||discountedEffectiveSize>0){function discountSizeAndEffectiveSize(dump){var dumpSizeAttr=dump.getValidSizeAttributeOrUndefined(SIZE_ATTRIBUTE_NAME,opt_model);if(dumpSizeAttr!==undefined)
-dumpSizeAttr.value-=discountedSize;var dumpEffectiveSizeAttr=dump.getValidSizeAttributeOrUndefined(EFFECTIVE_SIZE_ATTRIBUTE_NAME,opt_model);if(dumpEffectiveSizeAttr!==undefined)
-dumpEffectiveSizeAttr.value-=discountedEffectiveSize;}
-var hasDiscountedFromAllocatorDumps=DISCOUNTED_ALLOCATOR_NAMES.some(function(allocatorName){var allocatorDump=this.getMemoryAllocatorDumpByFullName(allocatorName);if(allocatorDump===undefined)
-return false;discountSizeAndEffectiveSize(allocatorDump);var allocatedObjectsDumpName=allocatorName+'/allocated_objects';var allocatedObjectsDump=this.getMemoryAllocatorDumpByFullName(allocatedObjectsDumpName);if(allocatedObjectsDump===undefined)
-return true;discountSizeAndEffectiveSize(allocatedObjectsDump);var discountDumpName=allocatedObjectsDumpName+'/discounted_tracing_overhead';var discountDump=new tr.model.MemoryAllocatorDump(this,discountDumpName);discountDump.parent=allocatedObjectsDump;discountDump.addAttribute(SIZE_ATTRIBUTE_NAME,new tr.model.ScalarAttribute('bytes',-discountedSize));discountDump.addAttribute(EFFECTIVE_SIZE_ATTRIBUTE_NAME,new tr.model.ScalarAttribute('bytes',-discountedEffectiveSize));allocatedObjectsDump.children.push(discountDump);return true;},this);if(hasDiscountedFromAllocatorDumps)
-this.memoryAllocatorDumps=this.memoryAllocatorDumps;}}};ProcessMemoryDump.hookUpMostRecentVmRegionsLinks=function(processDumps){var mostRecentVmRegions=undefined;processDumps.forEach(function(processDump){if(processDump.vmRegions_!==undefined)
-mostRecentVmRegions=processDump.vmRegions_;processDump.mostRecentVmRegions=mostRecentVmRegions;});};function VMRegion(startAddress,sizeInBytes,protectionFlags,mappedFile,byteStats){this.startAddress=startAddress;this.sizeInBytes=sizeInBytes;this.protectionFlags=protectionFlags;this.mappedFile=mappedFile;this.byteStats=byteStats;};VMRegion.PROTECTION_FLAG_READ=4;VMRegion.PROTECTION_FLAG_WRITE=2;VMRegion.PROTECTION_FLAG_EXECUTE=1;VMRegion.prototype={get protectionFlagsToString(){if(this.protectionFlags===undefined)
+return[];return this.flowEventsById_[id];}};return{ModelIndices:ModelIndices};});'use strict';tr.exportTo('tr.model',function(){function ModelStats(){this.traceEventCountsByKey_=new Map();this.allTraceEventStats_=[];this.traceEventStatsInTimeIntervals_=new Map();this.allTraceEventStatsInTimeIntervals_=[];this.hasEventSizesinBytes_=false;}
+ModelStats.prototype={TIME_INTERVAL_SIZE_IN_MS:100,willProcessBasicTraceEvent:function(phase,category,title,ts,opt_eventSizeinBytes){var key=phase+'/'+category+'/'+title;var eventStats=this.traceEventCountsByKey_.get(key);if(eventStats===undefined){eventStats={phase:phase,category:category,title:title,numEvents:0,totalEventSizeinBytes:0};this.traceEventCountsByKey_.set(key,eventStats);this.allTraceEventStats_.push(eventStats);}
+eventStats.numEvents++;var timeIntervalKey=Math.floor(tr.v.Unit.timestampFromUs(ts)/this.TIME_INTERVAL_SIZE_IN_MS);var eventStatsByTimeInverval=this.traceEventStatsInTimeIntervals_.get(timeIntervalKey);if(eventStatsByTimeInverval===undefined){eventStatsByTimeInverval={timeInterval:timeIntervalKey,numEvents:0,totalEventSizeinBytes:0};this.traceEventStatsInTimeIntervals_.set(timeIntervalKey,eventStatsByTimeInverval);this.allTraceEventStatsInTimeIntervals_.push(eventStatsByTimeInverval);}
+eventStatsByTimeInverval.numEvents++;if(opt_eventSizeinBytes!==undefined){this.hasEventSizesinBytes_=true;eventStats.totalEventSizeinBytes+=opt_eventSizeinBytes;eventStatsByTimeInverval.totalEventSizeinBytes+=opt_eventSizeinBytes;}},get allTraceEventStats(){return this.allTraceEventStats_;},get allTraceEventStatsInTimeIntervals(){return this.allTraceEventStatsInTimeIntervals_;},get hasEventSizesinBytes(){return this.hasEventSizesinBytes_;}};return{ModelStats:ModelStats};});'use strict';tr.exportTo('tr.model',function(){function VMRegion(startAddress,sizeInBytes,protectionFlags,mappedFile,byteStats){this.startAddress=startAddress;this.sizeInBytes=sizeInBytes;this.protectionFlags=protectionFlags;this.mappedFile=mappedFile||'';this.byteStats=byteStats||{};};VMRegion.PROTECTION_FLAG_READ=4;VMRegion.PROTECTION_FLAG_WRITE=2;VMRegion.PROTECTION_FLAG_EXECUTE=1;VMRegion.PROTECTION_FLAG_MAYSHARE=128;VMRegion.prototype={get uniqueIdWithinProcess(){return this.mappedFile+'#'+this.startAddress;},get protectionFlagsToString(){if(this.protectionFlags===undefined)
 return undefined;return((this.protectionFlags&VMRegion.PROTECTION_FLAG_READ?'r':'-')+
 (this.protectionFlags&VMRegion.PROTECTION_FLAG_WRITE?'w':'-')+
-(this.protectionFlags&VMRegion.PROTECTION_FLAG_EXECUTE?'x':'-'));}};VMRegion.fromDict=function(dict){return new VMRegion(dict.startAddress,dict.sizeInBytes,dict.protectionFlags,dict.mappedFile,VMRegionByteStats.fromDict(dict.byteStats));};function VMRegionByteStats(privateCleanResident,privateDirtyResident,sharedCleanResident,sharedDirtyResident,proportionalResident,swapped){this.privateCleanResident=privateCleanResident;this.privateDirtyResident=privateDirtyResident;this.sharedCleanResident=sharedCleanResident;this.sharedDirtyResident=sharedDirtyResident;this.proportionalResident=proportionalResident;this.swapped=swapped;}
-VMRegionByteStats.fromDict=function(dict){return new VMRegionByteStats(dict.privateCleanResident,dict.privateDirtyResident,dict.sharedCleanResident,dict.sharedDirtyResident,dict.proportionalResident,dict.swapped);}
-tr.model.EventRegistry.register(ProcessMemoryDump,{name:'processMemoryDump',pluralName:'processMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{ProcessMemoryDump:ProcessMemoryDump,VMRegion:VMRegion,VMRegionByteStats:VMRegionByteStats};});'use strict';tr.exportTo('tr.model',function(){var ProcessBase=tr.model.ProcessBase;var ProcessInstantEvent=tr.model.ProcessInstantEvent;var Frame=tr.model.Frame;var ProcessMemoryDump=tr.model.ProcessMemoryDump;function Process(model,pid){if(model===undefined)
+(this.protectionFlags&VMRegion.PROTECTION_FLAG_EXECUTE?'x':'-')+
+(this.protectionFlags&VMRegion.PROTECTION_FLAG_MAYSHARE?'s':'p'));}};VMRegion.fromDict=function(dict){return new VMRegion(dict.startAddress,dict.sizeInBytes,dict.protectionFlags,dict.mappedFile,dict.byteStats);};function VMRegionClassificationNode(opt_rule){this.rule_=opt_rule||VMRegionClassificationNode.CLASSIFICATION_RULES;this.hasRegions=false;this.sizeInBytes=undefined;this.byteStats={};this.children_=undefined;this.regions_=[];}
+VMRegionClassificationNode.CLASSIFICATION_RULES={name:'Total',children:[{name:'Android',file:/^\/dev\/ashmem(?!\/libc malloc)/,children:[{name:'Java runtime',file:/^\/dev\/ashmem\/dalvik-/,children:[{name:'Spaces',file:/\/dalvik-(alloc|main|large object|non moving|zygote) space/,children:[{name:'Normal',file:/\/dalvik-(alloc|main)/},{name:'Large',file:/\/dalvik-large object/},{name:'Zygote',file:/\/dalvik-zygote/},{name:'Non-moving',file:/\/dalvik-non moving/}]},{name:'Linear Alloc',file:/\/dalvik-LinearAlloc/},{name:'Indirect Reference Table',file:/\/dalvik-indirect.ref/},{name:'Cache',file:/\/dalvik-jit-code-cache/},{name:'Accounting'}]},{name:'Cursor',file:/\/CursorWindow/},{name:'Ashmem'}]},{name:'Native heap',file:/^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|(\[discounted tracing overhead\])|$)/},{name:'Stack',file:/^\[stack/},{name:'Files',file:/\.((((jar)|(apk)|(ttf)|(odex)|(oat)|(art))$)|(dex)|(so))/,children:[{name:'so',file:/\.so/},{name:'jar',file:/\.jar$/},{name:'apk',file:/\.apk$/},{name:'ttf',file:/\.ttf$/},{name:'dex',file:/\.((dex)|(odex$))/},{name:'oat',file:/\.oat$/},{name:'art',file:/\.art$/}]},{name:'Devices',file:/(^\/dev\/)|(anon_inode:dmabuf)/,children:[{name:'GPU',file:/\/((nv)|(mali)|(kgsl))/},{name:'DMA',file:/anon_inode:dmabuf/}]}]};VMRegionClassificationNode.OTHER_RULE={name:'Other'};VMRegionClassificationNode.fromRegions=function(regions,opt_rules){var tree=new VMRegionClassificationNode(opt_rules);tree.regions_=regions;for(var i=0;i<regions.length;i++)
+tree.addStatsFromRegion_(regions[i]);return tree;};VMRegionClassificationNode.prototype={get title(){return this.rule_.name;},get children(){if(this.isLeafNode)
+return undefined;if(this.children_===undefined)
+this.buildTree_();return this.children_;},get regions(){if(!this.isLeafNode){return undefined;}
+return this.regions_;},get allRegionsForTesting(){if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
+return this.regions_;}
+var regions=[];this.children_.forEach(function(childNode){regions=regions.concat(childNode.allRegionsForTesting);});return regions;},get isLeafNode(){var children=this.rule_.children;return children===undefined||children.length===0;},addRegion:function(region){this.addRegionRecursively_(region,true);},someRegion:function(fn,opt_this){if(this.regions_!==undefined){return this.regions_.some(fn,opt_this);}
+return this.children_.some(function(childNode){return childNode.someRegion(fn,opt_this);});},addRegionRecursively_:function(region,addStatsToThisNode){if(addStatsToThisNode)
+this.addStatsFromRegion_(region);if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
+this.regions_.push(region);return;}
+function regionRowMatchesChildNide(child){var fileRegExp=child.rule_.file;if(fileRegExp===undefined)
+return true;return fileRegExp.test(region.mappedFile);}
+var matchedChild=tr.b.findFirstInArray(this.children_,regionRowMatchesChildNide);if(matchedChild===undefined){if(this.children_.length!==this.rule_.children.length)
+throw new Error('Internal error');matchedChild=new VMRegionClassificationNode(VMRegionClassificationNode.OTHER_RULE);this.children_.push(matchedChild);}
+matchedChild.addRegionRecursively_(region,true);},buildTree_:function(){var cachedRegions=this.regions_;this.regions_=undefined;this.buildChildNodesRecursively_();for(var i=0;i<cachedRegions.length;i++){this.addRegionRecursively_(cachedRegions[i],false);}},buildChildNodesRecursively_:function(){if(this.children_!==undefined){throw new Error('Internal error: Classification node already has children');}
+if(this.regions_!==undefined&&this.regions_.length!==0){throw new Error('Internal error: Classification node should have no regions');}
+if(this.isLeafNode)
+return;this.regions_=undefined;this.children_=this.rule_.children.map(function(childRule){var child=new VMRegionClassificationNode(childRule);child.buildChildNodesRecursively_();return child;});},addStatsFromRegion_:function(region){this.hasRegions=true;var regionSizeInBytes=region.sizeInBytes;if(regionSizeInBytes!==undefined)
+this.sizeInBytes=(this.sizeInBytes||0)+regionSizeInBytes;var thisByteStats=this.byteStats;var regionByteStats=region.byteStats;for(var byteStatName in regionByteStats){var regionByteStatValue=regionByteStats[byteStatName];if(regionByteStatValue===undefined)
+continue;thisByteStats[byteStatName]=(thisByteStats[byteStatName]||0)+regionByteStatValue;}}};return{VMRegion:VMRegion,VMRegionClassificationNode:VMRegionClassificationNode};});'use strict';tr.exportTo('tr.model',function(){var DISCOUNTED_ALLOCATOR_NAMES=['winheap','malloc'];var TRACING_OVERHEAD_PATH=['allocated_objects','tracing_overhead'];var SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;var RESIDENT_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME;function getSizeNumericValue(dump,sizeNumericName){var sizeNumeric=dump.numerics[sizeNumericName];if(sizeNumeric===undefined)
+return 0;return sizeNumeric.value;}
+function ProcessMemoryDump(globalMemoryDump,process,start){tr.model.ContainerMemoryDump.call(this,start);this.process=process;this.globalMemoryDump=globalMemoryDump;this.totals=undefined;this.vmRegions=undefined;this.heapDumps=undefined;this.tracingOverheadOwnershipSetUp_=false;this.tracingOverheadDiscountedFromVmRegions_=false;};ProcessMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Process memory dump at '+
+tr.v.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return this.process.userFriendlyName;},get processMemoryDumps(){var dumps={};dumps[this.process.pid]=this;return dumps;},get hasOwnVmRegions(){return this.vmRegions!==undefined;},setUpTracingOverheadOwnership:function(opt_model){if(this.tracingOverheadOwnershipSetUp_)
+return;this.tracingOverheadOwnershipSetUp_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined||tracingDump.owns!==undefined){return;}
+if(tracingDump.owns!==undefined)
+return;var hasDiscountedFromAllocatorDumps=DISCOUNTED_ALLOCATOR_NAMES.some(function(allocatorName){var allocatorDump=this.getMemoryAllocatorDumpByFullName(allocatorName);if(allocatorDump===undefined)
+return false;var nextPathIndex=0;var currentDump=allocatorDump;var currentFullName=allocatorName;for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){var childFullName=currentFullName+'/'+
+TRACING_OVERHEAD_PATH[nextPathIndex];var childDump=this.getMemoryAllocatorDumpByFullName(childFullName);if(childDump===undefined)
+break;currentDump=childDump;currentFullName=childFullName;}
+for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){var childFullName=currentFullName+'/'+
+TRACING_OVERHEAD_PATH[nextPathIndex];var childDump=new tr.model.MemoryAllocatorDump(currentDump.containerMemoryDump,childFullName);childDump.parent=currentDump;currentDump.children.push(childDump);currentFullName=childFullName;currentDump=childDump;}
+var ownershipLink=new tr.model.MemoryAllocatorDumpLink(tracingDump,currentDump);tracingDump.owns=ownershipLink;currentDump.ownedBy.push(ownershipLink);return true;},this);if(hasDiscountedFromAllocatorDumps)
+this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();},discountTracingOverheadFromVmRegions:function(opt_model){if(this.tracingOverheadDiscountedFromVmRegions_)
+return;this.tracingOverheadDiscountedFromVmRegions_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined)
+return;var discountedSize=getSizeNumericValue(tracingDump,SIZE_NUMERIC_NAME);var discountedResidentSize=getSizeNumericValue(tracingDump,RESIDENT_SIZE_NUMERIC_NAME);if(discountedSize<=0&&discountedResidentSize<=0)
+return;if(this.totals!==undefined){if(this.totals.residentBytes!==undefined)
+this.totals.residentBytes-=discountedResidentSize;if(this.totals.peakResidentBytes!==undefined)
+this.totals.peakResidentBytes-=discountedResidentSize;}
+if(this.vmRegions!==undefined){var hasSizeInBytes=this.vmRegions.sizeInBytes!==undefined;var hasPrivateDirtyResident=this.vmRegions.byteStats.privateDirtyResident!==undefined;var hasProportionalResident=this.vmRegions.byteStats.proportionalResident!==undefined;if((hasSizeInBytes&&discountedSize>0)||((hasPrivateDirtyResident||hasProportionalResident)&&discountedResidentSize>0)){var byteStats={};if(hasPrivateDirtyResident)
+byteStats.privateDirtyResident=-discountedResidentSize;if(hasProportionalResident)
+byteStats.proportionalResident=-discountedResidentSize;this.vmRegions.addRegion(tr.model.VMRegion.fromDict({mappedFile:'[discounted tracing overhead]',sizeInBytes:hasSizeInBytes?-discountedSize:undefined,byteStats:byteStats}));}}}};ProcessMemoryDump.hookUpMostRecentVmRegionsLinks=function(processDumps){var mostRecentVmRegions=undefined;processDumps.forEach(function(processDump){if(processDump.vmRegions!==undefined)
+mostRecentVmRegions=processDump.vmRegions;processDump.mostRecentVmRegions=mostRecentVmRegions;});};tr.model.EventRegistry.register(ProcessMemoryDump,{name:'processMemoryDump',pluralName:'processMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{ProcessMemoryDump:ProcessMemoryDump};});'use strict';tr.exportTo('tr.model',function(){var ProcessBase=tr.model.ProcessBase;var ProcessInstantEvent=tr.model.ProcessInstantEvent;var Frame=tr.model.Frame;var ProcessMemoryDump=tr.model.ProcessMemoryDump;function Process(model,pid){if(model===undefined)
 throw new Error('model must be provided');if(pid===undefined)
 throw new Error('pid must be provided');tr.model.ProcessBase.call(this,model);this.pid=pid;this.name=undefined;this.labels=[];this.instantEvents=[];this.memoryDumps=[];this.frames=[];this.activities=[];};Process.compare=function(x,y){var tmp=tr.model.ProcessBase.compare(x,y);if(tmp)
 return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)
@@ -3566,7 +4099,7 @@
 return tmp;return x.pid-y.pid;};Process.prototype={__proto__:tr.model.ProcessBase.prototype,get stableId(){return this.pid;},compareTo:function(that){return Process.compare(this,that);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){ProcessBase.prototype.iterateAllEventsInThisContainer.call(this,eventTypePredicate,callback,opt_this);if(eventTypePredicate.call(opt_this,ProcessInstantEvent))
 this.instantEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Frame))
 this.frames.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,ProcessMemoryDump))
-this.memoryDumps.forEach(callback,opt_this);},pushInstantEvent:function(instantEvent){this.instantEvents.push(instantEvent);},addLabelIfNeeded:function(labelName){for(var i=0;i<this.labels.length;i++){if(this.labels[i]===labelName)
+this.memoryDumps.forEach(callback,opt_this);},addLabelIfNeeded:function(labelName){for(var i=0;i<this.labels.length;i++){if(this.labels[i]===labelName)
 return;}
 this.labels.push(labelName);},get userFriendlyName(){var res;if(this.name)
 res=this.name+' (pid '+this.pid+')';else
@@ -3574,15 +4107,15 @@
 res+=': '+this.labels.join(', ');return res;},get userFriendlyDetails(){if(this.name)
 return this.name+' (pid '+this.pid+')';return'pid: '+this.pid;},getSettingsKey:function(){if(!this.name)
 return undefined;if(!this.labels.length)
-return'processes.'+this.name;return'processes.'+this.name+'.'+this.labels.join('.');},shiftTimestampsForward:function(amount){for(var id in this.instantEvents)
-this.instantEvents[id].start+=amount;for(var i=0;i<this.frames.length;i++)
+return'processes.'+this.name;return'processes.'+this.name+'.'+this.labels.join('.');},shiftTimestampsForward:function(amount){for(var i=0;i<this.instantEvents.length;i++)
+this.instantEvents[i].start+=amount;for(var i=0;i<this.frames.length;i++)
 this.frames[i].shiftTimestampsForward(amount);for(var i=0;i<this.memoryDumps.length;i++)
 this.memoryDumps[i].shiftTimestampsForward(amount);for(var i=0;i<this.activities.length;i++)
 this.activities[i].shiftTimestampsForward(amount);tr.model.ProcessBase.prototype.shiftTimestampsForward.apply(this,arguments);},updateBounds:function(){tr.model.ProcessBase.prototype.updateBounds.apply(this);for(var i=0;i<this.frames.length;i++)
 this.frames[i].addBoundsToRange(this.bounds);for(var i=0;i<this.memoryDumps.length;i++)
 this.memoryDumps[i].addBoundsToRange(this.bounds);for(var i=0;i<this.activities.length;i++)
 this.activities[i].addBoundsToRange(this.bounds);},sortMemoryDumps:function(){this.memoryDumps.sort(function(x,y){return x.start-y.start;});tr.model.ProcessMemoryDump.hookUpMostRecentVmRegionsLinks(this.memoryDumps);}};return{Process:Process};});'use strict';tr.exportTo('tr.model',function(){function Sample(cpu,thread,title,start,leafStackFrame,opt_weight,opt_args){tr.model.TimedEvent.call(this,start);this.title=title;this.cpu=cpu;this.thread=thread;this.leafStackFrame=leafStackFrame;this.weight=opt_weight;this.args=opt_args||{};}
-Sample.prototype={__proto__:tr.model.TimedEvent.prototype,get colorId(){return this.leafStackFrame.colorId;},get stackTrace(){return this.leafStackFrame.stackTrace;},getUserFriendlyStackTrace:function(){return this.leafStackFrame.getUserFriendlyStackTrace();},get userFriendlyName(){return'Sample at '+tr.b.u.TimeStamp.format(this.start);}};tr.model.EventRegistry.register(Sample,{name:'sample',pluralName:'samples',singleViewElementName:'tr-ui-a-single-sample-sub-view',multiViewElementName:'tr-ui-a-multi-sample-sub-view'});return{Sample:Sample};});'use strict';tr.exportTo('tr.model',function(){function StackFrame(parentFrame,id,title,colorId,opt_sourceInfo){if(id===undefined)
+Sample.prototype={__proto__:tr.model.TimedEvent.prototype,get colorId(){return this.leafStackFrame.colorId;},get stackTrace(){return this.leafStackFrame.stackTrace;},getUserFriendlyStackTrace:function(){return this.leafStackFrame.getUserFriendlyStackTrace();},get userFriendlyName(){return'Sample at '+tr.v.Unit.byName.timeStampInMs.format(this.start);}};tr.model.EventRegistry.register(Sample,{name:'sample',pluralName:'samples',singleViewElementName:'tr-ui-a-single-sample-sub-view',multiViewElementName:'tr-ui-a-multi-sample-sub-view'});return{Sample:Sample};});'use strict';tr.exportTo('tr.model',function(){function StackFrame(parentFrame,id,title,colorId,opt_sourceInfo){if(id===undefined)
 throw new Error('id must be given');this.parentFrame_=parentFrame;this.id=id;this.title_=title;this.colorId=colorId;this.children=[];this.sourceInfo_=opt_sourceInfo;if(this.parentFrame_)
 this.parentFrame_.addChild(this);}
 StackFrame.prototype={get parentFrame(){return this.parentFrame_;},get title(){if(this.sourceInfo_){var src=this.sourceInfo_.toString();return this.title_+(src===''?'':' '+src);}
@@ -3593,7 +4126,9 @@
 this.parentFrame_.addChild(this);},addChild:function(child){this.children.push(child);},removeChild:function(child){var i=this.children.indexOf(child.id);if(i==-1)
 throw new Error('omg');this.children.splice(i,1);},removeAllChildren:function(){for(var i=0;i<this.children.length;i++)
 this.children[i].parentFrame_=undefined;this.children.splice(0,this.children.length);},get stackTrace(){var stack=[];var cur=this;while(cur){stack.push(cur);cur=cur.parentFrame;}
-return stack;},getUserFriendlyStackTrace:function(){return this.stackTrace.map(function(x){return x.title;});}};return{StackFrame:StackFrame};});'use strict';tr.exportTo('tr.ui.b',function(){function decorate(source,constr){var elements;if(typeof source=='string')
+return stack;},getUserFriendlyStackTrace:function(){return this.stackTrace.map(function(x){return x.title;});}};return{StackFrame:StackFrame};});'use strict';tr.exportTo('tr.model.um',function(){function UserModel(parentModel){tr.model.EventContainer.call(this);this.parentModel_=parentModel;this.expectations_=new tr.model.EventSet();}
+UserModel.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){return'UserModel';},get parentModel(){return this.parentModel_;},sortExpectations:function(){Array.prototype.sort.call(this.expectations_,function(x,y){return x.start-y.start;});},get expectations(){return this.expectations_;},shiftTimestampsForward:function(amount){},addCategoriesToDict:function(categoriesDict){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.um.UserExpectation))
+this.expectations.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){},updateBounds:function(){this.bounds.reset();this.expectations.forEach(function(expectation){expectation.addBoundsToRange(this.bounds);},this);}};return{UserModel:UserModel};});'use strict';tr.exportTo('tr.ui.b',function(){function decorate(source,constr){var elements;if(typeof source=='string')
 elements=tr.doc.querySelectorAll(source);else
 elements=[source];for(var i=0,el;el=elements[i];i++){if(!(el instanceof constr))
 constr.decorate(el);}}
@@ -3610,19 +4145,7 @@
 function elementIsChildOf(el,potentialParent){if(el==potentialParent)
 return false;var cur=el;while(cur.parentNode){if(cur==potentialParent)
 return true;cur=cur.parentNode;}
-return false;};return{decorate:decorate,define:define,elementIsChildOf:elementIsChildOf};});!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define(n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={exports:{},id:a,loaded:!1};return t[a].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){n.glMatrix=r(1),n.mat2=r(2),n.mat2d=r(3),n.mat3=r(4),n.mat4=r(5),n.quat=r(6),n.vec2=r(9),n.vec3=r(7),n.vec4=r(8)},function(t,n,r){var a={};a.EPSILON=1e-6,a.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,a.RANDOM=Math.random,a.setMatrixArrayType=function(t){GLMAT_ARRAY_TYPE=t};var e=Math.PI/180;a.toRadian=function(t){return t*e},t.exports=a},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;return o?(o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t):null},e.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},e.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*i+u*c,t[1]=e*i+o*c,t[2]=a*f+u*s,t[3]=e*f+o*s,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+u*i,t[1]=e*c+o*i,t[2]=a*-i+u*c,t[3]=e*-i+o*c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*c,t[3]=o*c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},e.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},e.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=r*u-a*e;return c?(c=1/c,t[0]=u*c,t[1]=-a*c,t[2]=-e*c,t[3]=r*c,t[4]=(e*i-u*o)*c,t[5]=(a*o-r*i)*c,t):null},e.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1],h=r[2],M=r[3],l=r[4],v=r[5];return t[0]=a*f+u*s,t[1]=e*f+o*s,t[2]=a*h+u*M,t[3]=e*h+o*M,t[4]=a*l+u*v+i,t[5]=e*l+o*v+c,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*f,t[1]=e*s+o*f,t[2]=a*-f+u*s,t[3]=e*-f+o*s,t[4]=i,t[5]=c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a*f,t[1]=e*f,t[2]=u*s,t[3]=o*s,t[4]=i,t[5]=c,t},e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*f+u*s+i,t[5]=e*f+o*s+c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},e.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},e.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=s*o-i*f,M=-s*u+i*c,l=f*u-o*c,v=r*h+a*M+e*l;return v?(v=1/v,t[0]=h*v,t[1]=(-s*a+e*f)*v,t[2]=(i*a-e*o)*v,t[3]=M*v,t[4]=(s*r-e*c)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-f*r+a*c)*v,t[8]=(o*r-a*u)*v,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8];return t[0]=o*s-i*f,t[1]=e*f-a*s,t[2]=a*i-e*o,t[3]=i*c-u*s,t[4]=r*s-e*c,t[5]=e*u-r*i,t[6]=u*f-o*c,t[7]=a*c-r*f,t[8]=r*o-a*u,t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8];return n*(f*u-o*c)+r*(-f*e+o*i)+a*(c*e-u*i)},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1],v=r[2],m=r[3],p=r[4],d=r[5],A=r[6],R=r[7],w=r[8];return t[0]=M*a+l*o+v*f,t[1]=M*e+l*i+v*s,t[2]=M*u+l*c+v*h,t[3]=m*a+p*o+d*f,t[4]=m*e+p*i+d*s,t[5]=m*u+p*c+d*h,t[6]=A*a+R*o+w*f,t[7]=A*e+R*i+w*s,t[8]=A*u+R*c+w*h,t},e.mul=e.multiply,e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=M*a+l*o+f,t[7]=M*e+l*i+s,t[8]=M*u+l*c+h,t},e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=Math.sin(r),l=Math.cos(r);return t[0]=l*a+M*o,t[1]=l*e+M*i,t[2]=l*u+M*c,t[3]=l*o-M*a,t[4]=l*i-M*e,t[5]=l*c-M*u,t[6]=f,t[7]=s,t[8]=h,t},e.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[3]=s-d,t[6]=M+p,t[1]=s+d,t[4]=1-f-v,t[7]=l-m,t[2]=M-p,t[5]=l+m,t[8]=1-f-h,t},e.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(c*P-o*b-f*x)*D,t[2]=(o*T-i*P+f*y)*D,t[3]=(e*T-a*b-u*E)*D,t[4]=(r*b-e*P+u*x)*D,t[5]=(a*P-r*T-u*y)*D,t[6]=(m*g-p*Y+d*q)*D,t[7]=(p*w-v*g-d*R)*D,t[8]=(v*Y-m*w+d*A)*D,t):null},e.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(e*T-a*b-u*E)*D,t[2]=(m*g-p*Y+d*q)*D,t[3]=(M*Y-h*g-l*q)*D,t[4]=(c*P-o*b-f*x)*D,t[5]=(r*b-e*P+u*x)*D,t[6]=(p*w-v*g-d*R)*D,t[7]=(s*g-M*w+l*R)*D,t[8]=(o*T-i*P+f*y)*D,t[9]=(a*P-r*T-u*y)*D,t[10]=(v*Y-m*w+d*A)*D,t[11]=(h*w-s*Y-l*A)*D,t[12]=(i*x-o*E-c*y)*D,t[13]=(r*E-a*x+e*y)*D,t[14]=(m*R-v*q-p*A)*D,t[15]=(s*q-h*R+M*A)*D,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15];return t[0]=i*(M*d-l*p)-h*(c*d-f*p)+m*(c*l-f*M),t[1]=-(a*(M*d-l*p)-h*(e*d-u*p)+m*(e*l-u*M)),t[2]=a*(c*d-f*p)-i*(e*d-u*p)+m*(e*f-u*c),t[3]=-(a*(c*l-f*M)-i*(e*l-u*M)+h*(e*f-u*c)),t[4]=-(o*(M*d-l*p)-s*(c*d-f*p)+v*(c*l-f*M)),t[5]=r*(M*d-l*p)-s*(e*d-u*p)+v*(e*l-u*M),t[6]=-(r*(c*d-f*p)-o*(e*d-u*p)+v*(e*f-u*c)),t[7]=r*(c*l-f*M)-o*(e*l-u*M)+s*(e*f-u*c),t[8]=o*(h*d-l*m)-s*(i*d-f*m)+v*(i*l-f*h),t[9]=-(r*(h*d-l*m)-s*(a*d-u*m)+v*(a*l-u*h)),t[10]=r*(i*d-f*m)-o*(a*d-u*m)+v*(a*f-u*i),t[11]=-(r*(i*l-f*h)-o*(a*l-u*h)+s*(a*f-u*i)),t[12]=-(o*(h*p-M*m)-s*(i*p-c*m)+v*(i*M-c*h)),t[13]=r*(h*p-M*m)-s*(a*p-e*m)+v*(a*M-e*h),t[14]=-(r*(i*p-c*m)-o*(a*p-e*m)+v*(a*c-e*i)),t[15]=r*(i*M-c*h)-o*(a*M-e*h)+s*(a*c-e*i),t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8],s=t[9],h=t[10],M=t[11],l=t[12],v=t[13],m=t[14],p=t[15],d=n*o-r*u,A=n*i-a*u,R=n*c-e*u,w=r*i-a*o,q=r*c-e*o,Y=a*c-e*i,g=f*v-s*l,y=f*m-h*l,x=f*p-M*l,P=s*m-h*v,E=s*p-M*v,T=h*p-M*m;return d*T-A*E+R*P+w*x-q*y+Y*g},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],m=n[12],p=n[13],d=n[14],A=n[15],R=r[0],w=r[1],q=r[2],Y=r[3];return t[0]=R*a+w*i+q*h+Y*m,t[1]=R*e+w*c+q*M+Y*p,t[2]=R*u+w*f+q*l+Y*d,t[3]=R*o+w*s+q*v+Y*A,R=r[4],w=r[5],q=r[6],Y=r[7],t[4]=R*a+w*i+q*h+Y*m,t[5]=R*e+w*c+q*M+Y*p,t[6]=R*u+w*f+q*l+Y*d,t[7]=R*o+w*s+q*v+Y*A,R=r[8],w=r[9],q=r[10],Y=r[11],t[8]=R*a+w*i+q*h+Y*m,t[9]=R*e+w*c+q*M+Y*p,t[10]=R*u+w*f+q*l+Y*d,t[11]=R*o+w*s+q*v+Y*A,R=r[12],w=r[13],q=r[14],Y=r[15],t[12]=R*a+w*i+q*h+Y*m,t[13]=R*e+w*c+q*M+Y*p,t[14]=R*u+w*f+q*l+Y*d,t[15]=R*o+w*s+q*v+Y*A,t},e.mul=e.multiply,e.translate=function(t,n,r){var a,e,u,o,i,c,f,s,h,M,l,v,m=r[0],p=r[1],d=r[2];return n===t?(t[12]=n[0]*m+n[4]*p+n[8]*d+n[12],t[13]=n[1]*m+n[5]*p+n[9]*d+n[13],t[14]=n[2]*m+n[6]*p+n[10]*d+n[14],t[15]=n[3]*m+n[7]*p+n[11]*d+n[15]):(a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=f,t[7]=s,t[8]=h,t[9]=M,t[10]=l,t[11]=v,t[12]=a*m+i*p+h*d+n[12],t[13]=e*m+c*p+M*d+n[13],t[14]=u*m+f*p+l*d+n[14],t[15]=o*m+s*p+v*d+n[15]),t},e.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.rotate=function(t,n,r,e){var u,o,i,c,f,s,h,M,l,v,m,p,d,A,R,w,q,Y,g,y,x,P,E,T,b=e[0],D=e[1],L=e[2],_=Math.sqrt(b*b+D*D+L*L);return Math.abs(_)<a.EPSILON?null:(_=1/_,b*=_,D*=_,L*=_,u=Math.sin(r),o=Math.cos(r),i=1-o,c=n[0],f=n[1],s=n[2],h=n[3],M=n[4],l=n[5],v=n[6],m=n[7],p=n[8],d=n[9],A=n[10],R=n[11],w=b*b*i+o,q=D*b*i+L*u,Y=L*b*i-D*u,g=b*D*i-L*u,y=D*D*i+o,x=L*D*i+b*u,P=b*L*i+D*u,E=D*L*i-b*u,T=L*L*i+o,t[0]=c*w+M*q+p*Y,t[1]=f*w+l*q+d*Y,t[2]=s*w+v*q+A*Y,t[3]=h*w+m*q+R*Y,t[4]=c*g+M*y+p*x,t[5]=f*g+l*y+d*x,t[6]=s*g+v*y+A*x,t[7]=h*g+m*y+R*x,t[8]=c*P+M*E+p*T,t[9]=f*P+l*E+d*T,t[10]=s*P+v*E+A*T,t[11]=h*P+m*E+R*T,n!==t&&(t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t)},e.rotateX=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[4],o=n[5],i=n[6],c=n[7],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[4]=u*e+f*a,t[5]=o*e+s*a,t[6]=i*e+h*a,t[7]=c*e+M*a,t[8]=f*e-u*a,t[9]=s*e-o*a,t[10]=h*e-i*a,t[11]=M*e-c*a,t},e.rotateY=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e-f*a,t[1]=o*e-s*a,t[2]=i*e-h*a,t[3]=c*e-M*a,t[8]=u*a+f*e,t[9]=o*a+s*e,t[10]=i*a+h*e,t[11]=c*a+M*e,t},e.rotateZ=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[4],s=n[5],h=n[6],M=n[7];return n!==t&&(t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e+f*a,t[1]=o*e+s*a,t[2]=i*e+h*a,t[3]=c*e+M*a,t[4]=f*e-u*a,t[5]=s*e-o*a,t[6]=h*e-i*a,t[7]=M*e-c*a,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=n[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=n[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotation=function(t,n,r){var e,u,o,i=r[0],c=r[1],f=r[2],s=Math.sqrt(i*i+c*c+f*f);return Math.abs(s)<a.EPSILON?null:(s=1/s,i*=s,c*=s,f*=s,e=Math.sin(n),u=Math.cos(n),o=1-u,t[0]=i*i*o+u,t[1]=c*i*o+f*e,t[2]=f*i*o-c*e,t[3]=0,t[4]=i*c*o-f*e,t[5]=c*c*o+u,t[6]=f*c*o+i*e,t[7]=0,t[8]=i*f*o+c*e,t[9]=c*f*o-i*e,t[10]=f*f*o+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.fromXRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=r,t[7]=0,t[8]=0,t[9]=-r,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromYRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=0,t[2]=-r,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=r,t[9]=0,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromZRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=0,t[4]=-r,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotationTranslation=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,c=e+e,f=u+u,s=a*i,h=a*c,M=a*f,l=e*c,v=e*f,m=u*f,p=o*i,d=o*c,A=o*f;return t[0]=1-(l+m),t[1]=h+A,t[2]=M-d,t[3]=0,t[4]=h-A,t[5]=1-(s+m),t[6]=v+p,t[7]=0,t[8]=M+d,t[9]=v-p,t[10]=1-(s+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],c=e+e,f=u+u,s=o+o,h=e*c,M=e*f,l=e*s,v=u*f,m=u*s,p=o*s,d=i*c,A=i*f,R=i*s,w=a[0],q=a[1],Y=a[2];return t[0]=(1-(v+p))*w,t[1]=(M+R)*w,t[2]=(l-A)*w,t[3]=0,t[4]=(M-R)*q,t[5]=(1-(h+p))*q,t[6]=(m+d)*q,t[7]=0,t[8]=(l+A)*Y,t[9]=(m-d)*Y,t[10]=(1-(h+v))*Y,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],c=n[3],f=u+u,s=o+o,h=i+i,M=u*f,l=u*s,v=u*h,m=o*s,p=o*h,d=i*h,A=c*f,R=c*s,w=c*h,q=a[0],Y=a[1],g=a[2],y=e[0],x=e[1],P=e[2];return t[0]=(1-(m+d))*q,t[1]=(l+w)*q,t[2]=(v-R)*q,t[3]=0,t[4]=(l-w)*Y,t[5]=(1-(M+d))*Y,t[6]=(p+A)*Y,t[7]=0,t[8]=(v+R)*g,t[9]=(p-A)*g,t[10]=(1-(M+m))*g,t[11]=0,t[12]=r[0]+y-(t[0]*y+t[4]*x+t[8]*P),t[13]=r[1]+x-(t[1]*y+t[5]*x+t[9]*P),t[14]=r[2]+P-(t[2]*y+t[6]*x+t[10]*P),t[15]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[1]=s+d,t[2]=M-p,t[3]=0,t[4]=s-d,t[5]=1-f-v,t[6]=l+m,t[7]=0,t[8]=M+p,t[9]=l-m,t[10]=1-f-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),c=1/(e-a),f=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*c,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*c,t[10]=(o+u)*f,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*f,t[15]=0,t},e.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t},e.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),f=2/(e+u);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=-((o-i)*c*.5),t[9]=(e-u)*f*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},e.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),c=1/(a-e),f=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*c,t[14]=(o+u)*f,t[15]=1,t},e.lookAt=function(t,n,r,u){var o,i,c,f,s,h,M,l,v,m,p=n[0],d=n[1],A=n[2],R=u[0],w=u[1],q=u[2],Y=r[0],g=r[1],y=r[2];return Math.abs(p-Y)<a.EPSILON&&Math.abs(d-g)<a.EPSILON&&Math.abs(A-y)<a.EPSILON?e.identity(t):(M=p-Y,l=d-g,v=A-y,m=1/Math.sqrt(M*M+l*l+v*v),M*=m,l*=m,v*=m,o=w*v-q*l,i=q*M-R*v,c=R*l-w*M,m=Math.sqrt(o*o+i*i+c*c),m?(m=1/m,o*=m,i*=m,c*=m):(o=0,i=0,c=0),f=l*c-v*i,s=v*o-M*c,h=M*i-l*o,m=Math.sqrt(f*f+s*s+h*h),m?(m=1/m,f*=m,s*=m,h*=m):(f=0,s=0,h=0),t[0]=o,t[1]=f,t[2]=M,t[3]=0,t[4]=i,t[5]=s,t[6]=l,t[7]=0,t[8]=c,t[9]=h,t[10]=v,t[11]=0,t[12]=-(o*p+i*d+c*A),t[13]=-(f*p+s*d+h*A),t[14]=-(M*p+l*d+v*A),t[15]=1,t)},e.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},t.exports=e},function(t,n,r){var a=r(1),e=r(4),u=r(7),o=r(8),i={};i.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var c=u.dot(e,o);return-.999999>c?(u.cross(t,n,e),u.length(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),i.setAxisAngle(a,t,Math.PI),a):c>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+c,i.normalize(a,a))}}(),i.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],i.normalize(n,i.fromMat3(n,t))}}(),i.clone=o.clone,i.fromValues=o.fromValues,i.copy=o.copy,i.set=o.set,i.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.setAxisAngle=function(t,n,r){r=.5*r;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t},i.add=o.add,i.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*s+o*i+e*f-u*c,t[1]=e*s+o*c+u*i-a*f,t[2]=u*s+o*f+a*c-e*i,t[3]=o*s-a*i-e*c-u*f,t},i.mul=i.multiply,i.scale=o.scale,i.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+o*i,t[1]=e*c+u*i,t[2]=u*c-e*i,t[3]=o*c-a*i,t},i.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c-u*i,t[1]=e*c+o*i,t[2]=u*c+a*i,t[3]=o*c-e*i,t},i.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+e*i,t[1]=e*c-a*i,t[2]=u*c+o*i,t[3]=o*c-u*i,t},i.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},i.dot=o.dot,i.lerp=o.lerp,i.slerp=function(t,n,r,a){var e,u,o,i,c,f=n[0],s=n[1],h=n[2],M=n[3],l=r[0],v=r[1],m=r[2],p=r[3];return u=f*l+s*v+h*m+M*p,0>u&&(u=-u,l=-l,v=-v,m=-m,p=-p),1-u>1e-6?(e=Math.acos(u),o=Math.sin(e),i=Math.sin((1-a)*e)/o,c=Math.sin(a*e)/o):(i=1-a,c=a),t[0]=i*f+c*l,t[1]=i*s+c*v,t[2]=i*h+c*m,t[3]=i*M+c*p,t},i.sqlerp=function(){var t=i.create(),n=i.create();return function(r,a,e,u,o,c){return i.slerp(t,a,o,c),i.slerp(n,e,u,c),i.slerp(r,t,n,2*c*(1-c)),r}}(),i.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},i.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},i.length=o.length,i.len=i.length,i.squaredLength=o.squaredLength,i.sqrLen=i.squaredLength,i.normalize=o.normalize,i.fromMat3=function(t,n){var r,a=n[0]+n[4]+n[8];if(a>0)r=Math.sqrt(a+1),t[3]=.5*r,r=.5/r,t[0]=(n[5]-n[7])*r,t[1]=(n[6]-n[2])*r,t[2]=(n[1]-n[3])*r;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;r=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*r,r=.5/r,t[3]=(n[3*u+o]-n[3*o+u])*r,t[u]=(n[3*u+e]+n[3*e+u])*r,t[o]=(n[3*o+e]+n[3*e+o])*r}return t},i.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=i},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},e.fromValues=function(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t},e.set=function(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},e.cross=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2];return t[0]=e*c-u*i,t[1]=u*o-a*c,t[2]=a*i-e*o,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t},e.hermite=function(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,c=o*(u-2)+u,f=o*(u-1),s=o*(3-2*u);return t[0]=n[0]*i+r[0]*c+a[0]*f+e[0]*s,t[1]=n[1]*i+r[1]*c+a[1]*f+e[1]*s,t[2]=n[2]*i+r[2]*c+a[2]*f+e[2]*s,t},e.bezier=function(t,n,r,a,e,u){var o=1-u,i=o*o,c=u*u,f=i*o,s=3*u*i,h=3*c*o,M=c*u;return t[0]=n[0]*f+r[0]*s+a[0]*h+e[0]*M,t[1]=n[1]*f+r[1]*s+a[1]*h+e[1]*M,t[2]=n[2]*f+r[2]*s+a[2]*h+e[2]*M,t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI,e=2*a.RANDOM()-1,u=Math.sqrt(1-e*e)*n;return t[0]=Math.cos(r)*u,t[1]=Math.sin(r)*u,t[2]=e*n,t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t},e.rotateX=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateY=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateZ=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=3),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2];return n}}(),e.angle=function(t,n){var r=e.fromValues(t[0],t[1],t[2]),a=e.fromValues(n[0],n[1],n[2]);e.normalize(r,r),e.normalize(a,a);var u=e.dot(r,a);return u>1?0:Math.acos(u)},e.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;return o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},e.random=function(t,n){return n=n||1,t[0]=a.RANDOM(),t[1]=a.RANDOM(),t[2]=a.RANDOM(),t[3]=a.RANDOM(),e.normalize(t,t),e.scale(t,t,n),t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t[3]=n[3],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=4),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],t[3]=n[i+3],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2],n[i+3]=t[3];return n}}(),e.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},e.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},e.set=function(t,n,r){return t[0]=n,t[1]=r,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1];return n*n+r*r},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},e.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},e.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},e.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=2),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],u(t,t,o),n[i]=t[0],n[i+1]=t[1];return n}}(),e.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},t.exports=e}])});'use strict';tr.exportTo('tr.b',function(){function clamp(x,lo,hi){return Math.min(Math.max(x,lo),hi);}
-function lerp(percentage,lo,hi){var range=hi-lo;return lo+percentage*range;}
-function normalize(value,lo,hi){return(value-lo)/(hi-lo);}
-function deg2rad(deg){return(Math.PI*deg)/180.0;}
-var tmp_vec2=vec2.create();var tmp_vec2b=vec2.create();var tmp_vec4=vec4.create();var tmp_mat2d=mat2d.create();vec2.createFromArray=function(arr){if(arr.length!=2)
-throw new Error('Should be length 2');var v=vec2.create();vec2.set(v,arr[0],arr[1]);return v;};vec2.createXY=function(x,y){var v=vec2.create();vec2.set(v,x,y);return v;};vec2.toString=function(a){return'['+a[0]+', '+a[1]+']';};vec2.addTwoScaledUnitVectors=function(out,u1,scale1,u2,scale2){vec2.scale(tmp_vec2,u1,scale1);vec2.scale(tmp_vec2b,u2,scale2);vec2.add(out,tmp_vec2,tmp_vec2b);};vec2.interpolatePiecewiseFunction=function(points,x){if(x<points[0][0])
-return points[0][1];for(var i=1;i<points.length;++i){if(x<points[i][0]){var percent=normalize(x,points[i-1][0],points[i][0]);return lerp(percent,points[i-1][1],points[i][1]);}}
-return points[points.length-1][1];};vec3.createXYZ=function(x,y,z){var v=vec3.create();vec3.set(v,x,y,z);return v;};vec3.toString=function(a){return'vec3('+a[0]+', '+a[1]+', '+a[2]+')';}
-mat2d.translateXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.translate(out,out,tmp_vec2);}
-mat2d.scaleXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.scale(out,out,tmp_vec2);}
-vec4.unitize=function(out,a){out[0]=a[0]/a[3];out[1]=a[1]/a[3];out[2]=a[2]/a[3];out[3]=1;return out;}
-vec2.copyFromVec4=function(out,a){vec4.unitize(tmp_vec4,a);vec2.copy(out,tmp_vec4);}
-return{clamp:clamp,lerp:lerp,normalize:normalize,deg2rad:deg2rad};});'use strict';tr.exportTo('tr.b',function(){function Rect(){this.x=0;this.y=0;this.width=0;this.height=0;};Rect.fromXYWH=function(x,y,w,h){var rect=new Rect();rect.x=x;rect.y=y;rect.width=w;rect.height=h;return rect;}
+return false;};return{decorate:decorate,define:define,elementIsChildOf:elementIsChildOf};});'use strict';tr.exportTo('tr.b',function(){function Rect(){this.x=0;this.y=0;this.width=0;this.height=0;};Rect.fromXYWH=function(x,y,w,h){var rect=new Rect();rect.x=x;rect.y=y;rect.width=w;rect.height=h;return rect;}
 Rect.fromArray=function(ary){if(ary.length!=4)
 throw new Error('ary.length must be 4');var rect=new Rect();rect.x=ary[0];rect.y=ary[1];rect.width=ary[2];rect.height=ary[3];return rect;}
 Rect.prototype={__proto__:Object.prototype,get left(){return this.x;},get top(){return this.y;},get right(){return this.x+this.width;},get bottom(){return this.y+this.height;},toString:function(){return'Rect('+this.x+', '+this.y+', '+
@@ -3631,14 +4154,16 @@
 function windowRectForElement(element){var position=[element.offsetLeft,element.offsetTop];var size=[element.offsetWidth,element.offsetHeight];var node=element.offsetParent;while(node){position[0]+=node.offsetLeft;position[1]+=node.offsetTop;node=node.offsetParent;}
 return tr.b.Rect.fromXYWH(position[0],position[1],size[0],size[1]);}
 function scrollIntoViewIfNeeded(el){var pr=el.parentElement.getBoundingClientRect();var cr=el.getBoundingClientRect();if(cr.top<pr.top){el.scrollIntoView(true);}else if(cr.bottom>pr.bottom){el.scrollIntoView(false);}}
-return{instantiateTemplate:instantiateTemplate,windowRectForElement:windowRectForElement,scrollIntoViewIfNeeded:scrollIntoViewIfNeeded};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)
+function extractUrlString(url){var extracted=url.replace(/url\((.*)\)/,'$1');extracted=extracted.replace(/\"(.*)\"/,'$1');return extracted;}
+function toThreeDigitLocaleString(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}
+return{toThreeDigitLocaleString:toThreeDigitLocaleString,instantiateTemplate:instantiateTemplate,windowRectForElement:windowRectForElement,scrollIntoViewIfNeeded:scrollIntoViewIfNeeded,extractUrlString:extractUrlString};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)
 return{};var THIS_DOC=document.currentScript.ownerDocument;var Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);var createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);this.shadow_.appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=this.shadow_.querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);this.shadow_.querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new WebKitMutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(this.shadow_.querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get:function(){return this.shadow_.querySelector('title').textContent;},set:function(title){this.shadow_.querySelector('title').textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return this.shadow_.querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)
 return;this.visible_=newValue;var e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_:function(){this.visible_?this.show_():this.hide_();},show_:function(){this.parentEl_.appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));}
 this.parentEl_.addEventListener('focusin',this.onFocusIn_);this.tabIndex=0;var focusEl=undefined;var elList=this.querySelectorAll('button, input, list, select, a');if(elList.length>0){if(elList[0]===this.closeBtn_){if(elList.length>1)
 focusEl=elList[1];}else{focusEl=elList[0];}}
 if(focusEl===undefined)
 focusEl=this;focusEl.focus();},hide_:function(){this.parentEl_.removeChild(this);this.parentEl_.removeEventListener('focusin',this.onFocusIn_);if(this.closeBtn_)
-this.closeBtn_.removeEventListener(this.onClose_);document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_:function(e){this.visible=false;if((e.type!='keydown')||(e.type==='keydown'&&e.keyCode===27))
+this.closeBtn_.removeEventListener('click',this.onClose_);document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_:function(e){this.visible=false;if((e.type!='keydown')||(e.type==='keydown'&&e.keyCode===27))
 e.stopPropagation();e.preventDefault();tr.b.dispatchSimpleEvent(this,'closeclick');},onFocusIn_:function(e){if(e.target===this)
 return;window.setTimeout(function(){this.focus();},0);e.preventDefault();e.stopPropagation();},didButtonBarMutate_:function(e){var hasButtons=this.buttons.children.length>0;if(hasButtons)
 this.shadow_.querySelector('button-bar').style.display=undefined;else
@@ -3647,22 +4172,24 @@
 return;this.onClose_(e);},onClick_:function(e){e.stopPropagation();},onDocumentClick_:function(e){if(!this.userCanClose_)
 return;this.onClose_(e);}};Overlay.showError=function(msg,opt_err){var o=new Overlay();o.title='Error';o.textContent=msg;if(opt_err){var e=tr.b.normalizeException(opt_err);var stackDiv=document.createElement('pre');stackDiv.textContent=e.stack;stackDiv.style.paddingLeft='8px';stackDiv.style.margin=0;o.appendChild(stackDiv);}
 var b=document.createElement('button');b.textContent='OK';b.addEventListener('click',function(){o.visible=false;});o.buttons.appendChild(b);o.visible=true;return o;}
-return{Overlay:Overlay};});'use strict';tr.exportTo('tr',function(){var Process=tr.model.Process;var Device=tr.model.Device;var Kernel=tr.model.Kernel;var GlobalMemoryDump=tr.model.GlobalMemoryDump;var GlobalInstantEvent=tr.model.GlobalInstantEvent;var FlowEvent=tr.model.FlowEvent;var Alert=tr.model.Alert;var InteractionRecord=tr.model.InteractionRecord;var Sample=tr.model.Sample;function ClockSyncRecord(name,ts,args){this.name=name;this.ts=ts;this.args=args;}
-function Model(){tr.model.EventContainer.call(this);tr.b.EventTarget.decorate(this);this.timestampShiftToZeroAmount_=0;this.faviconHue='blue';this.device=new Device(this);this.kernel=new Kernel(this);this.processes={};this.metadata=[];this.categories=[];this.instantEvents=[];this.flowEvents=[];this.clockSyncRecords=[];this.intrinsicTimeUnit_=undefined;this.stackFrames={};this.samples=[];this.alerts=[];this.interactionRecords=[];this.flowIntervalTree=new tr.b.IntervalTree(function(f){return f.start;},function(f){return f.end;});this.globalMemoryDumps=[];this.annotationsByGuid_={};this.modelIndices=undefined;this.importWarnings_=[];this.reportedImportWarnings_={};}
-Model.prototype={__proto__:tr.model.EventContainer.prototype,iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,GlobalMemoryDump))
+return{Overlay:Overlay};});'use strict';tr.exportTo('tr',function(){var Process=tr.model.Process;var Device=tr.model.Device;var Kernel=tr.model.Kernel;var GlobalMemoryDump=tr.model.GlobalMemoryDump;var GlobalInstantEvent=tr.model.GlobalInstantEvent;var FlowEvent=tr.model.FlowEvent;var Alert=tr.model.Alert;var Sample=tr.model.Sample;function Model(){tr.model.EventContainer.call(this);tr.b.EventTarget.decorate(this);this.timestampShiftToZeroAmount_=0;this.faviconHue='blue';this.device=new Device(this);this.kernel=new Kernel(this);this.processes={};this.metadata=[];this.categories=[];this.instantEvents=[];this.flowEvents=[];this.clockSyncManager=new tr.model.ClockSyncManager();this.clockSyncRecords=[];this.intrinsicTimeUnit_=undefined;this.stackFrames={};this.samples=[];this.alerts=[];this.userModel=new tr.model.um.UserModel(this);this.flowIntervalTree=new tr.b.IntervalTree((f)=>f.start,(f)=>f.end);this.globalMemoryDumps=[];this.userFriendlyCategoryDrivers_=[];this.annotationsByGuid_={};this.modelIndices=undefined;this.stats=new tr.model.ModelStats();this.importWarnings_=[];this.reportedImportWarnings_={};this.isTimeHighResolution_=undefined;this.patchupsToApply_=[];this.doesHelperGUIDSupportThisModel_={};this.helpersByConstructorGUID_={};}
+Model.prototype={__proto__:tr.model.EventContainer.prototype,getOrCreateHelper:function(constructor){if(!constructor.guid)
+throw new Error('Helper constructors must have GUIDs');if(this.helpersByConstructorGUID_[constructor.guid]===undefined){if(this.doesHelperGUIDSupportThisModel_[constructor.guid]===undefined){this.doesHelperGUIDSupportThisModel_[constructor.guid]=constructor.supportsModel(this);}
+if(!this.doesHelperGUIDSupportThisModel_[constructor.guid])
+return undefined;this.helpersByConstructorGUID_[constructor.guid]=new constructor(this);}
+return this.helpersByConstructorGUID_[constructor.guid];},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,GlobalMemoryDump))
 this.globalMemoryDumps.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,GlobalInstantEvent))
 this.instantEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,FlowEvent))
 this.flowEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Alert))
-this.alerts.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,InteractionRecord))
-this.interactionRecords.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Sample))
-this.samples.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){callback.call(opt_this,this.device);callback.call(opt_this,this.kernel);for(var pid in this.processes)
+this.alerts.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Sample))
+this.samples.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){callback.call(opt_this,this.userModel);callback.call(opt_this,this.device);callback.call(opt_this,this.kernel);for(var pid in this.processes)
 callback.call(opt_this,this.processes[pid]);},iterateAllPersistableObjects:function(callback){this.kernel.iterateAllPersistableObjects(callback);for(var pid in this.processes)
 this.processes[pid].iterateAllPersistableObjects(callback);},updateBounds:function(){this.bounds.reset();var bounds=this.bounds;this.iterateAllChildEventContainers(function(ec){ec.updateBounds();bounds.addRange(ec.bounds);});this.iterateAllEventsInThisContainer(function(eventConstructor){return true;},function(event){event.addBoundsToRange(bounds);});},shiftWorldToZero:function(){var shiftAmount=-this.bounds.min;this.timestampShiftToZeroAmount_=shiftAmount;this.iterateAllChildEventContainers(function(ec){ec.shiftTimestampsForward(shiftAmount);});this.iterateAllEventsInThisContainer(function(eventConstructor){return true;},function(event){event.start+=shiftAmount;});this.updateBounds();},convertTimestampToModelTime:function(sourceClockDomainName,ts){if(sourceClockDomainName!=='traceEventClock')
-throw new Error('Only traceEventClock is supported.');return tr.b.u.Units.timestampFromUs(ts)+
+throw new Error('Only traceEventClock is supported.');return tr.v.Unit.timestampFromUs(ts)+
 this.timestampShiftToZeroAmount_;},get numProcesses(){var n=0;for(var p in this.processes)
 n++;return n;},getProcess:function(pid){return this.processes[pid];},getOrCreateProcess:function(pid){if(!this.processes[pid])
-this.processes[pid]=new Process(this,pid);return this.processes[pid];},pushInstantEvent:function(instantEvent){this.instantEvents.push(instantEvent);},addStackFrame:function(stackFrame){if(this.stackFrames[stackFrame.id])
-throw new Error('Stack frame already exists');this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},addInteractionRecord:function(ir){this.interactionRecords.push(ir);return ir;},getClockSyncRecordsNamed:function(name){return this.clockSyncRecords.filter(function(x){return x.name===name;});},updateCategories_:function(){var categoriesDict={};this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(var pid in this.processes)
+this.processes[pid]=new Process(this,pid);return this.processes[pid];},addStackFrame:function(stackFrame){if(this.stackFrames[stackFrame.id])
+throw new Error('Stack frame already exists');this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},getClockSyncRecordsWithSyncId:function(syncId){return this.clockSyncRecords.filter(function(x){return x.syncId===syncId;});},updateCategories_:function(){var categoriesDict={};this.userModel.addCategoriesToDict(categoriesDict);this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(var pid in this.processes)
 this.processes[pid].addCategoriesToDict(categoriesDict);this.categories=[];for(var category in categoriesDict)
 if(category!='')
 this.categories.push(category);},getAllThreads:function(){var threads=[];for(var tid in this.kernel.threads){threads.push(process.threads[tid]);}
@@ -3670,14 +4197,21 @@
 return threads;},getAllProcesses:function(){var processes=[];for(var pid in this.processes)
 processes.push(this.processes[pid]);return processes;},getAllCounters:function(){var counters=[];counters.push.apply(counters,tr.b.dictionaryValues(this.device.counters));counters.push.apply(counters,tr.b.dictionaryValues(this.kernel.counters));for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.counters){counters.push(process.counters[tid]);}}
 return counters;},getAnnotationByGUID:function(guid){return this.annotationsByGuid_[guid];},addAnnotation:function(annotation){if(!annotation.guid)
-throw new Error('Annotation with undefined guid given');this.annotationsByGuid_[annotation.guid]=annotation;tr.b.dispatchSimpleEvent(this,'annotationChange');},removeAnnotation:function(annotation){this.annotationsByGuid_[annotation.guid].onRemove();delete this.annotationsByGuid_[annotation.guid];tr.b.dispatchSimpleEvent(this,'annotationChange');},getAllAnnotations:function(){return tr.b.dictionaryValues(this.annotationsByGuid_);},findAllThreadsNamed:function(name){var namedThreads=[];namedThreads.push.apply(namedThreads,this.kernel.findAllThreadsNamed(name));for(var pid in this.processes){namedThreads.push.apply(namedThreads,this.processes[pid].findAllThreadsNamed(name));}
-return namedThreads;},set importOptions(options){this.importOptions_=options;},get intrinsicTimeUnit(){if(this.intrinsicTimeUnit_===undefined)
-return tr.b.u.TimeDisplayModes.ms;return this.intrinsicTimeUnit_;},set intrinsicTimeUnit(value){if(this.intrinsicTimeUnit_===value)
+throw new Error('Annotation with undefined guid given');this.annotationsByGuid_[annotation.guid]=annotation;tr.b.dispatchSimpleEvent(this,'annotationChange');},removeAnnotation:function(annotation){this.annotationsByGuid_[annotation.guid].onRemove();delete this.annotationsByGuid_[annotation.guid];tr.b.dispatchSimpleEvent(this,'annotationChange');},getAllAnnotations:function(){return tr.b.dictionaryValues(this.annotationsByGuid_);},addUserFriendlyCategoryDriver:function(ufcd){this.userFriendlyCategoryDrivers_.push(ufcd);},getUserFriendlyCategoryFromEvent:function(event){for(var i=0;i<this.userFriendlyCategoryDrivers_.length;i++){var ufc=this.userFriendlyCategoryDrivers_[i].fromEvent(event);if(ufc!==undefined)
+return ufc;}
+return undefined;},findAllThreadsNamed:function(name){var namedThreads=[];namedThreads.push.apply(namedThreads,this.kernel.findAllThreadsNamed(name));for(var pid in this.processes){namedThreads.push.apply(namedThreads,this.processes[pid].findAllThreadsNamed(name));}
+return namedThreads;},get importOptions(){return this.importOptions_;},set importOptions(options){this.importOptions_=options;},get intrinsicTimeUnit(){if(this.intrinsicTimeUnit_===undefined)
+return tr.v.TimeDisplayModes.ms;return this.intrinsicTimeUnit_;},set intrinsicTimeUnit(value){if(this.intrinsicTimeUnit_===value)
 return;if(this.intrinsicTimeUnit_!==undefined)
-throw new Error('Intrinsic time unit already set');this.intrinsicTimeUnit_=value;},importWarning:function(data){data.showToUser=!!data.showToUser;this.importWarnings_.push(data);if(this.reportedImportWarnings_[data.type]===true)
+throw new Error('Intrinsic time unit already set');this.intrinsicTimeUnit_=value;},get isTimeHighResolution(){if(this.isTimeHighResolution_===undefined)
+this.isTimeHighResolution_=this.isTimeHighResolutionHeuristic_();return this.isTimeHighResolution_;},set isTimeHighResolution(value){if(this.isTimeHighResolution_===value)
+return;if(this.isTimeHighResolution_!==undefined)
+throw new Error('isTimeHighResolution already set');this.isTimeHighResolution_=value;},get canonicalUrl(){return this.canonicalUrl_;},set canonicalUrl(value){if(this.canonicalUrl_===value)
+return;if(this.canonicalUrl_!==undefined)
+throw new Error('canonicalUrl already set');this.canonicalUrl_=value;},importWarning:function(data){data.showToUser=!!data.showToUser;this.importWarnings_.push(data);if(this.reportedImportWarnings_[data.type]===true)
 return;if(this.importOptions_.showImportWarnings)
-console.warn(data.message);this.reportedImportWarnings_[data.type]=true;},get hasImportWarnings(){return(this.importWarnings_.length>0);},get importWarnings(){return this.importWarnings_;},get importWarningsThatShouldBeShownToUser(){return this.importWarnings_.filter(function(warning){return warning.showToUser;});},autoCloseOpenSlices:function(){this.samples.sort(function(x,y){return x.start-y.start;});this.updateBounds();this.kernel.autoCloseOpenSlices(this.bounds.max);for(var pid in this.processes)
-this.processes[pid].autoCloseOpenSlices(this.bounds.max);},createSubSlices:function(){this.kernel.createSubSlices();for(var pid in this.processes)
+console.warn(data.message);this.reportedImportWarnings_[data.type]=true;},get hasImportWarnings(){return(this.importWarnings_.length>0);},get importWarnings(){return this.importWarnings_;},get importWarningsThatShouldBeShownToUser(){return this.importWarnings_.filter(function(warning){return warning.showToUser;});},autoCloseOpenSlices:function(){this.samples.sort(function(x,y){return x.start-y.start;});this.updateBounds();this.kernel.autoCloseOpenSlices();for(var pid in this.processes)
+this.processes[pid].autoCloseOpenSlices();},createSubSlices:function(){this.kernel.createSubSlices();for(var pid in this.processes)
 this.processes[pid].createSubSlices();},preInitializeObjects:function(){for(var pid in this.processes)
 this.processes[pid].preInitializeObjects();},initializeObjects:function(){for(var pid in this.processes)
 this.processes[pid].initializeObjects();},pruneEmptyContainers:function(){this.kernel.pruneEmptyContainers();for(var pid in this.processes)
@@ -3686,31 +4220,502 @@
 this.shiftWorldToZero();},buildFlowEventIntervalTree:function(){for(var i=0;i<this.flowEvents.length;++i){var flowEvent=this.flowEvents[i];this.flowIntervalTree.insert(flowEvent);}
 this.flowIntervalTree.updateHighValues();},cleanupUndeletedObjects:function(){for(var pid in this.processes)
 this.processes[pid].autoDeleteObjects(this.bounds.max);},sortMemoryDumps:function(){this.globalMemoryDumps.sort(function(x,y){return x.start-y.start;});for(var pid in this.processes)
-this.processes[pid].sortMemoryDumps();},calculateMemoryGraphAttributes:function(){this.globalMemoryDumps.forEach(function(dump){dump.calculateGraphAttributes();});},buildEventIndices:function(){this.modelIndices=new tr.model.ModelIndices(this);},sortInteractionRecords:function(){this.interactionRecords.sort(function(x,y){return x.start-y.start;});},sortAlerts:function(){this.alerts.sort(function(x,y){return x.start-y.start;});}};return{ClockSyncRecord:ClockSyncRecord,Model:Model};});'use strict';tr.exportTo('tr.importer',function(){function EmptyImporter(events){this.importPriority=0;};EmptyImporter.canImport=function(eventData){if(eventData instanceof Array&&eventData.length==0)
-return true;if(typeof(eventData)==='string'||eventData instanceof String){return eventData.length==0;}
-return false;};EmptyImporter.prototype={__proto__:tr.importer.Importer.prototype};tr.importer.Importer.register(EmptyImporter);return{EmptyImporter:EmptyImporter};});'use strict';tr.exportTo('tr.importer',function(){function ImportOptions(){this.shiftWorldToZero=true;this.pruneEmptyContainers=true;this.showImportWarnings=true;this.customizeModelCallback=undefined;var auditorTypes=tr.c.Auditor.getAllRegisteredTypeInfos();this.auditorConstructors=auditorTypes.map(function(typeInfo){return typeInfo.constructor;});}
-function Import(model,opt_options){if(model===undefined)
-throw new Error('Must provide model to import into.');this.importing_=false;this.importOptions_=opt_options||new ImportOptions();this.model_=model;this.model_.importOptions=this.importOptions_;}
-Import.prototype={__proto__:Object.prototype,importTraces:function(traces){var progressMeter={update:function(msg){}};tr.b.Task.RunSynchronously(this.createImportTracesTask(progressMeter,traces));},importTracesWithProgressDialog:function(traces){if(tr.isHeadless)
-throw new Error('Cannot use this method in headless mode.');var overlay=tr.ui.b.Overlay();overlay.title='Importing...';overlay.userCanClose=false;overlay.msgEl=document.createElement('div');overlay.appendChild(overlay.msgEl);overlay.msgEl.style.margin='20px';overlay.update=function(msg){this.msgEl.textContent=msg;}
-overlay.visible=true;var promise=tr.b.Task.RunWhenIdle(this.createImportTracesTask(overlay,traces));promise.then(function(){overlay.visible=false;},function(err){overlay.visible=false;});return promise;},createImportTracesTask:function(progressMeter,traces){if(this.importing_)
-throw new Error('Already importing.');this.importing_=true;var importTask=new tr.b.Task(function(){progressMeter.update('I will now import your traces for you...');},this);var lastTask=importTask;var importers=[];lastTask=lastTask.after(function(){traces=traces.slice(0);progressMeter.update('Creating importers...');for(var i=0;i<traces.length;++i)
-importers.push(this.createImporter_(traces[i]));for(var i=0;i<importers.length;i++){var subtraces=importers[i].extractSubtraces();for(var j=0;j<subtraces.length;j++){try{traces.push(subtraces[j]);importers.push(this.createImporter_(subtraces[j]));}catch(error){console.warn(error.name+': '+error.message);continue;}}}
-if(traces.length&&!this.hasEventDataDecoder_(importers)){throw new Error('Could not find an importer for the provided eventData.');}
-importers.sort(function(x,y){return x.importPriority-y.importPriority;});},this);lastTask=lastTask.after(function(task){importers.forEach(function(importer,index){task.subTask(function(){progressMeter.update('Importing '+(index+1)+' of '+importers.length);importer.importEvents();},this);},this);},this);if(this.importOptions_.customizeModelCallback){lastTask=lastTask.after(function(task){this.importOptions_.customizeModelCallback(this.model_);},this);}
-lastTask=lastTask.after(function(task){importers.forEach(function(importer,index){progressMeter.update('Importing sample data '+(index+1)+'/'+importers.length);importer.importSampleData();},this);},this);lastTask=lastTask.after(function(){progressMeter.update('Autoclosing open slices...');this.model_.autoCloseOpenSlices();this.model_.createSubSlices();},this);lastTask=lastTask.after(function(task){importers.forEach(function(importer,index){progressMeter.update('Finalizing import '+(index+1)+'/'+importers.length);importer.finalizeImport();},this);},this);lastTask=lastTask.after(function(){progressMeter.update('Initializing objects (step 1/2)...');this.model_.preInitializeObjects();},this);if(this.importOptions_.pruneEmptyContainers){lastTask=lastTask.after(function(){progressMeter.update('Pruning empty containers...');this.model_.pruneEmptyContainers();},this);}
-lastTask=lastTask.after(function(){progressMeter.update('Merging kernel with userland...');this.model_.mergeKernelWithUserland();},this);var auditors=[];lastTask=lastTask.after(function(){progressMeter.update('Adding arbitrary data to model...');auditors=this.importOptions_.auditorConstructors.map(function(auditorConstructor){return new auditorConstructor(this.model_);},this);auditors.forEach(function(auditor){auditor.runAnnotate();});},this);lastTask=lastTask.after(function(){progressMeter.update('Computing final world bounds...');this.model_.computeWorldBounds(this.importOptions_.shiftWorldToZero);},this);lastTask=lastTask.after(function(){progressMeter.update('Building flow event map...');this.model_.buildFlowEventIntervalTree();},this);lastTask=lastTask.after(function(){progressMeter.update('Joining object refs...');for(var i=0;i<importers.length;i++)
-importers[i].joinRefs();},this);lastTask=lastTask.after(function(){progressMeter.update('Cleaning up undeleted objects...');this.model_.cleanupUndeletedObjects();},this);lastTask=lastTask.after(function(){progressMeter.update('Sorting memory dumps...');this.model_.sortMemoryDumps();},this);lastTask=lastTask.after(function(){progressMeter.update('Calculating memory dump graph attributes...');this.model_.calculateMemoryGraphAttributes();},this);lastTask=lastTask.after(function(){progressMeter.update('Initializing objects (step 2/2)...');this.model_.initializeObjects();},this);lastTask=lastTask.after(function(){progressMeter.update('Building flow event indices...');this.model_.buildEventIndices();},this);lastTask=lastTask.after(function(){progressMeter.update('Running auditors...');auditors.forEach(function(auditor){auditor.runAudit();});},this);lastTask=lastTask.after(function(){progressMeter.update('Updating interaction records...');this.model_.sortInteractionRecords();},this);lastTask=lastTask.after(function(){progressMeter.update('Updating alerts...');this.model_.sortAlerts();},this);lastTask=lastTask.after(function(){progressMeter.update('Update bounds...');this.model_.updateBounds();},this);lastTask.after(function(){this.importing_=false;},this);return importTask;},createImporter_:function(eventData){var importerConstructor=tr.importer.Importer.findImporterFor(eventData);if(!importerConstructor){throw new Error('Couldn\'t create an importer for the provided '+'eventData.');}
-return new importerConstructor(this.model_,eventData);},hasEventDataDecoder_:function(importers){if(importers.length===0)
-return false;for(var i=0;i<importers.length;++i){if(!importers[i].isTraceDataContainer())
-return true;}
-return false;}};return{ImportOptions:ImportOptions,Import:Import};});'use strict';tr.exportTo('tr.importer',function(){function SimpleLineReader(text){this.lines_=text.split('\n');this.curLine_=0;this.savedLines_=undefined;}
+this.processes[pid].sortMemoryDumps();},finalizeMemoryGraphs:function(){this.globalMemoryDumps.forEach(function(dump){dump.finalizeGraph();});},buildEventIndices:function(){this.modelIndices=new tr.model.ModelIndices(this);},sortAlerts:function(){this.alerts.sort(function(x,y){return x.start-y.start;});},applyObjectRefPatchups:function(){var unresolved=[];this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef in this.processes){var snapshot=this.processes[patchup.pidRef].objects.getSnapshotAt(patchup.scopedId,patchup.ts);if(snapshot){patchup.object[patchup.field]=snapshot;return;}}
+unresolved.push(patchup);},this);this.patchupsToApply_=unresolved;},replacePIDRefsInPatchups:function(old_pid_ref,new_pid_ref){this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef===old_pid_ref)
+patchup.pidRef=new_pid_ref;});},isTimeHighResolutionHeuristic_:function(){if(this.intrinsicTimeUnit!==tr.v.TimeDisplayModes.ms)
+return false;var nbEvents=0;var nbPerBin=[];var maxEvents=0;for(var i=0;i<100;++i)
+nbPerBin.push(0);this.iterateAllEvents(function(event){nbEvents++;if(event.start!==undefined){var remainder=Math.floor((event.start-Math.floor(event.start))*100);nbPerBin[remainder]++;maxEvents=Math.max(maxEvents,nbPerBin[remainder]);}});if(nbEvents<100)
+return true;return(maxEvents/nbEvents)<0.9;},joinRefs:function(){this.joinObjectRefs_();this.applyObjectRefPatchups();},joinObjectRefs_:function(){tr.b.iterItems(this.processes,function(pid,process){this.joinObjectRefsForProcess_(pid,process);},this);},joinObjectRefsForProcess_:function(pid,process){tr.b.iterItems(process.threads,function(tid,thread){thread.asyncSliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);thread.sliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);},this);process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(item){this.searchItemForIDRefs_(pid,'ts',item);},this);},this);},searchItemForIDRefs_:function(pid,itemTimestampField,item){if(!item.args)
+return;var patchupsToApply=this.patchupsToApply_;function handleField(object,fieldName,fieldValue){if(!fieldValue||(!fieldValue.id_ref&&!fieldValue.idRef))
+return;var scope=fieldValue.scope||tr.model.OBJECT_DEFAULT_SCOPE;var idRef=fieldValue.id_ref||fieldValue.idRef;var scopedId=new tr.model.ScopedId(scope,idRef);var pidRef=fieldValue.pid_ref||fieldValue.pidRef||pid;var ts=item[itemTimestampField];patchupsToApply.push({object:object,field:fieldName,pidRef:pidRef,scopedId:scopedId,ts:ts});}
+function iterObjectFieldsRecursively(object){if(!(object instanceof Object))
+return;if((object instanceof tr.model.ObjectSnapshot)||(object instanceof Float32Array)||(object instanceof tr.b.Quad))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++){handleField(object,i,object[i]);iterObjectFieldsRecursively(object[i]);}
+return;}
+for(var key in object){var value=object[key];handleField(object,key,value);iterObjectFieldsRecursively(value);}}
+iterObjectFieldsRecursively(item.args);}};return{Model:Model};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var kThreadGuid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadDCStartOpcode=3;function Decoder(){this.payload_=new DataView(new ArrayBuffer(256));};Decoder.prototype={__proto__:Object.prototype,reset:function(base64_payload){var decoded_size=tr.b.Base64.getDecodedBufferLength(base64_payload);if(decoded_size>this.payload_.byteLength)
+this.payload_=new DataView(new ArrayBuffer(decoded_size));tr.b.Base64.DecodeToTypedArray(base64_payload,this.payload_);this.position_=0;},skip:function(length){this.position_+=length;},decodeUInt8:function(){var result=this.payload_.getUint8(this.position_,true);this.position_+=1;return result;},decodeUInt16:function(){var result=this.payload_.getUint16(this.position_,true);this.position_+=2;return result;},decodeUInt32:function(){var result=this.payload_.getUint32(this.position_,true);this.position_+=4;return result;},decodeUInt64ToString:function(){var low=this.decodeUInt32();var high=this.decodeUInt32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},decodeInt8:function(){var result=this.payload_.getInt8(this.position_,true);this.position_+=1;return result;},decodeInt16:function(){var result=this.payload_.getInt16(this.position_,true);this.position_+=2;return result;},decodeInt32:function(){var result=this.payload_.getInt32(this.position_,true);this.position_+=4;return result;},decodeInt64ToString:function(){return this.decodeUInt64ToString();},decodeUInteger:function(is64){if(is64)
+return this.decodeUInt64ToString();return this.decodeUInt32();},decodeString:function(){var str='';while(true){var c=this.decodeUInt8();if(!c)
+return str;str=str+String.fromCharCode(c);}},decodeW16String:function(){var str='';while(true){var c=this.decodeUInt16();if(!c)
+return str;str=str+String.fromCharCode(c);}},decodeFixedW16String:function(length){var old_position=this.position_;var str='';for(var i=0;i<length;i++){var c=this.decodeUInt16();if(!c)
+break;str=str+String.fromCharCode(c);}
+this.position_=old_position+2*length;return str;},decodeBytes:function(length){var bytes=[];for(var i=0;i<length;++i){var c=this.decodeUInt8();bytes.push(c);}
+return bytes;},decodeSID:function(is64){var pSid=this.decodeUInteger(is64);var attributes=this.decodeUInt32();if(is64)
+this.decodeUInt32();var revision=this.decodeUInt8();var subAuthorityCount=this.decodeUInt8();this.decodeUInt16();this.decodeUInt32();if(revision!=1)
+throw'Invalid SID revision: could not decode the SID structure.';var sid=this.decodeBytes(4*subAuthorityCount);return{pSid:pSid,attributes:attributes,sid:sid};},decodeSystemTime:function(){var wYear=this.decodeInt16();var wMonth=this.decodeInt16();var wDayOfWeek=this.decodeInt16();var wDay=this.decodeInt16();var wHour=this.decodeInt16();var wMinute=this.decodeInt16();var wSecond=this.decodeInt16();var wMilliseconds=this.decodeInt16();return{wYear:wYear,wMonth:wMonth,wDayOfWeek:wDayOfWeek,wDay:wDay,wHour:wHour,wMinute:wMinute,wSecond:wSecond,wMilliseconds:wMilliseconds};},decodeTimeZoneInformation:function(){var bias=this.decodeUInt32();var standardName=this.decodeFixedW16String(32);var standardDate=this.decodeSystemTime();var standardBias=this.decodeUInt32();var daylightName=this.decodeFixedW16String(32);var daylightDate=this.decodeSystemTime();var daylightBias=this.decodeUInt32();return{bias:bias,standardName:standardName,standardDate:standardDate,standardBias:standardBias,daylightName:daylightName,daylightDate:daylightDate,daylightBias:daylightBias};}};function EtwImporter(model,events){this.importPriority=3;this.model_=model;this.events_=events;this.handlers_={};this.decoder_=new Decoder();this.walltime_=undefined;this.ticks_=undefined;this.is64bit_=undefined;this.tidsToPid_={};var allTypeInfos=tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();this.parsers_=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);}
+EtwImporter.canImport=function(events){if(!events.hasOwnProperty('name')||!events.hasOwnProperty('content')||events.name!=='ETW'){return false;}
+return true;};EtwImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EtwImporter';},get model(){return this.model_;},createThreadIfNeeded:function(pid,tid){this.tidsToPid_[tid]=pid;},removeThreadIfPresent:function(tid){this.tidsToPid_[tid]=undefined;},getPidFromWindowsTid:function(tid){if(tid==0)
+return 0;var pid=this.tidsToPid_[tid];if(pid==undefined){return 0;}
+return pid;},getThreadFromWindowsTid:function(tid){var pid=this.getPidFromWindowsTid(tid);var process=this.model_.getProcess(pid);if(!process)
+return undefined;return process.getThread(tid);},getOrCreateCpu:function(cpuNumber){var cpu=this.model_.kernel.getOrCreateCpu(cpuNumber);return cpu;},importEvents:function(){this.events_.content.forEach(this.parseInfo.bind(this));if(this.walltime_==undefined||this.ticks_==undefined)
+throw Error('Cannot find clock sync information in the system trace.');if(this.is64bit_==undefined)
+throw Error('Cannot determine pointer size of the system trace.');this.events_.content.forEach(this.parseEvent.bind(this));},importTimestamp:function(timestamp){var ts=parseInt(timestamp,16);return(ts-this.walltime_+this.ticks_)/1000.;},parseInfo:function(event){if(event.hasOwnProperty('guid')&&event.hasOwnProperty('walltime')&&event.hasOwnProperty('tick')&&event.guid==='ClockSync'){this.walltime_=parseInt(event.walltime,16);this.ticks_=parseInt(event.tick,16);}
+if(this.is64bit_==undefined&&event.hasOwnProperty('guid')&&event.hasOwnProperty('op')&&event.hasOwnProperty('ver')&&event.hasOwnProperty('payload')&&event.guid===kThreadGuid&&event.op==kThreadDCStartOpcode){var decoded_size=tr.b.Base64.getDecodedBufferLength(event.payload);if(event.ver==1){if(decoded_size>=52)
+this.is64bit_=true;else
+this.is64bit_=false;}else if(event.ver==2){if(decoded_size>=64)
+this.is64bit_=true;else
+this.is64bit_=false;}else if(event.ver==3){if(decoded_size>=60)
+this.is64bit_=true;else
+this.is64bit_=false;}}
+return true;},parseEvent:function(event){if(!event.hasOwnProperty('guid')||!event.hasOwnProperty('op')||!event.hasOwnProperty('ver')||!event.hasOwnProperty('cpu')||!event.hasOwnProperty('ts')||!event.hasOwnProperty('payload')){return false;}
+var timestamp=this.importTimestamp(event.ts);var header={guid:event.guid,opcode:event.op,version:event.ver,cpu:event.cpu,timestamp:timestamp,is64:this.is64bit_};var decoder=this.decoder_;decoder.reset(event.payload);var handler=this.getEventHandler(header.guid,header.opcode);if(!handler)
+return false;if(!handler(header,decoder)){this.model_.importWarning({type:'parse_error',message:'Malformed '+header.guid+' event ('+text+')'});return false;}
+return true;},registerEventHandler:function(guid,opcode,handler){if(this.handlers_[guid]==undefined)
+this.handlers_[guid]=[];this.handlers_[guid][opcode]=handler;},getEventHandler:function(guid,opcode){if(this.handlers_[guid]==undefined)
+return undefined;return this.handlers_[guid][opcode];}};tr.importer.Importer.register(EtwImporter);return{EtwImporter:EtwImporter};});!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});'use strict';if(tr.isVinn){global.window={};}'use strict';if(tr.isVinn){global.JSZip=global.window.JSZip;global.window=undefined;}else if(tr.isNode){var jsZipAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/jszip.min.js');var jsZipModule=require(jsZipAbsPath);global.JSZip=jsZipModule;}'use strict';tr.exportTo('tr.e.importer',function(){var GZIP_MEMBER_HEADER_ID_SIZE=3;var GZIP_HEADER_ID1=0x1f;var GZIP_HEADER_ID2=0x8b;var GZIP_DEFLATE_COMPRESSION=8;function GzipImporter(model,eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=JSZip.utils.transformTo('uint8array',eventData);}else if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}else
+throw new Error('Unknown gzip data format');this.model_=model;this.gzipData_=eventData;}
+GzipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
+header=new Uint8Array(eventData.slice(0,GZIP_MEMBER_HEADER_ID_SIZE));else if(typeof(eventData)==='string'||eventData instanceof String){header=eventData.substring(0,GZIP_MEMBER_HEADER_ID_SIZE);header=JSZip.utils.transformTo('uint8array',header);}else
+return false;return header[0]==GZIP_HEADER_ID1&&header[1]==GZIP_HEADER_ID2&&header[2]==GZIP_DEFLATE_COMPRESSION;};GzipImporter.inflateGzipData_=function(data){var position=0;function getByte(){if(position>=data.length)
+throw new Error('Unexpected end of gzip data');return data[position++];}
+function getWord(){var low=getByte();var high=getByte();return(high<<8)+low;}
+function skipBytes(amount){position+=amount;}
+function skipZeroTerminatedString(){while(getByte()!=0){}}
+var id1=getByte();var id2=getByte();if(id1!==GZIP_HEADER_ID1||id2!==GZIP_HEADER_ID2)
+throw new Error('Not gzip data');var compression_method=getByte();if(compression_method!==GZIP_DEFLATE_COMPRESSION)
+throw new Error('Unsupported compression method: '+compression_method);var flags=getByte();var have_header_crc=flags&(1<<1);var have_extra_fields=flags&(1<<2);var have_file_name=flags&(1<<3);var have_comment=flags&(1<<4);skipBytes(4+1+1);if(have_extra_fields){var bytes_to_skip=getWord();skipBytes(bytes_to_skip);}
+if(have_file_name)
+skipZeroTerminatedString();if(have_comment)
+skipZeroTerminatedString();if(have_header_crc)
+getWord();var inflated_data=JSZip.compressions['DEFLATE'].uncompress(data.subarray(position));var string=GzipImporter.transformToString(inflated_data);if(inflated_data.length>0&&string.length===0){throw new RangeError('Inflated gzip data too long to fit into a string'+' ('+inflated_data.length+').');}
+return string;};GzipImporter.transformToString=function(data){if(typeof TextDecoder==='undefined'){return JSZip.utils.transformTo('string',data);}
+var type=JSZip.utils.getTypeOf(data);if(type==='string')
+return data;if(type==='array'){data=new Uint8Array(data);}
+var decoder=new TextDecoder('utf-8');return decoder.decode(data);};GzipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GzipImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){var eventData=GzipImporter.inflateGzipData_(this.gzipData_);return eventData?[eventData]:[];}};tr.importer.Importer.register(GzipImporter);return{GzipImporter:GzipImporter};});'use strict';tr.exportTo('tr.importer',function(){function SimpleLineReader(text){this.lines_=text.split('\n');this.curLine_=0;this.savedLines_=undefined;}
 SimpleLineReader.prototype={advanceToLineMatching:function(regex){for(;this.curLine_<this.lines_.length;this.curLine_++){var line=this.lines_[this.curLine_];if(this.savedLines_!==undefined)
 this.savedLines_.push(line);if(regex.test(line))
 return true;}
-return false;},get curLineNumber(){return this.curLine_;},beginSavingLines:function(){this.savedLines_=[];},endSavingLinesAndGetResult:function(){var tmp=this.savedLines_;this.savedLines_=undefined;return tmp;}};return{SimpleLineReader:SimpleLineReader};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function Activity(name,category,range,args){tr.model.TimedEvent.call(this,range.min);this.title=name;this.category=category;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(name);this.duration=range.duration;this.args=args;this.name=name;};Activity.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};return{Activity:Activity};});'use strict';tr.exportTo('tr.e.importer.android',function(){var Importer=tr.importer.Importer;var ACTIVITY_STATE={NONE:'none',CREATED:'created',STARTED:'started',RESUMED:'resumed',PAUSED:'paused',STOPPED:'stopped',DESTROYED:'destroyed'};var activityMap={};function EventLogImporter(model,events){this.model_=model;this.events_=events;this.importPriority=3;}
+return false;},get curLineNumber(){return this.curLine_;},beginSavingLines:function(){this.savedLines_=[];},endSavingLinesAndGetResult:function(){var tmp=this.savedLines_;this.savedLines_=undefined;return tmp;}};return{SimpleLineReader:SimpleLineReader};});'use strict';tr.exportTo('tr.e.importer',function(){function Trace2HTMLImporter(model,events){this.importPriority=0;}
+Trace2HTMLImporter.subtraces_=[];function _extractEventsFromHTML(text){Trace2HTMLImporter.subtraces_=[];var r=new tr.importer.SimpleLineReader(text);while(true){if(!r.advanceToLineMatching(new RegExp('^<\s*script id="viewer-data" '+'type="(application\/json|text\/plain)">$')))
+break;r.beginSavingLines();if(!r.advanceToLineMatching(/^<\/\s*script>$/))
+return failure;var raw_events=r.endSavingLinesAndGetResult();raw_events=raw_events.slice(1,raw_events.length-1);var data64=raw_events.join('\n');var buffer=new ArrayBuffer(tr.b.Base64.getDecodedBufferLength(data64));var len=tr.b.Base64.DecodeToTypedArray(data64,new DataView(buffer));Trace2HTMLImporter.subtraces_.push(buffer.slice(0,len));}}
+function _canImportFromHTML(text){if(/^<!DOCTYPE html>/.test(text)===false)
+return false;_extractEventsFromHTML(text);if(Trace2HTMLImporter.subtraces_.length===0)
+return false;return true;}
+Trace2HTMLImporter.canImport=function(events){return _canImportFromHTML(events);};Trace2HTMLImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'Trace2HTMLImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){return Trace2HTMLImporter.subtraces_;},importEvents:function(){}};tr.importer.Importer.register(Trace2HTMLImporter);return{Trace2HTMLImporter:Trace2HTMLImporter};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function SplayTree(){};SplayTree.prototype.root_=null;SplayTree.prototype.isEmpty=function(){return!this.root_;};SplayTree.prototype.insert=function(key,value){if(this.isEmpty()){this.root_=new SplayTree.Node(key,value);return;}
+this.splay_(key);if(this.root_.key==key){return;}
+var node=new SplayTree.Node(key,value);if(key>this.root_.key){node.left=this.root_;node.right=this.root_.right;this.root_.right=null;}else{node.right=this.root_;node.left=this.root_.left;this.root_.left=null;}
+this.root_=node;};SplayTree.prototype.remove=function(key){if(this.isEmpty()){throw Error('Key not found: '+key);}
+this.splay_(key);if(this.root_.key!=key){throw Error('Key not found: '+key);}
+var removed=this.root_;if(!this.root_.left){this.root_=this.root_.right;}else{var right=this.root_.right;this.root_=this.root_.left;this.splay_(key);this.root_.right=right;}
+return removed;};SplayTree.prototype.find=function(key){if(this.isEmpty()){return null;}
+this.splay_(key);return this.root_.key==key?this.root_:null;};SplayTree.prototype.findMin=function(){if(this.isEmpty()){return null;}
+var current=this.root_;while(current.left){current=current.left;}
+return current;};SplayTree.prototype.findMax=function(opt_startNode){if(this.isEmpty()){return null;}
+var current=opt_startNode||this.root_;while(current.right){current=current.right;}
+return current;};SplayTree.prototype.findGreatestLessThan=function(key){if(this.isEmpty()){return null;}
+this.splay_(key);if(this.root_.key<=key){return this.root_;}else if(this.root_.left){return this.findMax(this.root_.left);}else{return null;}};SplayTree.prototype.exportKeysAndValues=function(){var result=[];this.traverse_(function(node){result.push([node.key,node.value]);});return result;};SplayTree.prototype.exportValues=function(){var result=[];this.traverse_(function(node){result.push(node.value);});return result;};SplayTree.prototype.splay_=function(key){if(this.isEmpty()){return;}
+var dummy,left,right;dummy=left=right=new SplayTree.Node(null,null);var current=this.root_;while(true){if(key<current.key){if(!current.left){break;}
+if(key<current.left.key){var tmp=current.left;current.left=tmp.right;tmp.right=current;current=tmp;if(!current.left){break;}}
+right.left=current;right=current;current=current.left;}else if(key>current.key){if(!current.right){break;}
+if(key>current.right.key){var tmp=current.right;current.right=tmp.left;tmp.left=current;current=tmp;if(!current.right){break;}}
+left.right=current;left=current;current=current.right;}else{break;}}
+left.right=current.left;right.left=current.right;current.left=dummy.right;current.right=dummy.left;this.root_=current;};SplayTree.prototype.traverse_=function(f){var nodesToVisit=[this.root_];while(nodesToVisit.length>0){var node=nodesToVisit.shift();if(node==null){continue;}
+f(node);nodesToVisit.push(node.left);nodesToVisit.push(node.right);}};SplayTree.Node=function(key,value){this.key=key;this.value=value;};SplayTree.Node.prototype.left=null;SplayTree.Node.prototype.right=null;return{SplayTree:SplayTree};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CodeMap(){this.dynamics_=new tr.e.importer.v8.SplayTree();this.dynamicsNameGen_=new tr.e.importer.v8.CodeMap.NameGenerator();this.statics_=new tr.e.importer.v8.SplayTree();this.libraries_=new tr.e.importer.v8.SplayTree();this.pages_=[];};CodeMap.PAGE_ALIGNMENT=12;CodeMap.PAGE_SIZE=1<<CodeMap.PAGE_ALIGNMENT;CodeMap.prototype.addCode=function(start,codeEntry){this.deleteAllCoveredNodes_(this.dynamics_,start,start+codeEntry.size);this.dynamics_.insert(start,codeEntry);};CodeMap.prototype.moveCode=function(from,to){var removedNode=this.dynamics_.remove(from);this.deleteAllCoveredNodes_(this.dynamics_,to,to+removedNode.value.size);this.dynamics_.insert(to,removedNode.value);};CodeMap.prototype.deleteCode=function(start){var removedNode=this.dynamics_.remove(start);};CodeMap.prototype.addLibrary=function(start,codeEntry){this.markPages_(start,start+codeEntry.size);this.libraries_.insert(start,codeEntry);};CodeMap.prototype.addStaticCode=function(start,codeEntry){this.statics_.insert(start,codeEntry);};CodeMap.prototype.markPages_=function(start,end){for(var addr=start;addr<=end;addr+=CodeMap.PAGE_SIZE){this.pages_[addr>>>CodeMap.PAGE_ALIGNMENT]=1;}};CodeMap.prototype.deleteAllCoveredNodes_=function(tree,start,end){var to_delete=[];var addr=end-1;while(addr>=start){var node=tree.findGreatestLessThan(addr);if(!node)break;var start2=node.key,end2=start2+node.value.size;if(start2<end&&start<end2)to_delete.push(start2);addr=start2-1;}
+for(var i=0,l=to_delete.length;i<l;++i)tree.remove(to_delete[i]);};CodeMap.prototype.isAddressBelongsTo_=function(addr,node){return addr>=node.key&&addr<(node.key+node.value.size);};CodeMap.prototype.findInTree_=function(tree,addr){var node=tree.findGreatestLessThan(addr);return node&&this.isAddressBelongsTo_(addr,node)?node.value:null;};CodeMap.prototype.findEntry=function(addr){var pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.statics_,addr)||this.findInTree_(this.libraries_,addr);}
+var min=this.dynamics_.findMin();var max=this.dynamics_.findMax();if(max!=null&&addr<(max.key+max.value.size)&&addr>=min.key){var dynaEntry=this.findInTree_(this.dynamics_,addr);if(dynaEntry==null)return null;if(!dynaEntry.nameUpdated_){dynaEntry.name=this.dynamicsNameGen_.getName(dynaEntry.name);dynaEntry.nameUpdated_=true;}
+return dynaEntry;}
+return null;};CodeMap.prototype.findDynamicEntryByStartAddress=function(addr){var node=this.dynamics_.find(addr);return node?node.value:null;};CodeMap.prototype.getAllDynamicEntries=function(){return this.dynamics_.exportValues();};CodeMap.prototype.getAllDynamicEntriesWithAddresses=function(){return this.dynamics_.exportKeysAndValues();};CodeMap.prototype.getAllStaticEntries=function(){return this.statics_.exportValues();};CodeMap.prototype.getAllLibrariesEntries=function(){return this.libraries_.exportValues();};CodeMap.CodeEntry=function(size,opt_name){this.id=tr.b.GUID.allocate();this.size=size;this.name=opt_name||'';this.nameUpdated_=false;};CodeMap.CodeEntry.prototype.getName=function(){return this.name;};CodeMap.CodeEntry.prototype.toString=function(){return this.name+': '+this.size.toString(16);};CodeMap.NameGenerator=function(){this.knownNames_={};};CodeMap.NameGenerator.prototype.getName=function(name){if(!(name in this.knownNames_)){this.knownNames_[name]=0;return name;}
+var count=++this.knownNames_[name];return name+' {'+count+'}';};return{CodeMap:CodeMap};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CsvParser(){};CsvParser.CSV_FIELD_RE_=/^"((?:[^"]|"")*)"|([^,]*)/;CsvParser.DOUBLE_QUOTE_RE_=/""/g;CsvParser.prototype.parseLine=function(line){var fieldRe=CsvParser.CSV_FIELD_RE_;var doubleQuoteRe=CsvParser.DOUBLE_QUOTE_RE_;var pos=0;var endPos=line.length;var fields=[];if(endPos>0){do{var fieldMatch=fieldRe.exec(line.substr(pos));if(typeof fieldMatch[1]==='string'){var field=fieldMatch[1];pos+=field.length+3;fields.push(field.replace(doubleQuoteRe,'"'));}else{var field=fieldMatch[2];pos+=field.length+1;fields.push(field);}}while(pos<=endPos);}
+return fields;};function LogReader(dispatchTable){this.dispatchTable_=dispatchTable;this.lineNum_=0;this.csvParser_=new CsvParser();};LogReader.prototype.printError=function(str){};LogReader.prototype.processLogChunk=function(chunk){this.processLog_(chunk.split('\n'));};LogReader.prototype.processLogLine=function(line){this.processLog_([line]);};LogReader.prototype.processStack=function(pc,func,stack){var fullStack=func?[pc,func]:[pc];var prevFrame=pc;for(var i=0,n=stack.length;i<n;++i){var frame=stack[i];var firstChar=frame.charAt(0);if(firstChar=='+'||firstChar=='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!='o'){fullStack.push(parseInt(frame,16));}}
+return fullStack;};LogReader.prototype.skipDispatch=function(dispatch){return false;};LogReader.prototype.dispatchLogRow_=function(fields){var command=fields[0];if(!(command in this.dispatchTable_))return;var dispatch=this.dispatchTable_[command];if(dispatch===null||this.skipDispatch(dispatch)){return;}
+var parsedFields=[];for(var i=0;i<dispatch.parsers.length;++i){var parser=dispatch.parsers[i];if(parser===null){parsedFields.push(fields[1+i]);}else if(typeof parser=='function'){parsedFields.push(parser(fields[1+i]));}else{parsedFields.push(fields.slice(1+i));break;}}
+dispatch.processor.apply(this,parsedFields);};LogReader.prototype.processLog_=function(lines){for(var i=0,n=lines.length;i<n;++i,++this.lineNum_){var line=lines[i];if(!line){continue;}
+try{var fields=this.csvParser_.parseLine(line);this.dispatchLogRow_(fields);}catch(e){this.printError('line '+(this.lineNum_+1)+': '+
+(e.message||e));}}};return{LogReader:LogReader};});'use strict';tr.exportTo('tr.e.importer.v8',function(){var ColorScheme=tr.b.ColorScheme;function V8LogImporter(model,eventData){this.importPriority=3;this.model_=model;this.logData_=eventData;this.code_map_=new tr.e.importer.v8.CodeMap();this.v8_timer_thread_=undefined;this.v8_thread_=undefined;this.root_stack_frame_=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8_stack_timeline_=new Array();}
+var kV8BinarySuffixes=['/d8','/libv8.so'];var TimerEventDefaultArgs={'V8.Execute':{pause:false,no_execution:false},'V8.External':{pause:false,no_execution:true},'V8.CompileFullCode':{pause:true,no_execution:true},'V8.RecompileSynchronous':{pause:true,no_execution:true},'V8.RecompileParallel':{pause:false,no_execution:false},'V8.CompileEval':{pause:true,no_execution:true},'V8.Parse':{pause:true,no_execution:true},'V8.PreParse':{pause:true,no_execution:true},'V8.ParseLazy':{pause:true,no_execution:true},'V8.GCScavenger':{pause:true,no_execution:true},'V8.GCCompactor':{pause:true,no_execution:true},'V8.GCContext':{pause:true,no_execution:true}};V8LogImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
+return false;return eventData.substring(0,11)=='v8-version,'||eventData.substring(0,12)=='timer-event,'||eventData.substring(0,5)=='tick,'||eventData.substring(0,15)=='shared-library,'||eventData.substring(0,9)=='profiler,'||eventData.substring(0,14)=='code-creation,';};V8LogImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'V8LogImporter';},processTimerEvent_:function(name,start,length){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;length/=1000;var colorId=ColorScheme.getColorIdForGeneralPurposeString(name);var slice=new tr.model.Slice('v8',name,colorId,start,args,length);this.v8_timer_thread_.sliceGroup.pushSlice(slice);},processTimerEventStart_:function(name,start){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;this.v8_timer_thread_.sliceGroup.beginSlice('v8',name,start,args);},processTimerEventEnd_:function(name,end){end/=1000;this.v8_timer_thread_.sliceGroup.endSlice(end);},processCodeCreateEvent_:function(type,kind,address,size,name){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(size,name);code_entry.kind=kind;this.code_map_.addCode(address,code_entry);},processCodeMoveEvent_:function(from,to){this.code_map_.moveCode(from,to);},processCodeDeleteEvent_:function(address){this.code_map_.deleteCode(address);},processSharedLibrary_:function(name,start,end){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(end-start,name);code_entry.kind=-3;for(var i=0;i<kV8BinarySuffixes.length;i++){var suffix=kV8BinarySuffixes[i];if(name.indexOf(suffix,name.length-suffix.length)>=0){code_entry.kind=-1;break;}}
+this.code_map_.addLibrary(start,code_entry);},findCodeKind_:function(kind){for(name in CodeKinds){if(CodeKinds[name].kinds.indexOf(kind)>=0){return CodeKinds[name];}}},processTickEvent_:function(pc,start,unused_x,unused_y,vmstate,stack){start/=1000;function findChildWithEntryID(stackFrame,entryID){for(var i=0;i<stackFrame.children.length;i++){if(stackFrame.children[i].entryID==entryID)
+return stackFrame.children[i];}
+return undefined;}
+var lastStackFrame;if(stack&&stack.length){lastStackFrame=this.root_stack_frame_;stack=stack.reverse();for(var i=0;i<stack.length;i++){if(!stack[i])
+break;var entry=this.code_map_.findEntry(stack[i]);var entryID=entry?entry.id:'Unknown';var childFrame=findChildWithEntryID(lastStackFrame,entryID);if(childFrame===undefined){var entryName=entry?entry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(lastStackFrame,'v8sf-'+tr.b.GUID.allocate(),entryName,ColorScheme.getColorIdForGeneralPurposeString(entryName));lastStackFrame.entryID=entryID;this.model_.addStackFrame(lastStackFrame);}else{lastStackFrame=childFrame;}}}else{var pcEntry=this.code_map_.findEntry(pc);var pcEntryID='v8pc-'+(pcEntry?pcEntry.id:'Unknown');if(this.model_.stackFrames[pcEntryID]===undefined){var pcEntryName=pcEntry?pcEntry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(undefined,pcEntryID,pcEntryName,ColorScheme.getColorIdForGeneralPurposeString(pcEntryName));this.model_.addStackFrame(lastStackFrame);}
+lastStackFrame=this.model_.stackFrames[pcEntryID];}
+var sample=new tr.model.Sample(undefined,this.v8_thread_,'V8 PC',start,lastStackFrame,1);this.model_.samples.push(sample);},processDistortion_:function(distortion_in_picoseconds){distortion_per_entry=distortion_in_picoseconds/1000000;},processPlotRange_:function(start,end){xrange_start_override=start;xrange_end_override=end;},processV8Version_:function(major,minor,build,patch,candidate){},importEvents:function(){var logreader=new tr.e.importer.v8.LogReader({'timer-event':{parsers:[null,parseInt,parseInt],processor:this.processTimerEvent_.bind(this)},'shared-library':{parsers:[null,parseInt,parseInt],processor:this.processSharedLibrary_.bind(this)},'timer-event-start':{parsers:[null,parseInt],processor:this.processTimerEventStart_.bind(this)},'timer-event-end':{parsers:[null,parseInt],processor:this.processTimerEventEnd_.bind(this)},'code-creation':{parsers:[null,parseInt,parseInt,parseInt,null],processor:this.processCodeCreateEvent_.bind(this)},'code-move':{parsers:[parseInt,parseInt],processor:this.processCodeMoveEvent_.bind(this)},'code-delete':{parsers:[parseInt],processor:this.processCodeDeleteEvent_.bind(this)},'tick':{parsers:[parseInt,parseInt,null,null,parseInt,'var-args'],processor:this.processTickEvent_.bind(this)},'distortion':{parsers:[parseInt],processor:this.processDistortion_.bind(this)},'plot-range':{parsers:[parseInt,parseInt],processor:this.processPlotRange_.bind(this)},'v8-version':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt],processor:this.processV8Version_.bind(this)}});this.v8_timer_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(1);this.v8_timer_thread_.name='V8 Timers';this.v8_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(2);this.v8_thread_.name='V8';var lines=this.logData_.split('\n');for(var i=0;i<lines.length;i++){logreader.processLogLine(lines[i]);}
+this.root_stack_frame_.removeAllChildren();function addSlices(slices,thread){for(var i=0;i<slices.length;i++){var duration=slices[i].end-slices[i].start;var slice=new tr.model.Slice('v8',slices[i].name,ColorScheme.getColorIdForGeneralPurposeString(slices[i].name),slices[i].start,{},duration);thread.sliceGroup.pushSlice(slice);addSlices(slices[i].children,thread);}}
+addSlices(this.v8_stack_timeline_,this.v8_thread_);}};tr.importer.Importer.register(V8LogImporter);return{V8LogImporter:V8LogImporter};});'use strict';tr.exportTo('tr.e.importer',function(){function ZipImporter(model,eventData){if(eventData instanceof ArrayBuffer)
+eventData=new Uint8Array(eventData);this.model_=model;this.eventData_=eventData;}
+ZipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
+header=new Uint8Array(eventData.slice(0,2));else if(typeof(eventData)==='string'||eventData instanceof String)
+header=[eventData.charCodeAt(0),eventData.charCodeAt(1)];else
+return false;return header[0]==='P'.charCodeAt(0)&&header[1]==='K'.charCodeAt(0);};ZipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'ZipImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){var zip=new JSZip(this.eventData_);var subtraces=[];for(var idx in zip.files)
+subtraces.push(zip.files[idx].asBinary());return subtraces;}};tr.importer.Importer.register(ZipImporter);return{ZipImporter:ZipImporter};});'use strict';tr.exportTo('tr.model.source_info',function(){function SourceInfo(file,opt_line,opt_column){this.file_=file;this.line_=opt_line||-1;this.column_=opt_column||-1;}
+SourceInfo.prototype={get file(){return this.file_;},get line(){return this.line_;},get column(){return this.column_;},get domain(){if(!this.file_)
+return undefined;var domain=this.file_.match(/(.*:\/\/[^:\/]*)/i);return domain?domain[1]:undefined;},toString:function(){var str='';if(this.file_)
+str+=this.file_;if(this.line_>0)
+str+=':'+this.line_;if(this.column_>0)
+str+=':'+this.column_;return str;}};return{SourceInfo:SourceInfo};});'use strict';tr.exportTo('tr.model.source_info',function(){function JSSourceInfo(file,line,column,isNative,scriptId,state){tr.model.source_info.SourceInfo.call(this,file,line,column);this.isNative_=isNative;this.scriptId_=scriptId;this.state_=state;}
+JSSourceInfo.prototype={__proto__:tr.model.source_info.SourceInfo.prototype,get state(){return this.state_;},get isNative(){return this.isNative_;},get scriptId(){return this.scriptId_;},toString:function(){var str=this.isNative_?'[native v8] ':'';return str+
+tr.model.source_info.SourceInfo.prototype.toString.call(this);}};return{JSSourceInfo:JSSourceInfo,JSSourceState:{COMPILED:'compiled',OPTIMIZABLE:'optimizable',OPTIMIZED:'optimized',UNKNOWN:'unknown'}};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeEntry(address,size,name,scriptId){this.id_=tr.b.GUID.allocate();this.address_=address;this.size_=size;var rePrefix=/^(\w*:)?([*~]?)(.*)$/m;var tokens=rePrefix.exec(name);var prefix=tokens[1];var state=tokens[2];var body=tokens[3];if(state==='*'){state=tr.model.source_info.JSSourceState.OPTIMIZED;}else if(state==='~'){state=tr.model.source_info.JSSourceState.OPTIMIZABLE;}else if(state===''){state=tr.model.source_info.JSSourceState.COMPILED;}else{console.warning('Unknown v8 code state '+state);state=tr.model.source_info.JSSourceState.UNKNOWN;}
+var rawName;var rawUrl;if(prefix==='Script:'){rawName='';rawUrl=body;}else{var spacePos=body.lastIndexOf(' ');rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):'';}
+function splitLineAndColumn(url){var lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;var lineColumnMatch=lineColumnRegEx.exec(url);var lineNumber;var columnNumber;if(typeof(lineColumnMatch[1])==='string'){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
+if(typeof(lineColumnMatch[2])==='string'){columnNumber=parseInt(lineColumnMatch[2],10);columnNumber=isNaN(columnNumber)?undefined:columnNumber-1;}
+return{url:url.substring(0,url.length-lineColumnMatch[0].length),lineNumber:lineNumber,columnNumber:columnNumber};}
+var nativeSuffix=' native';var isNative=rawName.endsWith(nativeSuffix);this.name_=isNative?rawName.slice(0,-nativeSuffix.length):rawName;var urlData=splitLineAndColumn(rawUrl);var url=urlData.url||'';var line=urlData.lineNumber||0;var column=urlData.columnNumber||0;this.sourceInfo_=new tr.model.source_info.JSSourceInfo(url,line,column,isNative,scriptId,state);};TraceCodeEntry.prototype={get id(){return this.id_;},get sourceInfo(){return this.sourceInfo_;},get name(){return this.name_;},set address(address){this.address_=address;},get address(){return this.address_;},set size(size){this.size_=size;},get size(){return this.size_;}};return{TraceCodeEntry:TraceCodeEntry};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeMap(){this.banks_=new Map();}
+TraceCodeMap.prototype={addEntry:function(addressHex,size,name,scriptId){var entry=new tr.e.importer.TraceCodeEntry(this.getAddress_(addressHex),size,name,scriptId);this.addEntry_(addressHex,entry);},moveEntry:function(oldAddressHex,newAddressHex,size){var entry=this.getBank_(oldAddressHex).removeEntry(this.getAddress_(oldAddressHex));if(!entry)
+return;entry.address=this.getAddress_(newAddressHex);entry.size=size;this.addEntry_(newAddressHex,entry);},lookupEntry:function(addressHex){return this.getBank_(addressHex).lookupEntry(this.getAddress_(addressHex));},addEntry_:function(addressHex,entry){this.getBank_(addressHex).addEntry(entry);},getAddress_:function(addressHex){var bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);},getBank_:function(addressHex){addressHex=addressHex.slice(2);var bankSizeHexDigits=13;var maxHexDigits=16;var bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);var bank=this.banks_.get(bankName);if(!bank){bank=new TraceCodeBank();this.banks_.set(bankName,bank);}
+return bank;}};function TraceCodeBank(){this.entries_=[];}
+TraceCodeBank.prototype={removeEntry:function(address){if(this.entries_.length===0)
+return undefined;var index=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},address);var entry=this.entries_[index];if(!entry||entry.address!==address)
+return undefined;this.entries_.splice(index,1);return entry;},lookupEntry:function(address){var index=tr.b.findHighIndexInSortedArray(this.entries_,function(e){return address-e.address;})-1;var entry=this.entries_[index];return entry&&address<entry.address+entry.size?entry:undefined;},addEntry:function(newEntry){if(this.entries_.length===0)
+this.entries_.push(newEntry);var endAddress=newEntry.address+newEntry.size;var lastIndex=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},endAddress);var index;for(index=lastIndex-1;index>=0;--index){var entry=this.entries_[index];var entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address)
+break;}
+++index;this.entries_.splice(index,lastIndex-index,newEntry);}};return{TraceCodeMap:TraceCodeMap};});'use strict';tr.exportTo('tr.model',function(){function ClockSyncRecord(syncId,start,args){this.syncId_=syncId;this.start_=start;this.args_=args;};ClockSyncRecord.prototype={get syncId(){return this.syncId_;},get start(){return this.start_;},set start(value){this.start_=value;},get args(){return this.args_;}};function InstantClockSyncRecord(syncId,start,args){ClockSyncRecord.call(this,syncId,start,args);};InstantClockSyncRecord.prototype={__proto__:ClockSyncRecord.prototype};function PingPongClockSyncRecord(syncId,start,duration,args){ClockSyncRecord.call(this,syncId,start,args);this.duration_=duration;};PingPongClockSyncRecord.prototype={__proto__:ClockSyncRecord.prototype,get duration(){return this.duration_;},set duration(value){this.duration_=value;},};return{InstantClockSyncRecord:InstantClockSyncRecord,PingPongClockSyncRecord:PingPongClockSyncRecord};});'use strict';tr.exportTo('tr.model',function(){function YComponent(stableId,yPercentOffset){this.stableId=stableId;this.yPercentOffset=yPercentOffset;}
+YComponent.prototype={toDict:function(){return{stableId:this.stableId,yPercentOffset:this.yPercentOffset};}};function Location(xWorld,yComponents){this.xWorld_=xWorld;this.yComponents_=yComponents;};Location.fromViewCoordinates=function(viewport,viewX,viewY){var dt=viewport.currentDisplayTransform;var xWorld=dt.xViewToWorld(viewX);var yComponents=[];var elem=document.elementFromPoint(viewX+viewport.modelTrackContainer.canvas.offsetLeft,viewY+viewport.modelTrackContainer.canvas.offsetTop);while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(viewY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+elem=elem.parentElement;}
+if(yComponents.length==0)
+return;return new Location(xWorld,yComponents);}
+Location.fromStableIdAndTimestamp=function(viewport,stableId,ts){var xWorld=ts;var yComponents=[];var containerToTrack=viewport.containerToTrackMap;var elem=containerToTrack.getTrackByStableId(stableId);if(!elem)
+return;var firstY=elem.getBoundingClientRect().top;while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(firstY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+elem=elem.parentElement;}
+if(yComponents.length==0)
+return;return new Location(xWorld,yComponents);}
+Location.prototype={get xWorld(){return this.xWorld_;},getContainingTrack:function(viewport){var containerToTrack=viewport.containerToTrackMap;for(var i in this.yComponents_){var yComponent=this.yComponents_[i];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined)
+return track;}},toViewCoordinates:function(viewport){var dt=viewport.currentDisplayTransform;var containerToTrack=viewport.containerToTrackMap;var viewX=dt.xWorldToView(this.xWorld_);var viewY=-1;for(var index in this.yComponents_){var yComponent=this.yComponents_[index];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined){var boundRect=track.getBoundingClientRect();viewY=yComponent.yPercentOffset*boundRect.height+boundRect.top;break;}}
+return{viewX:viewX,viewY:viewY};},toDict:function(){return{xWorld:this.xWorld_,yComponents:this.yComponents_};}};return{Location:Location};});'use strict';tr.exportTo('tr.model',function(){function Annotation(){this.guid_=tr.b.GUID.allocate();this.view_=undefined;};Annotation.fromDictIfPossible=function(args){if(args.typeName===undefined)
+throw new Error('Missing typeName argument');var typeInfo=Annotation.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.typeName===args.typeName;});if(typeInfo===undefined)
+return undefined;return typeInfo.constructor.fromDict(args);};Annotation.fromDict=function(){throw new Error('Not implemented');}
+Annotation.prototype={get guid(){return this.guid_;},onRemove:function(){},toDict:function(){throw new Error('Not implemented');},getOrCreateView:function(viewport){if(!this.view_)
+this.view_=this.createView_(viewport);return this.view_;},createView_:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Annotation,options);Annotation.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict'))
+throw new Error('Must have fromDict method');if(!e.typeInfo.metadata.typeName)
+throw new Error('Registered Annotations must provide typeName');});return{Annotation:Annotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function AnnotationView(viewport,annotation){}
+AnnotationView.prototype={draw:function(ctx){throw new Error('Not implemented');}};return{AnnotationView:AnnotationView};});'use strict';tr.exportTo('tr.ui.annotations',function(){function RectAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+RectAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var startCoords=this.annotation_.startLocation.toViewCoordinates(this.viewport_);var endCoords=this.annotation_.endLocation.toViewCoordinates(this.viewport_);var startY=startCoords.viewY-ctx.canvas.getBoundingClientRect().top;var sizeY=endCoords.viewY-startCoords.viewY;if(startY+sizeY<0){startY=sizeY;}else if(startY<0){startY=0;}
+ctx.fillStyle=this.annotation_.fillStyle;ctx.fillRect(startCoords.viewX,startY,endCoords.viewX-startCoords.viewX,sizeY);}};return{RectAnnotationView:RectAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function RectAnnotation(start,end){tr.model.Annotation.apply(this,arguments);this.startLocation_=start;this.endLocation_=end;this.fillStyle='rgba(255, 180, 0, 0.3)';}
+RectAnnotation.fromDict=function(dict){var args=dict.args;var startLoc=new tr.model.Location(args.start.xWorld,args.start.yComponents);var endLoc=new tr.model.Location(args.end.xWorld,args.end.yComponents);return new tr.model.RectAnnotation(startLoc,endLoc);}
+RectAnnotation.prototype={__proto__:tr.model.Annotation.prototype,get startLocation(){return this.startLocation_;},get endLocation(){return this.endLocation_;},toDict:function(){return{typeName:'rect',args:{start:this.startLocation.toDict(),end:this.endLocation.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.RectAnnotationView(viewport,this);}};tr.model.Annotation.register(RectAnnotation,{typeName:'rect'});return{RectAnnotation:RectAnnotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function CommentBoxAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;this.textArea_=undefined;this.styleWidth=250;this.styleHeight=50;this.fontSize=10;this.rightOffset=50;this.topOffset=25;}
+CommentBoxAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,removeTextArea:function(){this.textArea_.parentNode.removeChild(this.textArea_);},draw:function(ctx){var coords=this.annotation_.location.toViewCoordinates(this.viewport_);if(coords.viewX<0){if(this.textArea_)
+this.textArea_.style.visibility='hidden';return;}
+if(!this.textArea_){this.textArea_=document.createElement('textarea');this.textArea_.style.position='absolute';this.textArea_.readOnly=true;this.textArea_.value=this.annotation_.text;this.textArea_.style.zIndex=1;ctx.canvas.parentNode.appendChild(this.textArea_);}
+this.textArea_.style.width=this.styleWidth+'px';this.textArea_.style.height=this.styleHeight+'px';this.textArea_.style.fontSize=this.fontSize+'px';this.textArea_.style.visibility='visible';this.textArea_.style.left=coords.viewX+ctx.canvas.getBoundingClientRect().left+
+this.rightOffset+'px';this.textArea_.style.top=coords.viewY-ctx.canvas.getBoundingClientRect().top-
+this.topOffset+'px';ctx.strokeStyle='rgb(0, 0, 0)';ctx.lineWidth=2;ctx.beginPath();tr.ui.b.drawLine(ctx,coords.viewX,coords.viewY-ctx.canvas.getBoundingClientRect().top,coords.viewX+this.rightOffset,coords.viewY-this.topOffset-
+ctx.canvas.getBoundingClientRect().top);ctx.stroke();}};return{CommentBoxAnnotationView:CommentBoxAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function CommentBoxAnnotation(location,text){tr.model.Annotation.apply(this,arguments);this.location=location;this.text=text;}
+CommentBoxAnnotation.fromDict=function(dict){var args=dict.args;var location=new tr.model.Location(args.location.xWorld,args.location.yComponents);return new tr.model.CommentBoxAnnotation(location,args.text);};CommentBoxAnnotation.prototype={__proto__:tr.model.Annotation.prototype,onRemove:function(){this.view_.removeTextArea();},toDict:function(){return{typeName:'comment_box',args:{text:this.text,location:this.location.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.CommentBoxAnnotationView(viewport,this);}};tr.model.Annotation.register(CommentBoxAnnotation,{typeName:'comment_box'});return{CommentBoxAnnotation:CommentBoxAnnotation};});'use strict';tr.exportTo('tr.model',function(){function HeapEntry(heapDump,leafStackFrame,objectTypeName,size){this.heapDump=heapDump;this.leafStackFrame=leafStackFrame;this.objectTypeName=objectTypeName;this.size=size;}
+function HeapDump(processMemoryDump,allocatorName){this.processMemoryDump=processMemoryDump;this.allocatorName=allocatorName;this.entries=[];}
+HeapDump.prototype={addEntry:function(leafStackFrame,objectTypeName,size){var entry=new HeapEntry(this,leafStackFrame,objectTypeName,size);this.entries.push(entry);return entry;}};return{HeapEntry:HeapEntry,HeapDump:HeapDump};});'use strict';tr.exportTo('tr.model',function(){function ScopedId(scope,id){if(scope===undefined){throw new Error('Scope should be defined. Use \''+
+tr.model.OBJECT_DEFAULT_SCOPE+'\' as the default scope.');}
+this.scope=scope;this.id=id;}
+ScopedId.prototype={toString:function(){return'{scope: '+this.scope+', id: '+this.id+'}';}};return{ScopedId:ScopedId};});'use strict';tr.exportTo('tr.ui.annotations',function(){function XMarkerAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+XMarkerAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var viewX=dt.xWorldToView(this.annotation_.timestamp);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,ctx.canvas.height);ctx.strokeStyle=this.annotation_.strokeStyle;ctx.stroke();}};return{XMarkerAnnotationView:XMarkerAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function XMarkerAnnotation(timestamp){tr.model.Annotation.apply(this,arguments);this.timestamp=timestamp;this.strokeStyle='rgba(0, 0, 255, 0.5)';}
+XMarkerAnnotation.fromDict=function(dict){return new XMarkerAnnotation(dict.args.timestamp);}
+XMarkerAnnotation.prototype={__proto__:tr.model.Annotation.prototype,toDict:function(){return{typeName:'xmarker',args:{timestamp:this.timestamp}};},createView_:function(viewport){return new tr.ui.annotations.XMarkerAnnotationView(viewport,this);}};tr.model.Annotation.register(XMarkerAnnotation,{typeName:'xmarker'});return{XMarkerAnnotation:XMarkerAnnotation};});'use strict';tr.exportTo('tr.e.importer',function(){var Base64=tr.b.Base64;var deepCopy=tr.b.deepCopy;var ColorScheme=tr.b.ColorScheme;function getEventColor(event,opt_customName){if(event.cname)
+return ColorScheme.getColorIdForReservedName(event.cname);else if(opt_customName||event.name){return ColorScheme.getColorIdForGeneralPurposeString(opt_customName||event.name);}}
+var timestampFromUs=tr.v.Unit.timestampFromUs;var maybeTimestampFromUs=tr.v.Unit.maybeTimestampFromUs;var PRODUCER='producer';var CONSUMER='consumer';var STEP='step';var LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;var DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;var MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER=[undefined,LIGHT,DETAILED];var GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX='global/';var BYTE_STAT_NAME_MAP={'pc':'privateCleanResident','pd':'privateDirtyResident','sc':'sharedCleanResident','sd':'sharedDirtyResident','pss':'proportionalResident','sw':'swapped'};var WEAK_MEMORY_ALLOCATOR_DUMP_FLAG=1<<0;var OBJECT_TYPE_NAME_PATTERNS=[{prefix:'const char *WTF::getStringWithTypeName() [T = ',suffix:']'},{prefix:'const char* WTF::getStringWithTypeName() [with T = ',suffix:']'},{prefix:'const char *__cdecl WTF::getStringWithTypeName<',suffix:'>(void)'}];function TraceEventImporter(model,eventData){this.importPriority=1;this.model_=model;this.events_=undefined;this.sampleEvents_=undefined;this.stackFrameEvents_=undefined;this.systemTraceEvents_=undefined;this.battorData_=undefined;this.eventsWereFromString_=false;this.softwareMeasuredCpuCount_=undefined;this.allAsyncEvents_=[];this.allFlowEvents_=[];this.allObjectEvents_=[];this.traceEventSampleStackFramesByName_={};this.v8ProcessCodeMaps_={};this.v8ProcessRootStackFrame_={};this.v8SamplingData_=[];this.allMemoryDumpEvents_={};this.objectTypeNameMap_={};this.clockDomainId_=tr.model.ClockDomainId.TRACE_EVENT_IMPORTER;if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();if(eventData[0]==='['){eventData=eventData.replace(/\s*,\s*$/,'');if(eventData[eventData.length-1]!==']')
+eventData=eventData+']';}
+this.events_=JSON.parse(eventData);this.eventsWereFromString_=true;}else{this.events_=eventData;}
+this.traceAnnotations_=this.events_.traceAnnotations;if(this.events_.traceEvents){var container=this.events_;this.events_=this.events_.traceEvents;this.systemTraceEvents_=container.systemTraceEvents;this.battorData_=container.powerTraceAsString;this.sampleEvents_=container.samples;this.stackFrameEvents_=container.stackFrames;if(container.displayTimeUnit){var unitName=container.displayTimeUnit;var unit=tr.v.TimeDisplayModes[unitName];if(unit===undefined){throw new Error('Unit '+unitName+' is not supported.');}
+this.model_.intrinsicTimeUnit=unit;}
+var knownFieldNames={powerTraceAsString:true,samples:true,stackFrames:true,systemTraceEvents:true,traceAnnotations:true,traceEvents:true};for(var fieldName in container){if(fieldName in knownFieldNames)
+continue;this.model_.metadata.push({name:fieldName,value:container[fieldName]});if(fieldName==='metadata'){var metadata=container[fieldName];if(metadata['highres-ticks'])
+this.model_.isTimeHighResolution=metadata['highres-ticks'];if(metadata['clock-domain'])
+this.clockDomainId_=metadata['clock-domain'];}}}}
+TraceEventImporter.canImport=function(eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();return eventData[0]==='{'||eventData[0]==='[';}
+if(eventData instanceof Array&&eventData.length&&eventData[0].ph)
+return true;if(eventData.traceEvents){if(eventData.traceEvents instanceof Array){if(eventData.traceEvents.length&&eventData.traceEvents[0].ph)
+return true;if(eventData.samples.length&&eventData.stackFrames!==undefined)
+return true;}}
+return false;};TraceEventImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'TraceEventImporter';},extractSubtraces:function(){var systemEventsTmp=this.systemTraceEvents_;var battorDataTmp=this.battorData_;this.systemTraceEvents_=undefined;this.battorData_=undefined;var subTraces=systemEventsTmp?[systemEventsTmp]:[];if(battorDataTmp)
+subTraces.push(battorDataTmp);return subTraces;},deepCopyIfNeeded_:function(obj){if(obj===undefined)
+obj={};if(this.eventsWereFromString_)
+return obj;return deepCopy(obj);},deepCopyAlways_:function(obj){if(obj===undefined)
+obj={};return deepCopy(obj);},processAsyncEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allAsyncEvents_.push({sequenceNumber:this.allAsyncEvents_.length,event:event,thread:thread});},processFlowEvent:function(event,opt_slice){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allFlowEvents_.push({refGuid:tr.b.GUID.getLastGuid(),sequenceNumber:this.allFlowEvents_.length,event:event,slice:opt_slice,thread:thread});},processCounterEvent:function(event){var ctr_name;if(event.id!==undefined)
+ctr_name=event.name+'['+event.id+']';else
+ctr_name=event.name;var ctr=this.model_.getOrCreateProcess(event.pid).getOrCreateCounter(event.cat,ctr_name);var reservedColorId=event.cname?getEventColor(event):undefined;if(ctr.numSeries===0){for(var seriesName in event.args){var colorId=reservedColorId||getEventColor(event,ctr.name+'.'+seriesName);ctr.addSeries(new tr.model.CounterSeries(seriesName,colorId));}
+if(ctr.numSeries===0){this.model_.importWarning({type:'counter_parse_error',message:'Expected counter '+event.name+' to have at least one argument to use as a value.'});delete ctr.parent.counters[ctr.name];return;}}
+var ts=timestampFromUs(event.ts);ctr.series.forEach(function(series){var val=event.args[series.name]?event.args[series.name]:0;series.addCounterSample(ts,val);});},processObjectEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allObjectEvents_.push({sequenceNumber:this.allObjectEvents_.length,event:event,thread:thread});},processDurationEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var ts=timestampFromUs(event.ts);if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'duration_parse_error',message:'Timestamps are moving backward.'});return;}
+if(event.ph==='B'){var slice=thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));slice.startStackFrame=this.getStackFrameForEvent_(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){if(event.s!==undefined&&event.s!=='t')
+throw new Error('This should never happen');thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts));slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=undefined;}else{if(!thread.sliceGroup.openSliceCount){this.model_.importWarning({type:'duration_parse_error',message:'E phase event without a matching B phase event.'});return;}
+var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts),getEventColor(event));if(event.name&&slice.title!=event.name){this.model_.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+slice.title+' in openSlice, and is '+
+event.name+' in endSlice'});}
+slice.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(slice.args,event.args,slice.title);}},mergeArgsInto_:function(dstArgs,srcArgs,eventName){for(var arg in srcArgs){if(dstArgs[arg]!==undefined){this.model_.importWarning({type:'arg_merge_error',message:'Different phases of '+eventName+' provided values for argument '+arg+'.'+' The last provided value will be used.'});}
+dstArgs[arg]=this.deepCopyIfNeeded_(srcArgs[arg]);}},processCompleteEvent:function(event){if(event.cat!==undefined&&event.cat.indexOf('trace_event_overhead')>-1)
+return undefined;var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(event.flow_out){if(event.flow_in)
+event.flowPhase=STEP;else
+event.flowPhase=PRODUCER;}else if(event.flow_in){event.flowPhase=CONSUMER;}
+var slice=thread.sliceGroup.pushCompleteSlice(event.cat,event.name,timestampFromUs(event.ts),maybeTimestampFromUs(event.dur),maybeTimestampFromUs(event.tts),maybeTimestampFromUs(event.tdur),this.deepCopyIfNeeded_(event.args),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=this.getStackFrameForEvent_(event,true);return slice;},processJitCodeEvent:function(event){if(this.v8ProcessCodeMaps_[event.pid]===undefined)
+this.v8ProcessCodeMaps_[event.pid]=new tr.e.importer.TraceCodeMap();var map=this.v8ProcessCodeMaps_[event.pid];var data=event.args.data;if(event.name==='JitCodeMoved')
+map.moveEntry(data.code_start,data.new_code_start,data.code_len);else
+map.addEntry(data.code_start,data.code_len,data.name,data.script_id);},processMetadataEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
+if(event.argsStripped)
+return;if(event.name==='process_name'){var process=this.model_.getOrCreateProcess(event.pid);process.name=event.args.name;}else if(event.name==='process_labels'){var process=this.model_.getOrCreateProcess(event.pid);var labels=event.args.labels.split(',');for(var i=0;i<labels.length;i++)
+process.addLabelIfNeeded(labels[i]);}else if(event.name==='process_sort_index'){var process=this.model_.getOrCreateProcess(event.pid);process.sortIndex=event.args.sort_index;}else if(event.name==='thread_name'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.args.name;}else if(event.name==='thread_sort_index'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.args.sort_index;}else if(event.name==='num_cpus'){var n=event.args.number;if(this.softwareMeasuredCpuCount_!==undefined)
+n=Math.max(n,this.softwareMeasuredCpuCount_);this.softwareMeasuredCpuCount_=n;}else if(event.name==='stackFrames'){var stackFrames=event.args.stackFrames;if(stackFrames===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No stack frames found in a \''+event.name+'\' metadata event'});}else{this.importStackFrames_(stackFrames,'p'+event.pid+':');}}else if(event.name==='typeNames'){var objectTypeNameMap=event.args.typeNames;if(objectTypeNameMap===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No mapping from object type IDs to names found in a \''+
+event.name+'\' metadata event'});}else{this.importObjectTypeNameMap_(objectTypeNameMap,event.pid);}}else{this.model_.importWarning({type:'metadata_parse_error',message:'Unrecognized metadata name: '+event.name});}},processInstantEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
+if(event.s==='t'||event.s===undefined){this.processDurationEvent(event);return;}
+var constructor;switch(event.s){case'g':constructor=tr.model.GlobalInstantEvent;break;case'p':constructor=tr.model.ProcessInstantEvent;break;default:this.model_.importWarning({type:'instant_parse_error',message:'I phase event with unknown "s" field value.'});return;}
+var instantEvent=new constructor(event.cat,event.name,getEventColor(event),timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args));switch(instantEvent.type){case tr.model.InstantEventType.GLOBAL:this.model_.instantEvents.push(instantEvent);break;case tr.model.InstantEventType.PROCESS:var process=this.model_.getOrCreateProcess(event.pid);process.instantEvents.push(instantEvent);break;default:throw new Error('Unknown instant event type: '+event.s);}},processV8Sample:function(event){var data=event.args.data;if(data.vm_state==='js'&&!data.stack.length)
+return;var rootStackFrame=this.v8ProcessRootStackFrame_[event.pid];if(!rootStackFrame){rootStackFrame=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8ProcessRootStackFrame_[event.pid]=rootStackFrame;}
+function findChildWithEntryID(stackFrame,entryID){return tr.b.findFirstInArray(stackFrame.children,function(child){return child.entryID===entryID;});}
+var model=this.model_;function addStackFrame(lastStackFrame,entry){var childFrame=findChildWithEntryID(lastStackFrame,entry.id);if(childFrame)
+return childFrame;var frame=new tr.model.StackFrame(lastStackFrame,tr.b.GUID.allocate(),entry.name,ColorScheme.getColorIdForGeneralPurposeString(entry.name),entry.sourceInfo);frame.entryID=entry.id;model.addStackFrame(frame);return frame;}
+var lastStackFrame=rootStackFrame;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){var map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();for(var i=0;i<data.stack.length;i++){var entry=map.lookupEntry(data.stack[i]);if(entry===undefined){entry={id:'unknown',name:'unknown',sourceInfo:undefined};}
+lastStackFrame=addStackFrame(lastStackFrame,entry);}}else{var entry={id:data.vm_state,name:data.vm_state,sourceInfo:undefined};lastStackFrame=addStackFrame(lastStackFrame,entry);}
+var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'V8 Sample',timestampFromUs(event.ts),lastStackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},processTraceSampleEvent:function(event){if(event.name==='V8Sample'){this.v8SamplingData_.push(event);return;}
+var stackFrame=this.getStackFrameForEvent_(event);if(stackFrame===undefined){stackFrame=this.traceEventSampleStackFramesByName_[event.name];}
+if(stackFrame===undefined){var id='te-'+tr.b.GUID.allocate();stackFrame=new tr.model.StackFrame(undefined,id,event.name,ColorScheme.getColorIdForGeneralPurposeString(event.name));this.model_.addStackFrame(stackFrame);this.traceEventSampleStackFramesByName_[event.name]=stackFrame;}
+var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'Trace Event Sample',timestampFromUs(event.ts),stackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},processMemoryDumpEvent:function(event){if(event.ph!=='v')
+throw new Error('Invalid memory dump event phase "'+event.ph+'".');var dumpId=event.id;if(dumpId===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase \''+event.ph+'\') without a dump ID.'});return;}
+var pid=event.pid;if(pid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase\''+event.ph+'\', dump ID \''+
+dumpId+'\') without a PID.'});return;}
+var allEvents=this.allMemoryDumpEvents_;var dumpIdEvents=allEvents[dumpId];if(dumpIdEvents===undefined)
+allEvents[dumpId]=dumpIdEvents={};var processEvents=dumpIdEvents[pid];if(processEvents===undefined)
+dumpIdEvents[pid]=processEvents=[];processEvents.push(event);},processClockSyncEvent:function(event){if(event.ph!=='c')
+throw new Error('Invalid clock sync event phase "'+event.ph+'".');var syncId=event.args.sync_id;var issueStartTs=event.args.issue_ts;var issueEndTs=event.ts;if(syncId===undefined){this.model_.importWarning({type:'clock_sync_parse_error',message:'Clock sync at time '+issueEndTs+' without an ID.'});return;}
+if(issueStartTs===undefined){this.model_.importWarning({type:'clock_sync_parse_error',message:'Clock sync at time '+issueEndTs+' with ID '+syncId+' without a start timestamp.'});return;}
+this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,timestampFromUs(issueStartTs),timestampFromUs(issueEndTs-issueStartTs));this.model_.clockSyncRecords.push(new tr.model.PingPongClockSyncRecord(syncId,timestampFromUs(issueStartTs),timestampFromUs(issueEndTs-issueStartTs)));},processV8Events:function(){this.v8SamplingData_.sort(function(a,b){if(a.ts!==b.ts)
+return a.ts-b.ts;if(a.ph==='M'||a.ph==='I')
+return-1;else if(b.ph==='M'||b.ph==='I')
+return 1;return 0;});var length=this.v8SamplingData_.length;for(var i=0;i<length;++i){var event=this.v8SamplingData_[i];if(event.ph==='M'||event.ph==='I'){this.processJitCodeEvent(event);}else if(event.ph==='P'){this.processV8Sample(event);}}},importClockSyncMarkers:function(){this.model_.clockSyncRecords.push(new tr.model.InstantClockSyncRecord('ftrace_importer',0,{}));for(var i=0;i<this.events_.length;i++){var event=this.events_[i];if(event.ph!=='c')
+continue;var eventSizeInBytes=this.model_.importOptions.trackDetailedModelStats?JSON.stringify(event).length:undefined;this.model_.stats.willProcessBasicTraceEvent('clock_sync',event.cat,event.name,event.ts,eventSizeInBytes);this.processClockSyncEvent(event);}},importEvents:function(){if(this.stackFrameEvents_)
+this.importStackFrames_(this.stackFrameEvents_,'g');if(this.traceAnnotations_)
+this.importAnnotations_();var importOptions=this.model_.importOptions;var trackDetailedModelStats=importOptions.trackDetailedModelStats;var modelStats=this.model_.stats;var events=this.events_;for(var eI=0;eI<events.length;eI++){var event=events[eI];if(event.args==='__stripped__'){event.argsStripped=true;event.args=undefined;}
+var eventSizeInBytes;if(trackDetailedModelStats)
+eventSizeInBytes=JSON.stringify(event).length;else
+eventSizeInBytes=undefined;if(event.ph==='B'||event.ph==='E'){modelStats.willProcessBasicTraceEvent('begin_end (non-compact)',event.cat,event.name,event.ts,eventSizeInBytes);this.processDurationEvent(event);}else if(event.ph==='X'){modelStats.willProcessBasicTraceEvent('begin_end (compact)',event.cat,event.name,event.ts,eventSizeInBytes);var slice=this.processCompleteEvent(event);if(slice!==undefined&&event.bind_id!==undefined)
+this.processFlowEvent(event,slice);}else if(event.ph==='b'||event.ph==='e'||event.ph==='n'||event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){modelStats.willProcessBasicTraceEvent('async',event.cat,event.name,event.ts,eventSizeInBytes);this.processAsyncEvent(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){modelStats.willProcessBasicTraceEvent('instant',event.cat,event.name,event.ts,eventSizeInBytes);this.processInstantEvent(event);}else if(event.ph==='P'){modelStats.willProcessBasicTraceEvent('samples',event.cat,event.name,event.ts,eventSizeInBytes);this.processTraceSampleEvent(event);}else if(event.ph==='C'){modelStats.willProcessBasicTraceEvent('counters',event.cat,event.name,event.ts,eventSizeInBytes);this.processCounterEvent(event);}else if(event.ph==='M'){modelStats.willProcessBasicTraceEvent('metadata',event.cat,event.name,event.ts,eventSizeInBytes);this.processMetadataEvent(event);}else if(event.ph==='N'||event.ph==='D'||event.ph==='O'){modelStats.willProcessBasicTraceEvent('objects',event.cat,event.name,event.ts,eventSizeInBytes);this.processObjectEvent(event);}else if(event.ph==='s'||event.ph==='t'||event.ph==='f'){modelStats.willProcessBasicTraceEvent('flows',event.cat,event.name,event.ts,eventSizeInBytes);this.processFlowEvent(event);}else if(event.ph==='v'){modelStats.willProcessBasicTraceEvent('memory_dumps',event.cat,event.name,event.ts,eventSizeInBytes);this.processMemoryDumpEvent(event);}else if(event.ph==='c'){}else{modelStats.willProcessBasicTraceEvent('unknown',event.cat,event.name,event.ts,eventSizeInBytes);this.model_.importWarning({type:'parse_error',message:'Unrecognized event phase: '+
+event.ph+' ('+event.name+')'});}}
+this.processV8Events();tr.b.iterItems(this.v8ProcessRootStackFrame_,function(name,frame){frame.removeAllChildren();});},importStackFrames_:function(rawStackFrames,idPrefix){var model=this.model_;for(var id in rawStackFrames){var rawStackFrame=rawStackFrames[id];var fullId=idPrefix+id;var textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;var stackFrame=new tr.model.StackFrame(undefined,fullId,rawStackFrame.name,ColorScheme.getColorIdForGeneralPurposeString(textForColor));model.addStackFrame(stackFrame);}
+for(var id in rawStackFrames){var fullId=idPrefix+id;var stackFrame=model.stackFrames[fullId];if(stackFrame===undefined)
+throw new Error('Internal error');var rawStackFrame=rawStackFrames[id];var parentId=rawStackFrame.parent;var parentStackFrame;if(parentId===undefined){parentStackFrame=undefined;}else{var parentFullId=idPrefix+parentId;parentStackFrame=model.stackFrames[parentFullId];if(parentStackFrame===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentFullId+' for stack frame \''+stackFrame.name+'\' (ID '+fullId+').'});}}
+stackFrame.parentFrame=parentStackFrame;}},importObjectTypeNameMap_:function(rawObjectTypeNameMap,pid){if(pid in this.objectTypeNameMap_){this.model_.importWarning({type:'metadata_parse_error',message:'Mapping from object type IDs to names provided for pid='+
+pid+' multiple times.'});return;}
+var objectTypeNamePrefix=undefined;var objectTypeNameSuffix=undefined;var objectTypeNameMap={};for(var objectTypeId in rawObjectTypeNameMap){var rawObjectTypeName=rawObjectTypeNameMap[objectTypeId];if(objectTypeNamePrefix===undefined){for(var i=0;i<OBJECT_TYPE_NAME_PATTERNS.length;i++){var pattern=OBJECT_TYPE_NAME_PATTERNS[i];if(rawObjectTypeName.startsWith(pattern.prefix)&&rawObjectTypeName.endsWith(pattern.suffix)){objectTypeNamePrefix=pattern.prefix;objectTypeNameSuffix=pattern.suffix;break;}}}
+if(objectTypeNamePrefix!==undefined&&rawObjectTypeName.startsWith(objectTypeNamePrefix)&&rawObjectTypeName.endsWith(objectTypeNameSuffix)){objectTypeNameMap[objectTypeId]=rawObjectTypeName.substring(objectTypeNamePrefix.length,rawObjectTypeName.length-objectTypeNameSuffix.length);}else{objectTypeNameMap[objectTypeId]=rawObjectTypeName;}}
+this.objectTypeNameMap_[pid]=objectTypeNameMap;},importAnnotations_:function(){for(var id in this.traceAnnotations_){var annotation=tr.model.Annotation.fromDictIfPossible(this.traceAnnotations_[id]);if(!annotation){this.model_.importWarning({type:'annotation_warning',message:'Unrecognized traceAnnotation typeName \"'+
+this.traceAnnotations_[id].typeName+'\"'});continue;}
+this.model_.addAnnotation(annotation);}},finalizeImport:function(){if(this.softwareMeasuredCpuCount_!==undefined){this.model_.kernel.softwareMeasuredCpuCount=this.softwareMeasuredCpuCount_;}
+this.createAsyncSlices_();this.createFlowSlices_();this.createExplicitObjects_();this.createImplicitObjects_();this.createMemoryDumps_();},getStackFrameForEvent_:function(event,opt_lookForEndEvent){var sf;var stack;if(opt_lookForEndEvent){sf=event.esf;stack=event.estack;}else{sf=event.sf;stack=event.stack;}
+if(stack!==undefined&&sf!==undefined){this.model_.importWarning({type:'stack_frame_and_stack_error',message:'Event at '+event.ts+' cannot have both a stack and a stackframe.'});return undefined;}
+if(stack!==undefined)
+return this.model_.resolveStackToStackFrame_(event.pid,stack);if(sf===undefined)
+return undefined;var stackFrame=this.model_.stackFrames['g'+sf];if(stackFrame===undefined){this.model_.importWarning({type:'sample_import_error',message:'No frame for '+sf});return;}
+return stackFrame;},resolveStackToStackFrame_:function(pid,stack){return undefined;},importSampleData:function(){if(!this.sampleEvents_)
+return;var m=this.model_;var events=this.sampleEvents_;if(this.events_.length===0){for(var i=0;i<events.length;i++){var event=events[i];m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);}}
+var threadsByTid={};m.getAllThreads().forEach(function(t){threadsByTid[t.tid]=t;});for(var i=0;i<events.length;i++){var event=events[i];var thread=threadsByTid[event.tid];if(thread===undefined){m.importWarning({type:'sample_import_error',message:'Thread '+events.tid+'not found'});continue;}
+var cpu;if(event.cpu!==undefined)
+cpu=m.kernel.getOrCreateCpu(event.cpu);var stackFrame=this.getStackFrameForEvent_(event);var sample=new tr.model.Sample(cpu,thread,event.name,timestampFromUs(event.ts),stackFrame,event.weight);m.samples.push(sample);}},createAsyncSlices_:function(){if(this.allAsyncEvents_.length===0)
+return;this.allAsyncEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!==0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var legacyEvents=[];var nestableAsyncEventsByKey={};var nestableMeasureAsyncEventsByKey={};for(var i=0;i<this.allAsyncEvents_.length;i++){var asyncEventState=this.allAsyncEvents_[i];var event=asyncEventState.event;if(event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){legacyEvents.push(asyncEventState);continue;}
+if(event.cat===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'cat parameter.'});continue;}
+if(event.name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'name parameter.'});continue;}
+if(event.id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require an '+'id parameter.'});continue;}
+if(event.cat==='blink.user_timing'){var matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(event.name);if(matched!==null){var key=matched[1]+':'+event.cat;event.args=JSON.parse(Base64.atob(matched[3])||'{}');if(nestableMeasureAsyncEventsByKey[key]===undefined)
+nestableMeasureAsyncEventsByKey[key]=[];nestableMeasureAsyncEventsByKey[key].push(asyncEventState);continue;}}
+var key=event.cat+':'+event.id;if(nestableAsyncEventsByKey[key]===undefined)
+nestableAsyncEventsByKey[key]=[];nestableAsyncEventsByKey[key].push(asyncEventState);}
+this.createLegacyAsyncSlices_(legacyEvents);this.createNestableAsyncSlices_(nestableMeasureAsyncEventsByKey);this.createNestableAsyncSlices_(nestableAsyncEventsByKey);},createLegacyAsyncSlices_:function(legacyEvents){if(legacyEvents.length===0)
+return;legacyEvents.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var asyncEventStatesByNameThenID={};for(var i=0;i<legacyEvents.length;i++){var asyncEventState=legacyEvents[i];var event=asyncEventState.event;var name=event.name;if(name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require a name '+' parameter.'});continue;}
+var id=event.id;if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require an id parameter.'});continue;}
+if(event.ph==='S'){if(asyncEventStatesByNameThenID[name]===undefined)
+asyncEventStatesByNameThenID[name]={};if(asyncEventStatesByNameThenID[name][id]){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', a slice of the same id '+id+' was alrady open.'});continue;}
+asyncEventStatesByNameThenID[name][id]=[];asyncEventStatesByNameThenID[name][id].push(asyncEventState);}else{if(asyncEventStatesByNameThenID[name]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' was open.'});continue;}
+if(asyncEventStatesByNameThenID[name][id]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' with id='+id+' was open.'});continue;}
+var events=asyncEventStatesByNameThenID[name][id];events.push(asyncEventState);if(event.ph==='F'){var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,name);var slice=new asyncSliceConstructor(events[0].event.cat,name,getEventColor(events[0].event),timestampFromUs(events[0].event.ts),tr.b.concatenateObjects(events[0].event.args,events[events.length-1].event.args),timestampFromUs(event.ts-events[0].event.ts),true,undefined,undefined,events[0].event.argsStripped);slice.startThread=events[0].thread;slice.endThread=asyncEventState.thread;slice.id=id;var stepType=events[1].event.ph;var isValid=true;for(var j=1;j<events.length-1;++j){if(events[j].event.ph==='T'||events[j].event.ph==='p'){isValid=this.assertStepTypeMatches_(stepType,events[j]);if(!isValid)
+break;}
+if(events[j].event.ph==='S'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+event.event.id+' had a step before the start event.'});continue;}
+if(events[j].event.ph==='F'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+event.event.id+' had a step after the finish event.'});continue;}
+var startIndex=j+(stepType==='T'?0:-1);var endIndex=startIndex+1;var subName=events[j].event.name;if(!events[j].event.argsStripped&&(events[j].event.ph==='T'||events[j].event.ph==='p'))
+subName=subName+':'+events[j].event.args.step;var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,subName);var subSlice=new asyncSliceConstructor(events[0].event.cat,subName,getEventColor(event,subName+j),timestampFromUs(events[startIndex].event.ts),this.deepCopyIfNeeded_(events[j].event.args),timestampFromUs(events[endIndex].event.ts-events[startIndex].event.ts),undefined,undefined,events[startIndex].event.argsStripped);subSlice.startThread=events[startIndex].thread;subSlice.endThread=events[endIndex].thread;subSlice.id=id;slice.subSlices.push(subSlice);}
+if(isValid){slice.startThread.asyncSliceGroup.push(slice);}
+delete asyncEventStatesByNameThenID[name][id];}}}},createNestableAsyncSlices_:function(nestableEventsByKey){for(var key in nestableEventsByKey){var eventStateEntries=nestableEventsByKey[key];var parentStack=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'){var parentIndex=-1;for(var k=parentStack.length-1;k>=0;--k){if(parentStack[k].event.name===eventStateEntry.event.name){parentIndex=k;break;}}
+if(parentIndex===-1){eventStateEntry.finished=false;}else{parentStack[parentIndex].end=eventStateEntry;while(parentIndex<parentStack.length){parentStack.pop();}}}
+if(parentStack.length>0)
+eventStateEntry.parentEntry=parentStack[parentStack.length-1];if(eventStateEntry.event.ph==='b'){parentStack.push(eventStateEntry);}}
+var topLevelSlices=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'&&eventStateEntry.finished===undefined){continue;}
+var startState=undefined;var endState=undefined;var sliceArgs=eventStateEntry.event.args||{};var sliceError=undefined;if(eventStateEntry.event.ph==='n'){startState=eventStateEntry;endState=eventStateEntry;}else if(eventStateEntry.event.ph==='b'){if(eventStateEntry.end===undefined){eventStateEntry.end=eventStateEntries[eventStateEntries.length-1];sliceError='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async BEGIN event at '+
+eventStateEntry.event.ts+' with name='+
+eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});}else{function concatenateArguments(args1,args2){if(args1.params===undefined||args2.params===undefined)
+return tr.b.concatenateObjects(args1,args2);var args3={};args3.params=tr.b.concatenateObjects(args1.params,args2.params);return tr.b.concatenateObjects(args1,args2,args3);}
+var endArgs=eventStateEntry.end.event.args||{};sliceArgs=concatenateArguments(sliceArgs,endArgs);}
+startState=eventStateEntry;endState=eventStateEntry.end;}else{sliceError='Slice has no matching BEGIN. Start time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async END event at '+
+eventStateEntry.event.ts+' with name='+
+eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});startState=eventStateEntries[0];endState=eventStateEntry;}
+var isTopLevel=(eventStateEntry.parentEntry===undefined);var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(eventStateEntry.event.cat,eventStateEntry.event.name);var thread_start=undefined;var thread_duration=undefined;if(startState.event.tts&&startState.event.use_async_tts){thread_start=timestampFromUs(startState.event.tts);if(endState.event.tts){var thread_end=timestampFromUs(endState.event.tts);thread_duration=thread_end-thread_start;}}
+var slice=new asyncSliceConstructor(eventStateEntry.event.cat,eventStateEntry.event.name,getEventColor(endState.event),timestampFromUs(startState.event.ts),sliceArgs,timestampFromUs(endState.event.ts-startState.event.ts),isTopLevel,thread_start,thread_duration,startState.event.argsStripped);slice.startThread=startState.thread;slice.endThread=endState.thread;slice.startStackFrame=this.getStackFrameForEvent_(startState.event);slice.endStackFrame=this.getStackFrameForEvent_(endState.event);slice.id=key;if(sliceError!==undefined)
+slice.error=sliceError;eventStateEntry.slice=slice;if(isTopLevel){topLevelSlices.push(slice);}else if(eventStateEntry.parentEntry.slice!==undefined){eventStateEntry.parentEntry.slice.subSlices.push(slice);}}
+for(var si=0;si<topLevelSlices.length;si++){topLevelSlices[si].startThread.asyncSliceGroup.push(topLevelSlices[si]);}}},assertStepTypeMatches_:function(stepType,event){if(stepType!=event.event.ph){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+event.event.id+' had both begin and end steps, which is not allowed.'});return false;}
+return true;},createFlowSlices_:function(){if(this.allFlowEvents_.length===0)
+return;var that=this;function validateFlowEvent(){if(event.name===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require a name parameter.'});return false;}
+if(event.ph==='s'||event.ph==='f'||event.ph==='t'){if(event.id===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require an id parameter.'});return false;}
+return true;}
+if(event.bind_id){if(event.flow_in===undefined&&event.flow_out===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow producer or consumer require flow_in or flow_out.'});return false;}
+return true;}
+return false;}
+function createFlowEvent(thread,event,opt_slice){var startSlice,flowId,flowStartTs;if(event.bind_id){startSlice=opt_slice;flowId=event.bind_id;flowStartTs=timestampFromUs(event.ts+event.dur);}else{var ts=timestampFromUs(event.ts);startSlice=thread.sliceGroup.findSliceAtTs(ts);if(startSlice===undefined)
+return undefined;flowId=event.id;flowStartTs=ts;}
+var flowEvent=new tr.model.FlowEvent(event.cat,flowId,event.name,getEventColor(event),flowStartTs,that.deepCopyAlways_(event.args));flowEvent.startSlice=startSlice;flowEvent.startStackFrame=that.getStackFrameForEvent_(event);flowEvent.endStackFrame=undefined;startSlice.outFlowEvents.push(flowEvent);return flowEvent;}
+function finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent,opt_slice){var endSlice;if(event.bind_id){endSlice=opt_slice;}else{var ts=timestampFromUs(event.ts);if(bindToParent){endSlice=thread.sliceGroup.findSliceAtTs(ts);}else{endSlice=thread.sliceGroup.findNextSliceAfter(ts,refGuid);}
+if(endSlice===undefined)
+return false;}
+endSlice.inFlowEvents.push(flowEvent);flowEvent.endSlice=endSlice;flowEvent.duration=timestampFromUs(event.ts)-flowEvent.start;flowEvent.endStackFrame=that.getStackFrameForEvent_(event);that.mergeArgsInto_(flowEvent.args,event.args,flowEvent.title);return true;}
+function processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice){var flowEvent=flowIdToEvent[event.bind_id];if(flowEvent===undefined){that.model_.importWarning({type:'flow_slice_ordering_error',message:'Flow consumer '+event.bind_id+' does not have '+'a flow producer'});return false;}else if(flowEvent.endSlice){var flowProducer=flowEvent.startSlice;flowEvent=createFlowEvent(undefined,sliceGuidToEvent[flowProducer.guid],flowProducer);}
+var ok=finishFlowEventWith(flowEvent,undefined,event,refGuid,undefined,slice);if(ok){that.model_.flowEvents.push(flowEvent);}else{that.model_.importWarning({type:'flow_slice_end_error',message:'Flow consumer '+event.bind_id+' does not end '+'at an actual slice, so cannot be created.'});return false;}
+return true;}
+function processFlowProducer(flowIdToEvent,flowStatus,event,slice){if(flowIdToEvent[event.bind_id]&&flowStatus[event.bind_id]){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' already seen'});return false;}
+var flowEvent=createFlowEvent(undefined,event,slice);if(!flowEvent){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' does not start'+'a flow'});return false;}
+flowIdToEvent[event.bind_id]=flowEvent;return;}
+this.allFlowEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var flowIdToEvent={};var sliceGuidToEvent={};var flowStatus={};for(var i=0;i<this.allFlowEvents_.length;++i){var data=this.allFlowEvents_[i];var refGuid=data.refGuid;var event=data.event;var thread=data.thread;if(!validateFlowEvent(event))
+continue;if(event.bind_id){var slice=data.slice;sliceGuidToEvent[slice.guid]=event;if(event.flowPhase===PRODUCER){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
+continue;flowStatus[event.bind_id]=true;}
+else{if(!processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice))
+continue;flowStatus[event.bind_id]=false;if(event.flowPhase===STEP){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
+continue;flowStatus[event.bind_id]=true;}}
+continue;}
+var flowEvent;if(event.ph==='s'){if(flowIdToEvent[event.id]){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' already seen when '+'encountering start of flow event.'});continue;}
+flowEvent=createFlowEvent(thread,event);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' does not start '+'at an actual slice, so cannot be created.'});continue;}
+flowIdToEvent[event.id]=flowEvent;}else if(event.ph==='t'||event.ph==='f'){flowEvent=flowIdToEvent[event.id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Found flow phase '+event.ph+' for id: '+event.id+' but no flow start found.'});continue;}
+var bindToParent=event.ph==='t';if(event.ph==='f'){if(event.bp===undefined){if(event.cat.indexOf('input')>-1)
+bindToParent=true;else if(event.cat.indexOf('ipc.flow')>-1)
+bindToParent=true;}else{if(event.bp!=='e'){this.model_.importWarning({type:'flow_slice_bind_point_error',message:'Flow event with invalid binding point (event.bp).'});continue;}
+bindToParent=true;}}
+var ok=finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent);if(ok){that.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'event id '+event.id+' does not end '+'at an actual slice, so cannot be created.'});}
+flowIdToEvent[event.id]=undefined;if(ok&&event.ph==='t'){flowEvent=createFlowEvent(thread,event);flowIdToEvent[event.id]=flowEvent;}}}},createExplicitObjects_:function(){if(this.allObjectEvents_.length===0)
+return;function processEvent(objectEventState){var event=objectEventState.event;var scopedId=new tr.model.ScopedId(event.scope||tr.model.OBJECT_DEFAULT_SCOPE,event.id);var thread=objectEventState.thread;if(event.name===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an name parameter.'});}
+if(scopedId.id===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an id parameter.'});}
+var process=thread.parent;var ts=timestampFromUs(event.ts);var instance;if(event.ph==='N'){try{instance=process.objects.idWasCreated(scopedId,event.cat,event.name,ts);}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing create of '+
+scopedId+' at ts='+ts+': '+e});return;}}else if(event.ph==='O'){if(event.args.snapshot===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+scopedId+' at ts='+ts+': '+'Snapshots must have args: {snapshot: ...}'});return;}
+var snapshot;try{var args=this.deepCopyIfNeeded_(event.args.snapshot);var cat;if(args.cat){cat=args.cat;delete args.cat;}else{cat=event.cat;}
+var baseTypename;if(args.base_type){baseTypename=args.base_type;delete args.base_type;}else{baseTypename=undefined;}
+snapshot=process.objects.addSnapshot(scopedId,cat,event.name,ts,args,baseTypename);snapshot.snapshottedOnThread=thread;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing snapshot of '+
+scopedId+' at ts='+ts+': '+e});return;}
+instance=snapshot.objectInstance;}else if(event.ph==='D'){try{process.objects.idWasDeleted(scopedId,event.cat,event.name,ts);var instanceMap=process.objects.getOrCreateInstanceMap_(scopedId);instance=instanceMap.lastInstance;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing delete of '+
+scopedId+' at ts='+ts+': '+e});return;}}
+if(instance)
+instance.colorId=getEventColor(event,instance.typeName);}
+this.allObjectEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var allObjectEvents=this.allObjectEvents_;for(var i=0;i<allObjectEvents.length;i++){var objectEventState=allObjectEvents[i];try{processEvent.call(this,objectEventState);}catch(e){this.model_.importWarning({type:'object_parse_error',message:e.message});}}},createImplicitObjects_:function(){tr.b.iterItems(this.model_.processes,function(pid,process){this.createImplicitObjectsForProcess_(process);},this);},createImplicitObjectsForProcess_:function(process){function processField(referencingObject,referencingObjectFieldName,referencingObjectFieldValue,containingSnapshot){if(!referencingObjectFieldValue)
+return;if(referencingObjectFieldValue instanceof
+tr.model.ObjectSnapshot)
+return null;if(referencingObjectFieldValue.id===undefined)
+return;var implicitSnapshot=referencingObjectFieldValue;var rawId=implicitSnapshot.id;var m=/(.+)\/(.+)/.exec(rawId);if(!m)
+throw new Error('Implicit snapshots must have names.');delete implicitSnapshot.id;var name=m[1];var id=m[2];var res;var cat;if(implicitSnapshot.cat!==undefined)
+cat=implicitSnapshot.cat;else
+cat=containingSnapshot.objectInstance.category;var baseTypename;if(implicitSnapshot.base_type)
+baseTypename=implicitSnapshot.base_type;else
+baseTypename=undefined;var scope=containingSnapshot.objectInstance.scopedId.scope;try{res=process.objects.addSnapshot(new tr.model.ScopedId(scope,id),cat,name,containingSnapshot.ts,implicitSnapshot,baseTypename);}catch(e){this.model_.importWarning({type:'object_snapshot_parse_error',message:'While processing implicit snapshot of '+
+rawId+' at ts='+containingSnapshot.ts+': '+e});return;}
+res.objectInstance.hasImplicitSnapshots=true;res.containingSnapshot=containingSnapshot;res.snapshottedOnThread=containingSnapshot.snapshottedOnThread;referencingObject[referencingObjectFieldName]=res;if(!(res instanceof tr.model.ObjectSnapshot))
+throw new Error('Created object must be instanceof snapshot');return res.args;}
+function iterObject(object,func,containingSnapshot,thisArg){if(!(object instanceof Object))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++){var res=func.call(thisArg,object,i,object[i],containingSnapshot);if(res===null)
+continue;if(res)
+iterObject(res,func,containingSnapshot,thisArg);else
+iterObject(object[i],func,containingSnapshot,thisArg);}
+return;}
+for(var key in object){var res=func.call(thisArg,object,key,object[key],containingSnapshot);if(res===null)
+continue;if(res)
+iterObject(res,func,containingSnapshot,thisArg);else
+iterObject(object[key],func,containingSnapshot,thisArg);}}
+process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(snapshot){if(snapshot.args.id!==undefined)
+throw new Error('args cannot have an id field inside it');iterObject(snapshot.args,processField,snapshot,this);},this);},this);},createMemoryDumps_:function(){for(var dumpId in this.allMemoryDumpEvents_)
+this.createGlobalMemoryDump_(this.allMemoryDumpEvents_[dumpId],dumpId);},createGlobalMemoryDump_:function(dumpIdEvents,dumpId){var globalRange=new tr.b.Range();for(var pid in dumpIdEvents){var processEvents=dumpIdEvents[pid];for(var i=0;i<processEvents.length;i++)
+globalRange.addValue(timestampFromUs(processEvents[i].ts));}
+if(globalRange.isEmpty)
+throw new Error('Internal error: Global memory dump without events');var globalMemoryDump=new tr.model.GlobalMemoryDump(this.model_,globalRange.min);globalMemoryDump.duration=globalRange.range;this.model_.globalMemoryDumps.push(globalMemoryDump);var globalMemoryAllocatorDumpsByFullName={};var levelsOfDetail={};var allMemoryAllocatorDumpsByGuid={};for(var pid in dumpIdEvents){this.createProcessMemoryDump_(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,dumpIdEvents[pid],pid,dumpId);}
+globalMemoryDump.levelOfDetail=levelsOfDetail.global;globalMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(globalMemoryAllocatorDumpsByFullName);this.parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId);},createProcessMemoryDump_:function(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,processEvents,pid,dumpId){var processRange=new tr.b.Range();for(var i=0;i<processEvents.length;i++)
+processRange.addValue(timestampFromUs(processEvents[i].ts));if(processRange.isEmpty)
+throw new Error('Internal error: Process memory dump without events');var process=this.model_.getOrCreateProcess(pid);var processMemoryDump=new tr.model.ProcessMemoryDump(globalMemoryDump,process,processRange.min);processMemoryDump.duration=processRange.range;process.memoryDumps.push(processMemoryDump);globalMemoryDump.processMemoryDumps[pid]=processMemoryDump;var processMemoryAllocatorDumpsByFullName={};for(var i=0;i<processEvents.length;i++){var processEvent=processEvents[i];var dumps=processEvent.args.dumps;if(dumps===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'\'dumps\' field not found in a process memory dump'+' event for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
+this.parseMemoryDumpTotals_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpVmRegions_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpHeapDumps_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpLevelOfDetail_(levelsOfDetail,dumps,pid,dumpId);this.parseMemoryDumpAllocatorDumps_(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId);}
+if(levelsOfDetail.process===undefined){levelsOfDetail.process=processMemoryDump.vmRegions?DETAILED:LIGHT;}
+if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'global',levelsOfDetail.process)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for global memory'+' dump (dump ID='+dumpId+').'});}
+processMemoryDump.levelOfDetail=levelsOfDetail.process;delete levelsOfDetail.process;processMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(processMemoryAllocatorDumpsByFullName);},parseMemoryDumpTotals_:function(processMemoryDump,dumps,pid,dumpId){var rawTotals=dumps.process_totals;if(rawTotals===undefined)
+return;if(processMemoryDump.totals!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Process totals provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+var totals={};var platformSpecificTotals=undefined;for(var rawTotalName in rawTotals){var rawTotalValue=rawTotals[rawTotalName];if(rawTotalValue===undefined)
+continue;if(rawTotalName==='resident_set_bytes'){totals.residentBytes=parseInt(rawTotalValue,16);continue;}
+if(rawTotalName==='peak_resident_set_bytes'){totals.peakResidentBytes=parseInt(rawTotalValue,16);continue;}
+if(rawTotalName==='is_peak_rss_resetable'){totals.arePeakResidentBytesResettable=!!rawTotalValue;continue;}
+if(platformSpecificTotals===undefined){platformSpecificTotals={};totals.platformSpecific=platformSpecificTotals;}
+platformSpecificTotals[rawTotalName]=parseInt(rawTotalValue,16);}
+if(totals.peakResidentBytes===undefined&&totals.arePeakResidentBytesResettable!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field peak_resident_set_bytes found'+' but is_peak_rss_resetable not found in'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});}
+if(totals.arePeakResidentBytesResettable!==undefined&&totals.peakResidentBytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field is_peak_rss_resetable found'+' but peak_resident_set_bytes not found in'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});}
+processMemoryDump.totals=totals;},parseMemoryDumpVmRegions_:function(processMemoryDump,dumps,pid,dumpId){var rawProcessMmaps=dumps.process_mmaps;if(rawProcessMmaps===undefined)
+return;var rawVmRegions=rawProcessMmaps.vm_regions;if(rawVmRegions===undefined)
+return;if(processMemoryDump.vmRegions!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'VM regions provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+var vmRegions=new Array(rawVmRegions.length);for(var i=0;i<rawVmRegions.length;i++){var rawVmRegion=rawVmRegions[i];var byteStats={};var rawByteStats=rawVmRegion.bs;for(var rawByteStatName in rawByteStats){var rawByteStatValue=rawByteStats[rawByteStatName];if(rawByteStatValue===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Byte stat \''+rawByteStatName+'\' of VM region '+
+i+' ('+rawVmRegion.mf+') in process memory dump for '+'PID='+pid+' and dump ID='+dumpId+' does not have a value.'});continue;}
+var byteStatName=BYTE_STAT_NAME_MAP[rawByteStatName];if(byteStatName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown byte stat name \''+rawByteStatName+'\' ('+
+rawByteStatValue+') of VM region '+i+' ('+
+rawVmRegion.mf+') in process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
+byteStats[byteStatName]=parseInt(rawByteStatValue,16);}
+vmRegions[i]=new tr.model.VMRegion(parseInt(rawVmRegion.sa,16),parseInt(rawVmRegion.sz,16),rawVmRegion.pf,rawVmRegion.mf,byteStats);}
+processMemoryDump.vmRegions=tr.model.VMRegionClassificationNode.fromRegions(vmRegions);},parseMemoryDumpHeapDumps_:function(processMemoryDump,dumps,pid,dumpId){var rawHeapDumps=dumps.heaps;if(rawHeapDumps===undefined)
+return;if(processMemoryDump.heapDumps!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Heap dumps provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+var model=this.model_;var idPrefix='p'+pid+':';var heapDumps={};var objectTypeNameMap=this.objectTypeNameMap_[pid];if(objectTypeNameMap===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing mapping from object type IDs to names.'});}
+for(var allocatorName in rawHeapDumps){var entries=rawHeapDumps[allocatorName].entries;if(entries===undefined||entries.length===0){this.model_.importWarning({type:'memory_dump_parse_error',message:'No heap entries in a '+allocatorName+' heap dump for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
+var isOldFormat=entries[0].bt===undefined;if(!isOldFormat&&objectTypeNameMap===undefined){continue;}
+var heapDump=new tr.model.HeapDump(processMemoryDump,allocatorName);for(var i=0;i<entries.length;i++){var entry=entries[i];var leafStackFrameIndex=entry.bt;var leafStackFrame;if(isOldFormat){if(leafStackFrameIndex===undefined){leafStackFrame=undefined;}else{var leafStackFrameId=idPrefix+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+
+leafStackFrameId+') of heap entry '+i+' (size '+
+size+') in a '+allocatorName+' heap dump for PID='+pid+'.'});continue;}}
+leafStackFrameId+=':self';if(model.stackFrames[leafStackFrameId]!==undefined){leafStackFrame=model.stackFrames[leafStackFrameId];}else{leafStackFrame=new tr.model.StackFrame(leafStackFrame,leafStackFrameId,'<self>',undefined);model.addStackFrame(leafStackFrame);}}}else{if(leafStackFrameIndex===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing stack frame ID of heap entry '+i+' (size '+size+') in a '+allocatorName+' heap dump for PID='+pid+'.'});continue;}
+var leafStackFrameId=idPrefix+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+leafStackFrameId+') of heap entry '+i+' (size '+size+') in a '+
+allocatorName+' heap dump for PID='+pid+'.'});continue;}}}
+var objectTypeId=entry.type;var objectTypeName;if(objectTypeId===undefined){objectTypeName=undefined;}else if(objectTypeNameMap===undefined){continue;}else{objectTypeName=objectTypeNameMap[objectTypeId];if(objectTypeName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing object type name (ID '+objectTypeId+') of heap entry '+i+' (size '+size+') in a '+
+allocatorName+' heap dump for pid='+pid+'.'});continue;}}
+var size=parseInt(entry.size,16);heapDump.addEntry(leafStackFrame,objectTypeName,size);}
+if(heapDump.entries.length>0)
+heapDumps[allocatorName]=heapDump;}
+if(Object.keys(heapDumps).length>0)
+processMemoryDump.heapDumps=heapDumps;},parseMemoryDumpLevelOfDetail_:function(levelsOfDetail,dumps,pid,dumpId){var rawLevelOfDetail=dumps.level_of_detail;var level;switch(rawLevelOfDetail){case'light':level=LIGHT;break;case'detailed':level=DETAILED;break;case undefined:level=undefined;break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'unknown raw level of detail \''+rawLevelOfDetail+'\' of process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'process',level)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for process memory'+' dump for PID='+pid+' (dump ID='+dumpId+').'});}},updateMemoryDumpLevelOfDetail_:function(levelsOfDetail,scope,level){if(!(scope in levelsOfDetail)||level===levelsOfDetail[scope]){levelsOfDetail[scope]=level;return true;}
+if(MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(level)>MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(levelsOfDetail[scope])){levelsOfDetail[scope]=level;}
+return false;},parseMemoryDumpAllocatorDumps_:function(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId){var rawAllocatorDumps=dumps.allocators;if(rawAllocatorDumps===undefined)
+return;for(var fullName in rawAllocatorDumps){var rawAllocatorDump=rawAllocatorDumps[fullName];var guid=rawAllocatorDump.guid;if(guid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' for PID='+pid+' and dump ID='+dumpId+' does not have a GUID.'});}
+var flags=rawAllocatorDump.flags||0;var isWeakDump=!!(flags&WEAK_MEMORY_ALLOCATOR_DUMP_FLAG);var containerMemoryDump;var dstIndex;if(fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)){fullName=fullName.substring(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length);containerMemoryDump=globalMemoryDump;dstIndex=globalMemoryAllocatorDumpsByFullName;}else{containerMemoryDump=processMemoryDump;dstIndex=processMemoryAllocatorDumpsByFullName;}
+var allocatorDump=allMemoryAllocatorDumpsByGuid[guid];if(allocatorDump===undefined){if(fullName in dstIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple GUIDs provided for'+' memory allocator dump '+fullName+': '+
+dstIndex[fullName].guid+', '+guid+' (ignored) for'+' PID='+pid+' and dump ID='+dumpId+'.'});continue;}
+allocatorDump=new tr.model.MemoryAllocatorDump(containerMemoryDump,fullName,guid);allocatorDump.weak=isWeakDump;dstIndex[fullName]=allocatorDump;if(guid!==undefined)
+allMemoryAllocatorDumpsByGuid[guid]=allocatorDump;}else{if(allocatorDump.containerMemoryDump!==containerMemoryDump){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
+dumpId+' dumped in different contexts.'});continue;}
+if(allocatorDump.fullName!==fullName){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump with GUID='+guid+' for PID='+
+pid+' and dump ID='+dumpId+' has multiple names: '+
+allocatorDump.fullName+', '+fullName+' (ignored).'});continue;}
+if(!isWeakDump){allocatorDump.weak=false;}}
+var attributes=rawAllocatorDump.attrs;if(attributes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+' does not have attributes.'});attributes={};}
+for(var attrName in attributes){var attrArgs=attributes[attrName];var attrType=attrArgs.type;var attrValue=attrArgs.value;switch(attrType){case'scalar':if(attrName in allocatorDump.numerics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for scalar attribute '+
+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
+dumpId+'.'});break;}
+var unit=attrArgs.units==='bytes'?tr.v.Unit.byName.sizeInBytes_smallerIsBetter:tr.v.Unit.byName.unitlessNumber_smallerIsBetter;var value=parseInt(attrValue,16);allocatorDump.addNumeric(attrName,new tr.v.ScalarNumeric(unit,value));break;case'string':if(attrName in allocatorDump.diagnostics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for string attribute '+
+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
+dumpId+'.'});break;}
+allocatorDump.addDiagnostic(attrName,attrValue);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown type provided for attribute '+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+': '+
+attrType});break;}}}},inferMemoryAllocatorDumpTree_:function(memoryAllocatorDumpsByFullName){var rootAllocatorDumps=[];var fullNames=Object.keys(memoryAllocatorDumpsByFullName);fullNames.sort();for(var i=0;i<fullNames.length;i++){var fullName=fullNames[i];var allocatorDump=memoryAllocatorDumpsByFullName[fullName];while(true){var lastSlashIndex=fullName.lastIndexOf('/');if(lastSlashIndex===-1){rootAllocatorDumps.push(allocatorDump);break;}
+var parentFullName=fullName.substring(0,lastSlashIndex);var parentAllocatorDump=memoryAllocatorDumpsByFullName[parentFullName];var parentAlreadyExisted=true;if(parentAllocatorDump===undefined){parentAlreadyExisted=false;parentAllocatorDump=new tr.model.MemoryAllocatorDump(allocatorDump.containerMemoryDump,parentFullName);if(allocatorDump.weak!==false){parentAllocatorDump.weak=undefined;}
+memoryAllocatorDumpsByFullName[parentFullName]=parentAllocatorDump;}
+allocatorDump.parent=parentAllocatorDump;parentAllocatorDump.children.push(allocatorDump);if(parentAlreadyExisted){if(!allocatorDump.weak){while(parentAllocatorDump!==undefined&&parentAllocatorDump.weak===undefined){parentAllocatorDump.weak=false;parentAllocatorDump=parentAllocatorDump.parent;}}
+break;}
+fullName=parentFullName;allocatorDump=parentAllocatorDump;}}
+for(var fullName in memoryAllocatorDumpsByFullName){var allocatorDump=memoryAllocatorDumpsByFullName[fullName];if(allocatorDump.weak===undefined)
+allocatorDump.weak=true;}
+return rootAllocatorDumps;},parseMemoryDumpAllocatorEdges_:function(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId){for(var pid in dumpIdEvents){var processEvents=dumpIdEvents[pid];for(var i=0;i<processEvents.length;i++){var processEvent=processEvents[i];var dumps=processEvent.args.dumps;if(dumps===undefined)
+continue;var rawEdges=dumps.allocators_graph;if(rawEdges===undefined)
+continue;for(var j=0;j<rawEdges.length;j++){var rawEdge=rawEdges[j];var sourceGuid=rawEdge.source;var sourceDump=allMemoryAllocatorDumpsByGuid[sourceGuid];if(sourceDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing source memory allocator dump (GUID='+
+sourceGuid+').'});continue;}
+var targetGuid=rawEdge.target;var targetDump=allMemoryAllocatorDumpsByGuid[targetGuid];if(targetDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing target memory allocator dump (GUID='+
+targetGuid+').'});continue;}
+var importance=rawEdge.importance;var edge=new tr.model.MemoryAllocatorDumpLink(sourceDump,targetDump,importance);switch(rawEdge.type){case'ownership':if(sourceDump.owns!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+sourceDump.fullName+' (GUID='+sourceGuid+') already owns a memory'+' allocator dump ('+
+sourceDump.owns.target.fullName+').'});}else{sourceDump.owns=edge;targetDump.ownedBy.push(edge);}
+break;case'retention':sourceDump.retains.push(edge);targetDump.retainedBy.push(edge);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Invalid edge type: '+rawEdge.type+' (PID='+pid+', dump ID='+dumpId+', source='+sourceGuid+', target='+targetGuid+', importance='+importance+').'});}}}}}};tr.importer.Importer.register(TraceEventImporter);return{TraceEventImporter:TraceEventImporter};});'use strict';tr.exportTo('tr.e.measure',function(){var AsyncSlice=tr.model.AsyncSlice;function MeasureAsyncSlice(){this.groupTitle_='Ungrouped Measure';var matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(arguments[1]);if(matched!==null){arguments[1]=matched[2];this.groupTitle_=matched[1];}
+AsyncSlice.apply(this,arguments);}
+MeasureAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return this.groupTitle_;},get title(){return this.title_;},set title(title){this.title_=title;}};AsyncSlice.register(MeasureAsyncSlice,{categoryParts:['blink.user_timing']});return{MeasureAsyncSlice:MeasureAsyncSlice};});'use strict';tr.exportTo('tr.e.net',function(){var AsyncSlice=tr.model.AsyncSlice;function NetAsyncSlice(){AsyncSlice.apply(this,arguments);this.url_=undefined;this.byteCount_=undefined;this.isTitleComputed_=false;this.isUrlComputed_=false;}
+NetAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return'NetLog';},get title(){if(this.isTitleComputed_||!this.isTopLevel)
+return this.title_;if(this.url!==undefined&&this.url.length>0){this.title_=this.url;}else if(this.args!==undefined&&this.args.source_type!==undefined){this.title_=this.args.source_type;}
+this.isTitleComputed_=true;return this.title_;},set title(title){this.title_=title;},get url(){if(this.isUrlComputed_)
+return this.url_;if(this.args!==undefined&&this.args.params!==undefined&&this.args.params.url!==undefined){this.url_=this.args.params.url;}else if(this.subSlices!==undefined&&this.subSlices.length>0){for(var i=0;i<this.subSlices.length&&!this.url_;i++){if(this.subSlices[i].url!==undefined)
+this.url_=this.subSlices[i].url;}}
+this.isUrlComputed_=true;return this.url_;},get byteCount(){if(this.byteCount_!==undefined)
+return this.byteCount_;this.byteCount_=0;if((this.originalTitle==='URL_REQUEST_JOB_FILTERED_BYTES_READ'||this.originalTitle==='URL_REQUEST_JOB_BYTES_READ')&&this.args!==undefined&&this.args.params!==undefined&&this.args.params.byte_count!==undefined){this.byteCount_=this.args.params.byte_count;}
+for(var i=0;i<this.subSlices.length;i++){this.byteCount_+=this.subSlices[i].byteCount;}
+return this.byteCount_;}};AsyncSlice.register(NetAsyncSlice,{categoryParts:['netlog','disabled-by-default-netlog']});return{NetAsyncSlice:NetAsyncSlice};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function Activity(name,category,range,args){tr.model.TimedEvent.call(this,range.min);this.title=name;this.category=category;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(name);this.duration=range.duration;this.args=args;this.name=name;};Activity.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};return{Activity:Activity};});'use strict';tr.exportTo('tr.e.importer.android',function(){var Importer=tr.importer.Importer;var ACTIVITY_STATE={NONE:'none',CREATED:'created',STARTED:'started',RESUMED:'resumed',PAUSED:'paused',STOPPED:'stopped',DESTROYED:'destroyed'};var activityMap={};function EventLogImporter(model,events){this.model_=model;this.events_=events;this.importPriority=3;}
 var eventLogActivityRE=new RegExp('(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d+)'+'\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s*'+'(am_\\w+)\\s*:(.*)');var amCreateRE=new RegExp('\s*\\[.*,.*,.*,(.*),.*,.*,.*,.*\\]');var amFocusedRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amProcStartRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,.*,activity,(.*)\\]');var amOnResumeRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amOnPauseRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amLaunchTimeRE=new RegExp('\s*\\[\\d+,\\d+,(.*),(\\d+),(\\d+)');var amDestroyRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,(.*)\\]');EventLogImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
-return false;return eventLogActivityRE.test(events);};EventLogImporter.prototype={__proto__:Importer.prototype,get model(){return this.model_;},getFullActivityName:function(component){var componentSplit=component.split('/');if(componentSplit[1].startsWith('.'))
+return false;if(/^<!DOCTYPE html>/.test(events))
+return false;return eventLogActivityRE.test(events);};EventLogImporter.prototype={__proto__:Importer.prototype,get importerName(){return'EventLogImporter';},get model(){return this.model_;},getFullActivityName:function(component){var componentSplit=component.split('/');if(componentSplit[1].startsWith('.'))
 return componentSplit[0]+componentSplit[1];return componentSplit[1];},getProcName:function(component){var componentSplit=component.split('/');return componentSplit[0];},findOrCreateActivity:function(activityName){if(activityName in activityMap)
 return activityMap[activityName];var activity={state:ACTIVITY_STATE.NONE,name:activityName};activityMap[activityName]=activity;return activity;},deleteActivity:function(activityName){delete activityMap[activityName];},handleCreateActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.CREATED;activity.createdTs=ts;},handleFocusActivity:function(ts,procName,activityName){var activity=this.findOrCreateActivity(activityName);activity.lastFocusedTs=ts;},handleProcStartForActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.procStartTs=ts;},handleOnResumeCalled:function(ts,pid,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.RESUMED;activity.lastResumeTs=ts;activity.pid=pid;},handleOnPauseCalled:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.PAUSED;activity.lastPauseTs=ts;if(ts>this.model_.bounds.min&&ts<this.model_.bounds.max)
 this.addActivityToProcess(activity);},handleLaunchTime:function(ts,activityName,launchTime){var activity=this.findOrCreateActivity(activityName);activity.launchTime=launchTime;},handleDestroyActivity:function(ts,activityName){this.deleteActivity(activityName);},addActivityToProcess:function(activity){if(activity.pid===undefined)
@@ -3720,28 +4725,31 @@
 match[1].substring(5,match[1].length);var monotonic_ts=Date.parse(ts)+
 this.model_.realtime_to_monotonic_offset_ms;var pid=match[2];var action=match[5];var data=match[6];if(action==='am_create_activity'){match=amCreateRE.exec(data);if(match&&match.length>=2){this.handleCreateActivity(monotonic_ts,this.getFullActivityName(match[1]));}}else if(action==='am_focused_activity'){match=amFocusedRE.exec(data);if(match&&match.length>=2){this.handleFocusActivity(monotonic_ts,this.getProcName(match[1]),this.getFullActivityName(match[1]));}}else if(action==='am_proc_start'){match=amProcStartRE.exec(data);if(match&&match.length>=2){this.handleProcStartForActivity(monotonic_ts,this.getFullActivityName(match[1]));}}else if(action==='am_on_resume_called'){match=amOnResumeRE.exec(data);if(match&&match.length>=2)
 this.handleOnResumeCalled(monotonic_ts,pid,match[1]);}else if(action==='am_on_paused_called'){match=amOnPauseRE.exec(data);if(match&&match.length>=2)
-this.handleOnPauseCalled(monotonic_ts,match[1]);}else if(action==='am_activity_launch_time'){match=amLaunchTimeRE.exec(data);this.handleLaunchTime(monotonic_ts,this.getFullActivityName(match[1]),match[2]);}else if(action==='am_destroy_activity'){match=amDestroyRE.exec(data);if(match&&match.length==2){this.handleDestroyActivity(monotonic_ts,this.getFullActivityName(match[1]));}}},importEvents:function(isSecondaryImport){if(isNaN(this.model_.realtime_to_monotonic_offset_ms)){this.model_.importWarning({type:'eveng_log_clock_sync',message:'Need a trace_event_clock_sync to map realtime to import.'});return;}
-this.model_.updateBounds();var lines=this.events_.split('\n');lines.forEach(this.parseAmLine_,this);for(var activityName in activityMap){var activity=activityMap[activityName];if(activity.state==ACTIVITY_STATE.RESUMED){activity.lastPauseTs=this.model_.bounds.max;this.addActivityToProcess(activity);}}}};Importer.register(EventLogImporter);return{EventLogImporter:EventLogImporter};});'use strict';tr.exportTo('tr.e.importer.battor',function(){function BattorImporter(model,events){this.importPriority=3;this.sampleRate_=undefined;this.model_=model;this.events_=events;}
-var TestExports={};var battorDataLineRE=/^(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)$/;var battorHeaderLineRE=/^# BattOr/;var sampleRateLineRE=/^# sample_rate=(\d+)Hz/;BattorImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
-return false;return battorHeaderLineRE.test(events);};BattorImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},importEvents:function(isSecondaryImport){if(this.model_.device.powerSeries){this.model_.importWarning({type:'import_error',message:'Power counter exists, can not import BattOr power trace.'});return;}
-var name='power';var series=new tr.model.PowerSeries(this.model_.device);this.importPowerSamples(series);var syncMarks=this.model_.getClockSyncRecordsNamed('battor');if(syncMarks.length<1){this.model_.importWarning({type:'clock_sync',message:'Cannot import BattOr power trace without a sync signal.'});return;}
-var shiftTs=this.correlationClockSync(syncMarks,series);if(shiftTs===undefined){this.model_.importWarning({type:'clock_sync',message:'All of the BattOr power trace clock sync techinques failed.'});return;}
+this.handleOnPauseCalled(monotonic_ts,match[1]);}else if(action==='am_activity_launch_time'){match=amLaunchTimeRE.exec(data);this.handleLaunchTime(monotonic_ts,this.getFullActivityName(match[1]),match[2]);}else if(action==='am_destroy_activity'){match=amDestroyRE.exec(data);if(match&&match.length==2){this.handleDestroyActivity(monotonic_ts,this.getFullActivityName(match[1]));}}},importEvents:function(){if(isNaN(this.model_.realtime_to_monotonic_offset_ms)){this.model_.importWarning({type:'eveng_log_clock_sync',message:'Need a trace_event_clock_sync to map realtime to import.'});return;}
+this.model_.updateBounds();var lines=this.events_.split('\n');lines.forEach(this.parseAmLine_,this);for(var activityName in activityMap){var activity=activityMap[activityName];if(activity.state==ACTIVITY_STATE.RESUMED){activity.lastPauseTs=this.model_.bounds.max;this.addActivityToProcess(activity);}}}};Importer.register(EventLogImporter);return{EventLogImporter:EventLogImporter};});'use strict';tr.exportTo('tr.e.importer.battor',function(){function BattorImporter(model,events){this.importPriority=3;this.sampleRate_=undefined;this.model_=model;this.events_=events;this.explicitSyncMark_=undefined;}
+var TestExports={};var battorDataLineRE=new RegExp('^(\\d+\\.\\d+)\\s+(\\d+\\.\\d+)\\s+(\\d+\\.\\d+)'+'(?:\\s+<(\\S+)>)?$');var battorHeaderLineRE=/^# BattOr/;var sampleRateLineRE=/^# sample_rate (\d+) Hz/;BattorImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
+return false;return battorHeaderLineRE.test(events);};BattorImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'BattorImporter';},get model(){return this.model_;},importEvents:function(){if(this.model_.device.powerSeries){this.model_.importWarning({type:'import_error',message:'Power counter exists, can not import BattOr power trace.'});return;}
+var name='power';var series=new tr.model.PowerSeries(this.model_.device);this.importPowerSamples(series);var battorSyncMarks=this.model_.getClockSyncRecordsWithSyncId('battor');var shiftTs=undefined;shiftTs=this.correlationClockSync(battorSyncMarks,series);if(shiftTs===undefined)
+shiftTs=this.explicitClockSync();if(shiftTs===undefined){this.model_.importWarning({type:'clock_sync',message:'All of the BattOr power trace clock sync techinques failed.'});return;}
 series.shiftTimestampsForward(shiftTs);this.model_.device.powerSeries=series;},importPowerSamples:function(series){var lines=this.events_.split('\n');this.model_.updateBounds();var minTs=0;if(this.model_.bounds.min!==undefined)
 minTs=this.model_.bounds.min;lines.forEach(function(line){line=line.trim();if(line.length===0)
 return;if(/^#/.test(line)){groups=sampleRateLineRE.exec(line);if(!groups)
 return;this.sampleRate_=parseInt(groups[1]);}else{var groups=battorDataLineRE.exec(line);if(!groups){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});return;}
-var time=parseFloat(groups[1])+minTs;var voltage_mV=parseFloat(groups[2]);var current_mA=parseFloat(groups[3]);series.addPowerSample(time,(voltage_mV*current_mA)/1000);}},this);},correlationClockSync:function(syncMarks,series){var syncCtr=this.model_.kernel.counters['null.vreg '+syncMarks[0].args['regulator']+' enabled'];if(syncCtr===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot correlate BattOr power trace without sync vreg.'});return undefined;}
-var syncEvents=[];var firstSyncEventTs=undefined;syncCtr.series[0].iterateAllEvents(function(event){if(event.timestamp>=syncMarks[0].ts&&event.timestamp<=syncMarks[1].ts){if(firstSyncEventTs===undefined)
+var time=parseFloat(groups[1])+minTs;var voltage_mV=parseFloat(groups[2]);var current_mA=parseFloat(groups[3]);series.addPowerSample(time,(voltage_mV*current_mA)/1000);if(groups[4]!==undefined&&this.explicitSyncMark_===undefined){var id=groups[4];this.explicitSyncMark_={'id':id,'ts':time};}}},this);},correlationClockSync:function(syncMarks,series){if(syncMarks.length!==2)
+return undefined;var syncCtr=this.model_.kernel.counters['null.vreg '+syncMarks[0].args['regulator']+' enabled'];if(syncCtr===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot correlate BattOr power trace without sync vreg.'});return undefined;}
+var syncEvents=[];var firstSyncEventTs=undefined;syncCtr.series[0].iterateAllEvents(function(event){if(event.timestamp>=syncMarks[0].start&&event.timestamp<=syncMarks[1].start){if(firstSyncEventTs===undefined)
 firstSyncEventTs=event.timestamp;var newEvent={'ts':(event.timestamp-firstSyncEventTs)/1000,'val':event.value};syncEvents.push(newEvent);}});var syncSamples=[];var syncNumSamples=Math.ceil(syncEvents[syncEvents.length-1].ts*this.sampleRate_);for(var i=1;i<syncEvents.length;i++){var sampleStartIdx=Math.ceil(syncEvents[i-1].ts*this.sampleRate_);var sampleEndIdx=Math.ceil(syncEvents[i].ts*this.sampleRate_);for(var j=sampleStartIdx;j<sampleEndIdx;j++){syncSamples[j]=syncEvents[i-1].val;}}
 var powerSamples=series.samples;if(powerSamples.length<syncSamples.length){this.model_.importWarning({type:'not_enough_samples',message:'Not enough power samples to correlate with sync signal.'});return undefined;}
 var maxShift=powerSamples.length-syncSamples.length;var minShift=0;var corrNumSamples=this.sampleRate_*5.0;if(powerSamples.length>corrNumSamples)
 minShift=powerSamples.length-corrNumSamples;var corr=[];for(var shift=minShift;shift<=maxShift;shift++){var corrSum=0;var powerAvg=0;for(var i=0;i<syncSamples.length;i++){corrSum+=(powerSamples[i+shift].power*syncSamples[i]);powerAvg+=powerSamples[i+shift].power;}
 powerAvg=powerAvg/syncSamples.length;corr.push(corrSum/powerAvg);}
 var corrPeakIdx=0;var corrPeak=0;for(var i=0;i<powerSamples.length;i++){if(corr[i]>corrPeak){corrPeak=corr[i];corrPeakIdx=i;}}
-var corrPeakTs=((minShift+corrPeakIdx)/this.sampleRate_);corrPeakTs*=1000;var syncStartTs=firstSyncEventTs-this.model_.bounds.min;var shiftTs=syncStartTs-corrPeakTs;return shiftTs;}};tr.importer.Importer.register(BattorImporter);return{BattorImporter:BattorImporter,_BattorImporterTestExports:TestExports};});!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});'use strict';if(tr.isHeadless){global.window={};}'use strict';if(tr.isHeadless){global.JSZip=global.window.JSZip;global.window=undefined;}'use strict';tr.exportTo('tr.e.importer.ddms',function(){var kPid=0;var kCategory='java';var kMethodLutEndMarker='\n*end\n';var kThreadsStart='\n*threads\n';var kMethodsStart='\n*methods\n';var kTraceMethodEnter=0x00;var kTraceMethodExit=0x01;var kTraceUnroll=0x02;var kTraceMethodActionMask=0x03;var kTraceHeaderLength=32;var kTraceMagicValue=0x574f4c53;var kTraceVersionSingleClock=2;var kTraceVersionDualClock=3;var kTraceRecordSizeSingleClock=10;var kTraceRecordSizeDualClock=14;function Reader(string_payload){this.position_=0;this.data_=JSZip.utils.transformTo('uint8array',string_payload);}
+var corrPeakTs=((minShift+corrPeakIdx)/this.sampleRate_);corrPeakTs*=1000;var syncStartTs=firstSyncEventTs-this.model_.bounds.min;var shiftTs=syncStartTs-corrPeakTs;return shiftTs;},explicitClockSync:function(){if(this.explicitSyncMark_===undefined)
+return undefined;var syncMarks=this.model.getClockSyncRecordsWithSyncId(this.explicitSyncMark_['id']);if(syncMarks.length!==1){this.model_.importWarning({type:'missing_sync_marker',message:'No single clock sync record found for explicit clock sync.'});return undefined;}
+var clockSync=syncMarks[0];var syncTs=clockSync.start;var traceTs=this.explicitSyncMark_['ts'];return syncTs-traceTs;},foundExplicitSyncMark:function(){return this.explicitSyncMark_!==undefined;}};tr.importer.Importer.register(BattorImporter);return{BattorImporter:BattorImporter,_BattorImporterTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.ddms',function(){var kPid=0;var kCategory='java';var kMethodLutEndMarker='\n*end\n';var kThreadsStart='\n*threads\n';var kMethodsStart='\n*methods\n';var kTraceMethodEnter=0x00;var kTraceMethodExit=0x01;var kTraceUnroll=0x02;var kTraceMethodActionMask=0x03;var kTraceHeaderLength=32;var kTraceMagicValue=0x574f4c53;var kTraceVersionSingleClock=2;var kTraceVersionDualClock=3;var kTraceRecordSizeSingleClock=10;var kTraceRecordSizeDualClock=14;function Reader(string_payload){this.position_=0;this.data_=JSZip.utils.transformTo('uint8array',string_payload);}
 Reader.prototype={__proto__:Object.prototype,uint8:function(){var result=this.data_[this.position_];this.position_+=1;return result;},uint16:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;return result;},uint32:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;result+=this.uint8()<<16;result+=this.uint8()<<24;return result;},uint64:function(){var low=this.uint32();var high=this.uint32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},seekTo:function(position){this.position_=position;},hasMore:function(){return this.position_<this.data_.length;}};function DdmsImporter(model,data){this.importPriority=3;this.model_=model;this.data_=data;}
 DdmsImporter.canImport=function(data){if(typeof(data)==='string'||data instanceof String){var header=data.slice(0,1000);return header.startsWith('*version\n')&&header.indexOf('\nvm=')>=0&&header.indexOf(kThreadsStart)>=0;}
-return false;};DdmsImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},importEvents:function(isSecondaryImport){var divider=this.data_.indexOf(kMethodLutEndMarker)+
+return false;};DdmsImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'DdmsImporter';},get model(){return this.model_;},importEvents:function(){var divider=this.data_.indexOf(kMethodLutEndMarker)+
 kMethodLutEndMarker.length;this.metadata_=this.data_.slice(0,divider);this.methods_={};this.parseThreads();this.parseMethods();var traceReader=new Reader(this.data_.slice(divider));var magic=traceReader.uint32();if(magic!=kTraceMagicValue){throw Error('Failed to match magic value');}
 this.version_=traceReader.uint16();if(this.version_!=kTraceVersionDualClock){throw Error('Unknown version');}
 var dataOffest=traceReader.uint16();var startDateTime=traceReader.uint64();var recordSize=traceReader.uint16();traceReader.seekTo(dataOffest);while(traceReader.hasMore()){this.parseTraceEntry(traceReader);}},parseTraceEntry:function(reader){var tid=reader.uint16();var methodPacked=reader.uint32();var cpuSinceStart=reader.uint32();var wallClockSinceStart=reader.uint32();var method=methodPacked&~kTraceMethodActionMask;var action=methodPacked&kTraceMethodActionMask;var thread=this.getTid(tid);method=this.getMethodName(method);if(action==kTraceMethodEnter){thread.sliceGroup.beginSlice(kCategory,method,wallClockSinceStart,undefined,cpuSinceStart);}else if(thread.sliceGroup.openSliceCount){thread.sliceGroup.endSlice(wallClockSinceStart,cpuSinceStart);}},parseThreads:function(){var threads=this.metadata_.slice(this.metadata_.indexOf(kThreadsStart)+
@@ -3785,7 +4793,7 @@
 function BinderParser(importer){Parser.call(this,importer);importer.registerEventHandler('binder_locked',BinderParser.prototype.binderLocked.bind(this));importer.registerEventHandler('binder_unlock',BinderParser.prototype.binderUnlock.bind(this));importer.registerEventHandler('binder_lock',BinderParser.prototype.binderLock.bind(this));importer.registerEventHandler('binder_transaction',BinderParser.prototype.binderTransaction.bind(this));importer.registerEventHandler('binder_transaction_received',BinderParser.prototype.binderTransactionReceived.bind(this));this.model_=importer.model;this.kthreadlookup={};this.importer_=importer;this.transWaitingRecv={};this.syncTransWaitingCompletion={};this.recursiveSyncTransWaitingCompletion_ByPID={};this.receivedTransWaitingConversion={};}
 BinderParser.prototype={__proto__:Parser.prototype,binderLock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventName.threadName);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);kthread.binderAttemptLockTS=ts;kthread.binderOpenTsA=ts;return true;},binderLocked:function(eventName,cpuNumber,pid,ts,eventBase){var binder_thread=isBinderThread(eventBase.threadName);var tgid,name;var as_slice;var need_push=false;var kthread,rthread;tgid=parseInt(eventBase.tgid);name=eventBase.threadName;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);this.doNameMappings(pid,tgid,name);rthread=kthread.thread;kthread.binderLockAquiredTS=ts;if(kthread.binderAttemptLockTS===undefined)
 return false;var args=this.generateArgsForSlice(tgid,pid,name,kthread);rthread.sliceGroup.pushCompleteSlice('binder','binder lock waiting',kthread.binderAttemptLockTS,ts-kthread.binderAttemptLockTS,0,0,args);kthread.binderAttemptLockTS=undefined;return true;},binderUnlock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);if(kthread.binderLockAquiredTS===undefined)
-return false;args=this.generateArgsForSlice(tgid,pid,eventBase.threadName,kthread);kthread.thread.sliceGroup.pushCompleteSlice('binder','binder lock held',kthread.binderLockAquiredTS,ts-kthread.binderLockAquiredTS,0,0,args);kthread.binderLockAquiredTS=undefined;return true;},binderTransaction:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransRE.exec(eventBase.details);if(event===undefined)
+return false;var args=this.generateArgsForSlice(tgid,pid,eventBase.threadName,kthread);kthread.thread.sliceGroup.pushCompleteSlice('binder','binder lock held',kthread.binderLockAquiredTS,ts-kthread.binderLockAquiredTS,0,0,args);kthread.binderLockAquiredTS=undefined;return true;},binderTransaction:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransRE.exec(eventBase.details);if(event===undefined)
 return false;var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventBase.threadName);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var trans=new BinderTransaction(event,pid,ts,kthread);var args=generateBinderArgsForSlice(trans,eventBase.threadName);var prior_receive=this.getPriorReceiveOnPID(pid);if(prior_receive!==false){return this.modelPriorReceive(prior_receive,ts,pid,tgid,kthread,trans,args,event);}
 var recursive_trans=this.getRecursiveTransactionNeedingCompletion(pid);if(recursive_trans!==false)
 return this.modelRecursiveTransactions(recursive_trans,ts,pid,kthread,trans,args);var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);slice.colorId=ColorScheme.getColorIdForGeneralPurposeString(ts.toString());trans.slice=slice;if(trans.expect_reply)
@@ -3926,26 +4934,34 @@
 kthread.openSliceTS=undefined;kthread.order=undefined;return true;},reclaimBegin:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimBeginRE.exec(eventBase.details);if(!event)
 return false;var order=parseInt(event[1]);var gfp=event[2];var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.openSliceTS=ts;kthread.order=order;kthread.gfp=gfp;return true;},reclaimEnd:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimEndRE.exec(eventBase.details);if(!event)
 return false;var nr_reclaimed=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS!==undefined){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim','direct reclaim',kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order,gfp:kthread.gfp,nr_reclaimed:nr_reclaimed});}
-kthread.openSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser:MemReclaimParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
+kthread.openSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser:MemReclaimParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency_limits',PowerParser.prototype.cpuFrequencyLimitsEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
 PowerParser.prototype={__proto__:Parser.prototype,cpuStateSlice:function(ts,targetCpuNumber,eventType,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter;if(eventType!='1'){this.importer.model.importWarning({type:'parse_error',message:'Don\'t understand power_start events of '+'type '+eventType});return;}
 powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
 powerCounter.series.forEach(function(series){series.addCounterSample(ts,cpuState);});},cpuIdleSlice:function(ts,targetCpuNumber,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name)));}
 var val=(cpuState!=4294967295?cpuState+1:0);powerCounter.series.forEach(function(series){series.addCounterSample(ts,val);});},cpuFrequencySlice:function(ts,targetCpuNumber,powerState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
-powerCounter.series.forEach(function(series){series.addCounterSample(ts,powerState);});},powerStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[3]);var cpuState=parseInt(event[2]);this.cpuStateSlice(ts,targetCpuNumber,event[1],cpuState);return true;},powerFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d+) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[3]);var powerState=parseInt(event[2]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[2]);var powerState=parseInt(event[1]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuIdleEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,powerState);});},cpuFrequencyLimitsSlice:function(ts,targetCpuNumber,minFreq,maxFreq){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency Limits');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('Min Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Min Frequency')));powerCounter.addSeries(new tr.model.CounterSeries('Max Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Max Frequency')));}
+powerCounter.series.forEach(function(series){if(series.name=='Min Frequency')
+series.addCounterSample(ts,minFreq);if(series.name=='Max Frequency')
+series.addCounterSample(ts,maxFreq);});},powerStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[3]);var cpuState=parseInt(event[2]);this.cpuStateSlice(ts,targetCpuNumber,event[1],cpuState);return true;},powerFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[3]);var powerState=parseInt(event[2]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[2]);var powerState=parseInt(event[1]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyLimitsEvent:function(eventName,cpu,pid,ts,eventBase){var event=/min=(\d+) max=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[3]);var minFreq=parseInt(event[1]);var maxFreq=parseInt(event[2]);this.cpuFrequencyLimitsSlice(ts,targetCpuNumber,minFreq,maxFreq);return true;},cpuIdleEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
 return false;var targetCpuNumber=parseInt(event[2]);var cpuState=parseInt(event[1]);this.cpuIdleSlice(ts,targetCpuNumber,cpuState);return true;}};Parser.register(PowerParser);return{PowerParser:PowerParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function RegulatorParser(importer){Parser.call(this,importer);importer.registerEventHandler('regulator_enable',RegulatorParser.prototype.regulatorEnableEvent.bind(this));importer.registerEventHandler('regulator_enable_delay',RegulatorParser.prototype.regulatorEnableDelayEvent.bind(this));importer.registerEventHandler('regulator_enable_complete',RegulatorParser.prototype.regulatorEnableCompleteEvent.bind(this));importer.registerEventHandler('regulator_disable',RegulatorParser.prototype.regulatorDisableEvent.bind(this));importer.registerEventHandler('regulator_disable_complete',RegulatorParser.prototype.regulatorDisableCompleteEvent.bind(this));importer.registerEventHandler('regulator_set_voltage',RegulatorParser.prototype.regulatorSetVoltageEvent.bind(this));importer.registerEventHandler('regulator_set_voltage_complete',RegulatorParser.prototype.regulatorSetVoltageCompleteEvent.bind(this));this.model_=importer.model_;}
 var regulatorEnableRE=/name=(.+)/;var regulatorDisableRE=/name=(.+)/;var regulatorSetVoltageCompleteRE=/name=(\S+), val=(\d+)/;RegulatorParser.prototype={__proto__:Parser.prototype,getCtr_:function(ctrName,valueName){var ctr=this.model_.kernel.getOrCreateCounter(null,'vreg '+ctrName+' '+valueName);if(ctr.series[0]===undefined){ctr.addSeries(new tr.model.CounterSeries(valueName,ColorScheme.getColorIdForGeneralPurposeString(ctrName+'.'+valueName)));}
 return ctr;},regulatorEnableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorEnableRE.exec(eventBase.details);if(!event)
 return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,1);return true;},regulatorEnableDelayEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorEnableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorDisableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorDisableRE.exec(eventBase.details);if(!event)
 return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,0);return true;},regulatorDisableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorSetVoltageCompleteRE.exec(eventBase.details);if(!event)
-return false;var name=event[1];var voltage=parseInt(event[2]);var ctr=this.getCtr_(name,'voltage');ctr.series[0].addCounterSample(ts,voltage);return true;}};Parser.register(RegulatorParser);return{RegulatorParser:RegulatorParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function SchedParser(importer){Parser.call(this,importer);importer.registerEventHandler('sched_switch',SchedParser.prototype.schedSwitchEvent.bind(this));importer.registerEventHandler('sched_wakeup',SchedParser.prototype.schedWakeupEvent.bind(this));}
-var TestExports={};var schedSwitchRE=new RegExp('prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) '+'prev_state=(\\S\\+?|\\S\\|\\S) ==> '+'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)');TestExports.schedSwitchRE=schedSwitchRE;var schedWakeupRE=/comm=(.+) pid=(\d+) prio=(\d+) success=(\d+) target_cpu=(\d+)/;TestExports.schedWakeupRE=schedWakeupRE;SchedParser.prototype={__proto__:Parser.prototype,schedSwitchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedSwitchRE.exec(eventBase.details);if(!event)
+return false;var name=event[1];var voltage=parseInt(event[2]);var ctr=this.getCtr_(name,'voltage');ctr.series[0].addCounterSample(ts,voltage);return true;}};Parser.register(RegulatorParser);return{RegulatorParser:RegulatorParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function SchedParser(importer){Parser.call(this,importer);importer.registerEventHandler('sched_switch',SchedParser.prototype.schedSwitchEvent.bind(this));importer.registerEventHandler('sched_wakeup',SchedParser.prototype.schedWakeupEvent.bind(this));importer.registerEventHandler('sched_blocked_reason',SchedParser.prototype.schedBlockedEvent.bind(this));importer.registerEventHandler('sched_cpu_hotplug',SchedParser.prototype.schedCpuHotplugEvent.bind(this));}
+var TestExports={};var schedSwitchRE=new RegExp('prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) '+'prev_state=(\\S\\+?|\\S\\|\\S) ==> '+'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)');var schedBlockedRE=new RegExp('pid=(\\d+) iowait=(\\d) caller=(.+)');TestExports.schedSwitchRE=schedSwitchRE;var schedWakeupRE=/comm=(.+) pid=(\d+) prio=(\d+) success=(\d+) target_cpu=(\d+)/;TestExports.schedWakeupRE=schedWakeupRE;SchedParser.prototype={__proto__:Parser.prototype,schedSwitchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedSwitchRE.exec(eventBase.details);if(!event)
 return false;var prevState=event[4];var nextComm=event[5];var nextPid=parseInt(event[6]);var nextPrio=parseInt(event[7]);var nextThread=this.importer.threadsByLinuxPid[nextPid];var nextName;if(nextThread)
 nextName=nextThread.userFriendlyName;else
 nextName=nextComm;var cpu=this.importer.getOrCreateCpu(cpuNumber);cpu.switchActiveThread(ts,{stateWhenDescheduled:prevState},nextPid,nextName,{comm:nextComm,tid:nextPid,prio:nextPrio});return true;},schedWakeupEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedWakeupRE.exec(eventBase.details);if(!event)
-return false;var fromPid=pid;var comm=event[1];var pid=parseInt(event[2]);var prio=parseInt(event[3]);this.importer.markPidRunnable(ts,pid,comm,prio,fromPid);return true;}};Parser.register(SchedParser);return{SchedParser:SchedParser,_SchedParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function SyncParser(importer){Parser.call(this,importer);importer.registerEventHandler('sync_timeline',SyncParser.prototype.timelineEvent.bind(this));importer.registerEventHandler('sync_wait',SyncParser.prototype.syncWaitEvent.bind(this));importer.registerEventHandler('sync_pt',SyncParser.prototype.syncPtEvent.bind(this));this.model_=importer.model_;}
+return false;var fromPid=pid;var comm=event[1];var pid=parseInt(event[2]);var prio=parseInt(event[3]);this.importer.markPidRunnable(ts,pid,comm,prio,fromPid);return true;},schedCpuHotplugEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/cpu (\d+) (.+) error=(\d+)/.exec(eventBase.details);if(!event)
+return false;var cpuNumber=event[1];var state=event[2];var targetCpu=this.importer.getOrCreateCpu(cpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Cpu Hotplug');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('State',tr.b.ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'State')));}
+powerCounter.series.forEach(function(series){if(series.name=='State')
+series.addCounterSample(ts,state.localeCompare('offline')?0:1);});return true;},schedBlockedEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedBlockedRE.exec(eventBase.details);if(!event)
+return false;var pid=parseInt(event[1]);var iowait=parseInt(event[2]);var caller=event[3];this.importer.addPidBlockedReason(ts,pid,iowait,caller);return true;}};Parser.register(SchedParser);return{SchedParser:SchedParser,_SchedParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function SyncParser(importer){Parser.call(this,importer);importer.registerEventHandler('sync_timeline',SyncParser.prototype.timelineEvent.bind(this));importer.registerEventHandler('sync_wait',SyncParser.prototype.syncWaitEvent.bind(this));importer.registerEventHandler('sync_pt',SyncParser.prototype.syncPtEvent.bind(this));this.model_=importer.model_;}
 var syncTimelineRE=/name=(\S+) value=(\S*)/;var syncWaitRE=/(\S+) name=(\S+) state=(\d+)/;var syncPtRE=/name=(\S+) value=(\S*)/;SyncParser.prototype={__proto__:Parser.prototype,timelineEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncTimelineRE.exec(eventBase.details);if(!event)
 return false;var thread=this.importer.getOrCreatePseudoThread(event[1]);if(thread.lastActiveTs!==undefined){var duration=ts-thread.lastActiveTs;var value=thread.lastActiveValue;if(value==undefined)
 value=' ';var slice=new tr.model.Slice('',value,ColorScheme.getColorIdForGeneralPurposeString(value),thread.lastActiveTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
@@ -3958,7 +4974,7 @@
 var workqueueExecuteStartRE=/work struct (.+): function (\S+)/;var workqueueExecuteEndRE=/work struct (.+)/;WorkqueueParser.prototype={__proto__:Parser.prototype,executeStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteStartRE.exec(eventBase.details);if(!event)
 return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);kthread.openSliceTS=ts;kthread.openSlice=event[2];return true;},executeEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteEndRE.exec(eventBase.details);if(!event)
 return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,{},ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
-kthread.openSlice=undefined;return true;},executeQueueWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;},executeActivateWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;}};Parser.register(WorkqueueParser);return{WorkqueueParser:WorkqueueParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ClockSyncRecord=tr.ClockSyncRecord;function LinuxPerfImporter(model,events){this.importPriority=2;this.model_=model;this.events_=events;this.newlyAddedClockSyncRecords_=[];this.wakeups_=[];this.kernelThreadStates_={};this.buildMapFromLinuxPidsToThreads();this.lines_=[];this.pseudoThreadCounter=1;this.parsers_=[];this.eventHandlers_={};}
+kthread.openSlice=undefined;return true;},executeQueueWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;},executeActivateWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;}};Parser.register(WorkqueueParser);return{WorkqueueParser:WorkqueueParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var InstantClockSyncRecord=tr.model.InstantClockSyncRecord;function FTraceImporter(model,events){this.importPriority=2;this.model_=model;this.events_=events;this.newlyAddedClockSyncRecords_=[];this.wakeups_=[];this.blocked_reasons_=[];this.kernelThreadStates_={};this.buildMapFromLinuxPidsToThreads_();this.lines_=[];this.pseudoThreadCounter=1;this.parsers_=[];this.eventHandlers_={};}
 var TestExports={};var lineREWithTGID=new RegExp('^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithTGID=function(line){var groups=lineREWithTGID.exec(line);if(!groups){return groups;}
 var tgid=groups[3];if(tgid[0]==='-')
 tgid=undefined;return{threadName:groups[1],pid:groups[2],tgid:tgid,cpuNumber:groups[4],timestamp:groups[5],eventName:groups[6],details:groups[7]};};TestExports.lineParserWithTGID=lineParserWithTGID;var lineREWithIRQInfo=new RegExp('^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithIRQInfo=function(line){var groups=lineREWithIRQInfo.exec(line);if(!groups){return groups;}
@@ -3967,13 +4983,13 @@
 return false;if(lineREWithTGID.test(line))
 return lineParserWithTGID;if(lineREWithIRQInfo.test(line))
 return lineParserWithIRQInfo;if(lineREWithLegacyFmt.test(line))
-return lineParserWithLegacyFmt;return null;};TestExports.autoDetectLineParser=autoDetectLineParser;LinuxPerfImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
-return false;if(LinuxPerfImporter._extractEventsFromSystraceHTML(events,false).ok)
-return true;if(LinuxPerfImporter._extractEventsFromSystraceMultiHTML(events,false).ok)
+return lineParserWithLegacyFmt;return undefined;};TestExports.autoDetectLineParser=autoDetectLineParser;FTraceImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
+return false;if(FTraceImporter._extractEventsFromSystraceHTML(events,false).ok)
+return true;if(FTraceImporter._extractEventsFromSystraceMultiHTML(events,false).ok)
 return true;if(/^# tracer:/.test(events))
 return true;var lineBreakIndex=events.indexOf('\n');if(lineBreakIndex>-1)
 events=events.substring(0,lineBreakIndex);if(autoDetectLineParser(events))
-return true;return false;};LinuxPerfImporter._extractEventsFromSystraceHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
+return true;return false;};FTraceImporter._extractEventsFromSystraceHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
 produce_result=true;if(/^<!DOCTYPE html>/.test(incoming_events)==false)
 return failure;var r=new tr.importer.SimpleLineReader(incoming_events);if(!r.advanceToLineMatching(/^  <script>$/))
 return failure;if(!r.advanceToLineMatching(/^  var linuxPerfData = "\\$/))
@@ -3985,176 +5001,54 @@
 return str;return str.substring(str,str.length-suffix.length);}
 var events=[];if(produce_result){for(var i=0;i<raw_events.length;i++){var event=raw_events[i];event=stripSuffix(event,'\\n\\');events.push(event);}}else{events=[raw_events[raw_events.length-1]];}
 var oldLastEvent=events[events.length-1];var newLastEvent=stripSuffix(oldLastEvent,'\\n";');if(newLastEvent==oldLastEvent)
-return failure;events[events.length-1]=newLastEvent;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};LinuxPerfImporter._extractEventsFromSystraceMultiHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
+return failure;events[events.length-1]=newLastEvent;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};FTraceImporter._extractEventsFromSystraceMultiHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
 produce_result=true;if(new RegExp('^<!DOCTYPE HTML>','i').test(incoming_events)==false)
 return failure;var r=new tr.importer.SimpleLineReader(incoming_events);var events=[];while(!/^# tracer:/.test(events)){if(!r.advanceToLineMatching(/^  <script class="trace-data" type="application\/text">$/))
 return failure;var events_begin_at_line=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))
 return failure;events=r.endSavingLinesAndGetResult();events=events.slice(1,events.length-1);}
 if(!r.advanceToLineMatching(/^<\/body>$/))
 return failure;if(!r.advanceToLineMatching(/^<\/html>$/))
-return failure;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};LinuxPerfImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},buildMapFromLinuxPidsToThreads:function(){this.threadsByLinuxPid={};this.model_.getAllThreads().forEach(function(thread){this.threadsByLinuxPid[thread.tid]=thread;}.bind(this));},getOrCreateCpu:function(cpuNumber){return this.model_.kernel.getOrCreateCpu(cpuNumber);},getOrCreateKernelThread:function(kernelThreadName,pid,tid){if(!this.kernelThreadStates_[kernelThreadName]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[kernelThreadName]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
+return failure;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};FTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'FTraceImporter';},get model(){return this.model_;},importEvents:function(){this.parsers_=this.createParsers_();this.registerDefaultHandlers_();this.parseLines_();this.importClockSyncRecords_();var modelTimeTransformer=this.getModelTimeTransformer_();if(modelTimeTransformer===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot import kernel trace without a clock sync.'});return;}
+this.shiftNewlyAddedClockSyncRecords_(modelTimeTransformer);this.importCpuData_(modelTimeTransformer);this.buildMapFromLinuxPidsToThreads_();this.buildPerThreadCpuSlicesFromCpuState_();},registerEventHandler:function(eventName,handler){this.eventHandlers_[eventName]=handler;},getOrCreateCpu:function(cpuNumber){return this.model_.kernel.getOrCreateCpu(cpuNumber);},getOrCreateKernelThread:function(kernelThreadName,pid,tid){if(!this.kernelThreadStates_[kernelThreadName]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[kernelThreadName]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
 return this.kernelThreadStates_[kernelThreadName];},getOrCreateBinderKernelThread:function(kernelThreadName,pid,tid){var key=kernelThreadName+pid+tid;if(!this.kernelThreadStates_[key]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[key]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
 return this.kernelThreadStates_[key];},getOrCreatePseudoThread:function(threadName){var thread=this.kernelThreadStates_[threadName];if(!thread){thread=this.getOrCreateKernelThread(threadName,pseudoKernelPID,this.pseudoThreadCounter);this.pseudoThreadCounter++;}
-return thread;},importEvents:function(isSecondaryImport){this.parsers_=this.createParsers_();this.registerDefaultHandlers_();this.parseLines();this.importClockSyncRecords();var timeShift=this.computeTimeTransform();if(timeShift===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot import kernel trace without a clock sync.'});return;}
-this.shiftNewlyAddedClockSyncRecords(timeShift);this.importCpuData(timeShift);this.buildMapFromLinuxPidsToThreads();this.buildPerThreadCpuSlicesFromCpuState();this.computeCpuTimestampsForSlicesAsNeeded();},buildPerThreadCpuSlicesFromCpuState:function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;for(var cpuNumber in this.model_.kernel.cpus){var cpu=this.model_.kernel.cpus[cpuNumber];for(var i=0;i<cpu.slices.length;i++){var cpuSlice=cpu.slices[i];var thread=this.threadsByLinuxPid[cpuSlice.args.tid];if(!thread)
+return thread;},markPidRunnable:function(ts,pid,comm,prio,fromPid){this.wakeups_.push({ts:ts,tid:pid,fromTid:fromPid});},addPidBlockedReason:function(ts,pid,iowait,caller){this.blocked_reasons_.push({ts:ts,tid:pid,iowait:iowait,caller:caller});},buildMapFromLinuxPidsToThreads_:function(){this.threadsByLinuxPid={};this.model_.getAllThreads().forEach(function(thread){this.threadsByLinuxPid[thread.tid]=thread;}.bind(this));},buildPerThreadCpuSlicesFromCpuState_:function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;for(var cpuNumber in this.model_.kernel.cpus){var cpu=this.model_.kernel.cpus[cpuNumber];for(var i=0;i<cpu.slices.length;i++){var cpuSlice=cpu.slices[i];var thread=this.threadsByLinuxPid[cpuSlice.args.tid];if(!thread)
 continue;cpuSlice.threadThatWasRunning=thread;if(!thread.tempCpuSlices)
 thread.tempCpuSlices=[];thread.tempCpuSlices.push(cpuSlice);}}
 for(var i in this.wakeups_){var wakeup=this.wakeups_[i];var thread=this.threadsByLinuxPid[wakeup.tid];if(!thread)
 continue;thread.tempWakeups=thread.tempWakeups||[];thread.tempWakeups.push(wakeup);}
+for(var i in this.blocked_reasons_){var reason=this.blocked_reasons_[i];var thread=this.threadsByLinuxPid[reason.tid];if(!thread)
+continue;thread.tempBlockedReasons=thread.tempBlockedReasons||[];thread.tempBlockedReasons.push(reason);}
 this.model_.getAllThreads().forEach(function(thread){if(thread.tempCpuSlices===undefined)
-return;var origSlices=thread.tempCpuSlices;delete thread.tempCpuSlices;origSlices.sort(function(x,y){return x.start-y.start;});var wakeups=thread.tempWakeups||[];delete thread.tempWakeups;wakeups.sort(function(x,y){return x.ts-y.ts;});var slices=[];if(origSlices.length){var slice=origSlices[0];if(wakeups.length&&wakeups[0].ts<slice.start){var wakeup=wakeups.shift();var wakeupDuration=slice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));}
+return;var origSlices=thread.tempCpuSlices;delete thread.tempCpuSlices;origSlices.sort(function(x,y){return x.start-y.start;});var wakeups=thread.tempWakeups||[];delete thread.tempWakeups;wakeups.sort(function(x,y){return x.ts-y.ts;});var reasons=thread.tempBlockedReasons||[];delete thread.tempBlockedReasons;reasons.sort(function(x,y){return x.ts-y.ts;});var slices=[];if(origSlices.length){var slice=origSlices[0];if(wakeups.length&&wakeups[0].ts<slice.start){var wakeup=wakeups.shift();var wakeupDuration=slice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));}
 var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',slice.start,{},slice.duration);runningSlice.cpuOnWhichThreadWasRunning=slice.cpu;slices.push(runningSlice);}
 var wakeup=undefined;for(var i=1;i<origSlices.length;i++){var prevSlice=origSlices[i-1];var nextSlice=origSlices[i];var midDuration=nextSlice.start-prevSlice.end;while(wakeups.length&&wakeups[0].ts<nextSlice.start){var w=wakeups.shift();if(wakeup===undefined&&w.ts>prevSlice.end){wakeup=w;}}
+var blocked_reason=undefined;while(reasons.length&&reasons[0].ts<prevSlice.end){var r=reasons.shift();}
+if(wakeup!==undefined&&reasons.length&&reasons[0].ts<wakeup.ts){blocked_reason=reasons.shift();}
 var pushSleep=function(state){if(wakeup!==undefined){midDuration=wakeup.ts-prevSlice.end;}
-slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,{},midDuration));if(wakeup!==undefined){var wakeupDuration=nextSlice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));wakeup=undefined;}};if(prevSlice.args.stateWhenDescheduled=='S'){pushSleep(SCHEDULING_STATE.SLEEPING);}else if(prevSlice.args.stateWhenDescheduled=='R'||prevSlice.args.stateWhenDescheduled=='R+'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP);}else if(prevSlice.args.stateWhenDescheduled=='T'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.STOPPED,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='t'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.DEBUG,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='Z'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.ZOMBIE,'',ioWaitId,prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='X'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.EXIT_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='x'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.TASK_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='K'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKE_KILL,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='W'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKING,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D|K'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL);}else if(prevSlice.args.stateWhenDescheduled=='D|W'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING);}else{slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.UNKNOWN,'',prevSlice.end,{},midDuration));this.model_.importWarning({type:'parse_error',message:'Unrecognized sleep state: '+
+if(blocked_reason!==undefined){var args={'kernel callsite when blocked:':blocked_reason.caller};if(blocked_reason.iowait){switch(state){case SCHEDULING_STATE.UNINTR_SLEEP:state=SCHEDULING_STATE.UNINTR_SLEEP_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;default:}}
+slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,args,midDuration));}else{slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,{},midDuration));}
+if(wakeup!==undefined){var wakeupDuration=nextSlice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));wakeup=undefined;}};if(prevSlice.args.stateWhenDescheduled=='S'){pushSleep(SCHEDULING_STATE.SLEEPING);}else if(prevSlice.args.stateWhenDescheduled=='R'||prevSlice.args.stateWhenDescheduled=='R+'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP);}else if(prevSlice.args.stateWhenDescheduled=='T'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.STOPPED,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='t'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.DEBUG,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='Z'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.ZOMBIE,'',ioWaitId,prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='X'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.EXIT_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='x'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.TASK_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='K'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKE_KILL,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='W'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKING,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D|K'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL);}else if(prevSlice.args.stateWhenDescheduled=='D|W'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING);}else{slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.UNKNOWN,'',prevSlice.end,{},midDuration));this.model_.importWarning({type:'parse_error',message:'Unrecognized sleep state: '+
 prevSlice.args.stateWhenDescheduled});}
 var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',nextSlice.start,{},nextSlice.duration);runningSlice.cpuOnWhichThreadWasRunning=prevSlice.cpu;slices.push(runningSlice);}
-thread.timeSlices=slices;},this);},computeCpuTimestampsForSlicesAsNeeded:function(){},computeTimeTransform:function(){var isSecondaryImport=this.model.getClockSyncRecordsNamed('ftrace_importer').length!==0;var mSyncs=this.model_.getClockSyncRecordsNamed('monotonic');if(mSyncs.length==0)
-return isSecondaryImport?undefined:0;var sync=mSyncs[0].args;if(sync.parentTS==0||sync.parentTS==sync.perfTS)
-return 0;return sync.parentTS-sync.perfTS;},createParsers_:function(){var allTypeInfos=tr.e.importer.linux_perf.Parser.getAllRegisteredTypeInfos();var parsers=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);return parsers;},registerDefaultHandlers_:function(){this.registerEventHandler('tracing_mark_write',LinuxPerfImporter.prototype.traceMarkingWriteEvent.bind(this));this.registerEventHandler('0',LinuxPerfImporter.prototype.traceMarkingWriteEvent.bind(this));this.registerEventHandler('tracing_mark_write:trace_event_clock_sync',function(){return true;});this.registerEventHandler('0:trace_event_clock_sync',function(){return true;});},registerEventHandler:function(eventName,handler){this.eventHandlers_[eventName]=handler;},markPidRunnable:function(ts,pid,comm,prio,fromPid){this.wakeups_.push({ts:ts,tid:pid,fromTid:fromPid});},traceClockSyncEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/name=(\w+?)\s(.+)/.exec(eventBase.details);if(event){var name=event[1];var pieces=event[2].split(' ');var args={perfTS:ts};for(var i=0;i<pieces.length;i++){var parts=pieces[i].split('=');if(parts.length!=2)
+thread.timeSlices=slices;},this);},getModelTimeTransformer_:function(){var isAttachedToChromeTrace=this.model.getClockSyncRecordsWithSyncId('ftrace_importer').length!==0;var monotonicSyncs=this.model_.getClockSyncRecordsWithSyncId('monotonic');if(monotonicSyncs.length==0)
+return isAttachedToChromeTrace?undefined:tr.b.identity;var sync=monotonicSyncs[0].args;if(sync.parentTS===0)
+return tr.b.identity;return function(ts){return ts+sync.parentTS-sync.perfTS;};},createParsers_:function(){var allTypeInfos=tr.e.importer.linux_perf.Parser.getAllRegisteredTypeInfos();var parsers=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);return parsers;},registerDefaultHandlers_:function(){this.registerEventHandler('tracing_mark_write',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('0',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('tracing_mark_write:trace_event_clock_sync',function(){return true;});this.registerEventHandler('0:trace_event_clock_sync',function(){return true;});},traceClockSyncEvent_:function(eventName,cpuNumber,pid,ts,eventBase){var event=/name=(\w+?)\s(.+)/.exec(eventBase.details);if(event){var name=event[1];var pieces=event[2].split(' ');var args={perfTS:ts};for(var i=0;i<pieces.length;i++){var parts=pieces[i].split('=');if(parts.length!=2)
 throw new Error('omgbbq');args[parts[0]]=parts[1];}
-this.addClockSyncRecord(new ClockSyncRecord(name,ts,args));return true;}
+this.addClockSyncRecord_(new InstantClockSyncRecord(name,ts,args));return true;}
 event=/parent_ts=(\d+\.?\d*)/.exec(eventBase.details);if(!event)
-return false;this.addClockSyncRecord(new ClockSyncRecord('monotonic',ts,{perfTS:ts,parentTS:event[1]*1000}));return true;},traceMarkingWriteEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){eventBase.details=eventBase.details.replace(/\\n.*$/,'');var event=/^\s*(\w+):\s*(.*)$/.exec(eventBase.details);if(!event){var tag=eventBase.details.substring(0,2);if(tag=='B|'||tag=='E'||tag=='E|'||tag=='X|'||tag=='C|'||tag=='S|'||tag=='F|'){eventBase.subEventName='android';}else{return false;}}else{eventBase.subEventName=event[1];eventBase.details=event[2];}
+return false;this.addClockSyncRecord_(new InstantClockSyncRecord('monotonic',ts,{perfTS:ts,parentTS:event[1]*1000}));return true;},traceMarkingWriteEvent_:function(eventName,cpuNumber,pid,ts,eventBase,threadName){eventBase.details=eventBase.details.replace(/\\n.*$/,'');var event=/^\s*(\w+):\s*(.*)$/.exec(eventBase.details);if(!event){var tag=eventBase.details.substring(0,2);if(tag=='B|'||tag=='E'||tag=='E|'||tag=='X|'||tag=='C|'||tag=='S|'||tag=='F|'){eventBase.subEventName='android';}else{return false;}}else{eventBase.subEventName=event[1];eventBase.details=event[2];}
 var writeEventName=eventName+':'+eventBase.subEventName;var handler=this.eventHandlers_[writeEventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown trace_marking_write event '+writeEventName});return true;}
-return handler(writeEventName,cpuNumber,pid,ts,eventBase,threadName);},importClockSyncRecords:function(){this.forEachLine(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;if(eventName!=='tracing_mark_write'&&eventName!=='0')
+return handler(writeEventName,cpuNumber,pid,ts,eventBase,threadName);},importClockSyncRecords_:function(){this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;if(eventName!=='tracing_mark_write'&&eventName!=='0')
 return;if(traceEventClockSyncRE.exec(eventBase.details))
-this.traceClockSyncEvent(eventName,cpuNumber,pid,ts,eventBase);if(realTimeClockSyncRE.exec(eventBase.details)){var match=realTimeClockSyncRE.exec(eventBase.details);this.model_.realtime_to_monotonic_offset_ms=ts-match[1];}
+this.traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase);if(realTimeClockSyncRE.exec(eventBase.details)){var match=realTimeClockSyncRE.exec(eventBase.details);this.model_.realtime_to_monotonic_offset_ms=ts-match[1];}
 if(genericClockSyncRE.exec(eventBase.details))
-this.traceClockSyncEvent(eventName,cpuNumber,pid,ts,eventBase);}.bind(this));},addClockSyncRecord:function(csr){this.newlyAddedClockSyncRecords_.push(csr);this.model_.clockSyncRecords.push(csr);},shiftNewlyAddedClockSyncRecords:function(timeShift){this.newlyAddedClockSyncRecords_.forEach(function(csr){csr.ts+=timeShift;});},importCpuData:function(timeShift){this.forEachLine(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;var handler=this.eventHandlers_[eventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown event '+eventName+' ('+text+')'});return;}
-ts+=timeShift;if(!handler(eventName,cpuNumber,pid,ts,eventBase)){this.model_.importWarning({type:'parse_error',message:'Malformed '+eventName+' event ('+text+')'});}}.bind(this));},parseLines:function(){var lines=[];var extractResult=LinuxPerfImporter._extractEventsFromSystraceHTML(this.events_,true);if(!extractResult.ok)
-extractResult=LinuxPerfImporter._extractEventsFromSystraceMultiHTML(this.events_,true);var lines=extractResult.ok?extractResult.lines:this.events_.split('\n');var lineParser=null;for(var lineNumber=0;lineNumber<lines.length;++lineNumber){var line=lines[lineNumber].trim();if(line.length==0||/^#/.test(line))
-continue;if(lineParser==null){lineParser=autoDetectLineParser(line);if(lineParser==null){this.model_.importWarning({type:'parse_error',message:'Cannot parse line: '+line});continue;}}
+this.traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase);}.bind(this));},addClockSyncRecord_:function(csr){this.newlyAddedClockSyncRecords_.push(csr);this.model_.clockSyncRecords.push(csr);},shiftNewlyAddedClockSyncRecords_:function(modelTimeTransformer){this.newlyAddedClockSyncRecords_.forEach(function(csr){csr.start=modelTimeTransformer(csr.start);});},importCpuData_:function(modelTimeTransformer){this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;var handler=this.eventHandlers_[eventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown event '+eventName+' ('+text+')'});return;}
+ts=modelTimeTransformer(ts);if(!handler(eventName,cpuNumber,pid,ts,eventBase)){this.model_.importWarning({type:'parse_error',message:'Malformed '+eventName+' event ('+text+')'});}}.bind(this));},parseLines_:function(){var lines=[];var extractResult=FTraceImporter._extractEventsFromSystraceHTML(this.events_,true);if(!extractResult.ok)
+extractResult=FTraceImporter._extractEventsFromSystraceMultiHTML(this.events_,true);var lines=extractResult.ok?extractResult.lines:this.events_.split('\n');var lineParser=undefined;for(var lineNumber=0;lineNumber<lines.length;++lineNumber){var line=lines[lineNumber].trim();if(line.length==0||/^#/.test(line))
+continue;if(!lineParser){lineParser=autoDetectLineParser(line);if(!lineParser){this.model_.importWarning({type:'parse_error',message:'Cannot parse line: '+line});continue;}}
 var eventBase=lineParser(line);if(!eventBase){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});continue;}
-this.lines_.push([line,eventBase,parseInt(eventBase.cpuNumber),parseInt(eventBase.pid),parseFloat(eventBase.timestamp)*1000]);}},forEachLine:function(handler){for(var i=0;i<this.lines_.length;++i){var line=this.lines_[i];handler.apply(this,line);}}};tr.importer.Importer.register(LinuxPerfImporter);return{LinuxPerfImporter:LinuxPerfImporter,_LinuxPerfImporterTestExports:TestExports};});'use strict';tr.exportTo('tr.b.u',function(){function TimeDuration(duration){tr.b.u.Scalar.call(this,duration,tr.b.u.Units.timeDurationInMs);};TimeDuration.prototype={__proto__:tr.b.u.Scalar.prototype,get duration(){return this.value;}};TimeDuration.format=function(duration){return tr.b.u.Units.timeDurationInMs.format(duration);};return{TimeDuration:TimeDuration};});'use strict';tr.exportTo('tr.b',function(){function convertEventsToRanges(events){return events.map(function(event){return tr.b.Range.fromExplicitRange(event.start,event.end);});}
-function mergeRanges(inRanges,mergeThreshold,mergeFunction){var remainingEvents=inRanges.slice();remainingEvents.sort(function(x,y){return x.min-y.min;});if(remainingEvents.length<=1){var merged=[];if(remainingEvents.length==1){merged.push(mergeFunction(remainingEvents));}
-return merged;}
-var mergedEvents=[];var currentMergeBuffer=[];var rightEdge;function beginMerging(){currentMergeBuffer.push(remainingEvents[0]);remainingEvents.splice(0,1);rightEdge=currentMergeBuffer[0].max;}
-function flushCurrentMergeBuffer(){if(currentMergeBuffer.length==0)
-return;mergedEvents.push(mergeFunction(currentMergeBuffer));currentMergeBuffer=[];if(remainingEvents.length!=0)
-beginMerging();}
-beginMerging();while(remainingEvents.length){var currentEvent=remainingEvents[0];var distanceFromRightEdge=currentEvent.min-rightEdge;if(distanceFromRightEdge<mergeThreshold){rightEdge=Math.max(rightEdge,currentEvent.max);remainingEvents.splice(0,1);currentMergeBuffer.push(currentEvent);continue;}
-flushCurrentMergeBuffer();}
-flushCurrentMergeBuffer();return mergedEvents;}
-function findEmptyRangesBetweenRanges(inRanges,opt_totalRange){if(opt_totalRange&&opt_totalRange.isEmpty)
-opt_totalRange=undefined;var emptyRanges=[];if(!inRanges.length){if(opt_totalRange)
-emptyRanges.push(opt_totalRange);return emptyRanges;}
-inRanges=inRanges.slice();inRanges.sort(function(x,y){return x.min-y.min;});if(opt_totalRange&&(opt_totalRange.min<inRanges[0].min)){emptyRanges.push(tr.b.Range.fromExplicitRange(opt_totalRange.min,inRanges[0].min));}
-inRanges.forEach(function(range,index){for(var otherIndex=0;otherIndex<inRanges.length;++otherIndex){if(index===otherIndex)
-continue;var other=inRanges[otherIndex];if(other.min>range.max){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,other.min));return;}
-if(other.max>range.max){return;}}
-if(opt_totalRange&&(range.max<opt_totalRange.max)){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,opt_totalRange.max));}});return emptyRanges;}
-return{convertEventsToRanges:convertEventsToRanges,findEmptyRangesBetweenRanges:findEmptyRangesBetweenRanges,mergeRanges:mergeRanges};});'use strict';tr.exportTo('tr.e.audits',function(){var Frame=tr.model.Frame;var Statistics=tr.b.Statistics;var UI_DRAW_TYPE={NONE:'none',LEGACY:'legacy',MARSHMALLOW:'marshmallow'};var UI_THREAD_DRAW_NAMES={'performTraversals':UI_DRAW_TYPE.LEGACY,'Choreographer#doFrame':UI_DRAW_TYPE.MARSHMALLOW};var RENDER_THREAD_DRAW_NAME='DrawFrame';var RENDER_THREAD_INDEP_DRAW_NAME='doFrame';var THREAD_SYNC_NAME='syncFrameState';function getSlicesForThreadTimeRanges(threadTimeRanges){var ret=[];threadTimeRanges.forEach(function(threadTimeRange){var slices=[];threadTimeRange.thread.sliceGroup.iterSlicesInTimeRange(function(slice){slices.push(slice);},threadTimeRange.start,threadTimeRange.end);ret.push.apply(ret,slices);});return ret;}
-function makeFrame(threadTimeRanges,surfaceFlinger){var args={};if(surfaceFlinger&&surfaceFlinger.hasVsyncs){var start=Statistics.min(threadTimeRanges,function(threadTimeRanges){return threadTimeRanges.start;});args['deadline']=surfaceFlinger.getFrameDeadline(start);args['frameKickoff']=surfaceFlinger.getFrameKickoff(start);}
-var events=getSlicesForThreadTimeRanges(threadTimeRanges);return new Frame(events,threadTimeRanges,args);}
-function findOverlappingDrawFrame(renderThread,time){if(!renderThread)
-return undefined;var slices=renderThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){var slice=slices[i];if(slice.title==RENDER_THREAD_DRAW_NAME&&slice.start<=time&&time<=slice.end){return slice;}}
-return undefined;}
-function getPreTraversalWorkRanges(uiThread){if(!uiThread)
-return[];var preFrameEvents=[];uiThread.sliceGroup.slices.forEach(function(slice){if(slice.title=='obtainView'||slice.title=='setupListItem'||slice.title=='deliverInputEvent'||slice.title=='RV Scroll')
-preFrameEvents.push(slice);});uiThread.asyncSliceGroup.slices.forEach(function(slice){if(slice.title=='deliverInputEvent')
-preFrameEvents.push(slice);});return tr.b.mergeRanges(tr.b.convertEventsToRanges(preFrameEvents),3,function(events){return{start:events[0].min,end:events[events.length-1].max};});}
-function getFrameStartTime(traversalStart,preTraversalWorkRanges){var preTraversalWorkRange=tr.b.findClosestIntervalInSortedIntervals(preTraversalWorkRanges,function(range){return range.start},function(range){return range.end},traversalStart,3);if(preTraversalWorkRange)
-return preTraversalWorkRange.start;return traversalStart;}
-function getUiThreadDrivenFrames(app){if(!app.uiThread)
-return[];var preTraversalWorkRanges=[];if(app.uiDrawType==UI_DRAW_TYPE.LEGACY)
-preTraversalWorkRanges=getPreTraversalWorkRanges(app.uiThread);var frames=[];app.uiThread.sliceGroup.slices.forEach(function(slice){if(!(slice.title in UI_THREAD_DRAW_NAMES)){return;}
-var threadTimeRanges=[];var uiThreadTimeRange={thread:app.uiThread,start:getFrameStartTime(slice.start,preTraversalWorkRanges),end:slice.end};threadTimeRanges.push(uiThreadTimeRange);var rtDrawSlice=findOverlappingDrawFrame(app.renderThread,slice.end);if(rtDrawSlice){var rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice){uiThreadTimeRange.end=Math.min(uiThreadTimeRange.end,rtSyncSlice.start);}
-threadTimeRanges.push({thread:app.renderThread,start:rtDrawSlice.start,end:rtDrawSlice.end});}
-frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
-function getRenderThreadDrivenFrames(app){if(!app.renderThread)
-return[];var frames=[];app.renderThread.sliceGroup.getSlicesOfName(RENDER_THREAD_INDEP_DRAW_NAME).forEach(function(slice){var threadTimeRanges=[{thread:app.renderThread,start:slice.start,end:slice.end}];frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
-function getUiDrawType(uiThread){if(!uiThread)
-return UI_DRAW_TYPE.NONE;var slices=uiThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){if(slices[i].title in UI_THREAD_DRAW_NAMES){return UI_THREAD_DRAW_NAMES[slices[i].title];}}
-return UI_DRAW_TYPE.NONE;}
-function getInputSamples(process){var samples=undefined;for(var counterName in process.counters){if(/^android\.aq\:pending/.test(counterName)&&process.counters[counterName].numSeries==1){samples=process.counters[counterName].series[0].samples;break;}}
-if(!samples)
-return[];var inputSamples=[];var lastValue=0;samples.forEach(function(sample){if(sample.value>lastValue){inputSamples.push(sample);}
-lastValue=sample.value;});return inputSamples;}
-function getAnimationAsyncSlices(uiThread){if(!uiThread)
-return[];var slices=[];uiThread.asyncSliceGroup.iterateAllEvents(function(slice){if(/^animator\:/.test(slice.title))
-slices.push(slice);});return slices;}
-function AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType){this.process=process;this.uiThread=uiThread;this.renderThread=renderThread;this.surfaceFlinger=surfaceFlinger;this.uiDrawType=uiDrawType;this.frames_=undefined;this.inputs_=undefined;};AndroidApp.createForProcessIfPossible=function(process,surfaceFlinger){var uiThread=process.getThread(process.pid);var uiDrawType=getUiDrawType(uiThread);if(uiDrawType==UI_DRAW_TYPE.NONE){uiThread=undefined;}
-var renderThreads=process.findAllThreadsNamed('RenderThread');var renderThread=renderThreads.length==1?renderThreads[0]:undefined;if(uiThread||renderThread){return new AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType);}}
-AndroidApp.prototype={getFrames:function(){if(!this.frames_){var uiFrames=getUiThreadDrivenFrames(this);var rtFrames=getRenderThreadDrivenFrames(this);this.frames_=uiFrames.concat(rtFrames);this.frames_.sort(function(a,b){a.end-b.end});}
-return this.frames_;},getInputSamples:function(){if(!this.inputs_){this.inputs_=getInputSamples(this.process);}
-return this.inputs_;},getAnimationAsyncSlices:function(){if(!this.animations_){this.animations_=getAnimationAsyncSlices(this.uiThread);}
-return this.animations_;}};return{AndroidApp:AndroidApp};});'use strict';tr.exportTo('tr.e.audits',function(){var findLowIndexInSortedArray=tr.b.findLowIndexInSortedArray;var VSYNC_SF_NAME='android.VSYNC-sf';var VSYNC_APP_NAME='android.VSYNC-app';var VSYNC_FALLBACK_NAME='android.VSYNC';var TIMESTAMP_FUDGE_MS=0.01;function getVsyncTimestamps(process,counterName){var vsync=process.counters[counterName];if(!vsync)
-vsync=process.counters[VSYNC_FALLBACK_NAME];if(vsync&&vsync.numSeries==1&&vsync.numSamples>1)
-return vsync.series[0].timestamps;return undefined;}
-function AndroidSurfaceFlinger(process,thread){this.process=process;this.thread=thread;this.appVsync_=undefined;this.sfVsync_=undefined;this.appVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_APP_NAME);this.sfVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_SF_NAME);};AndroidSurfaceFlinger.createForProcessIfPossible=function(process){var mainThread=process.getThread(process.pid);if(mainThread&&mainThread.name&&/surfaceflinger/.test(mainThread.name))
-return new AndroidSurfaceFlinger(process,mainThread);var primaryThreads=process.findAllThreadsNamed('SurfaceFlinger');if(primaryThreads.length==1)
-return new AndroidSurfaceFlinger(process,primaryThreads[0]);return undefined;};AndroidSurfaceFlinger.prototype={get hasVsyncs(){return!!this.appVsyncTimestamps_&&!!this.sfVsyncTimestamps_;},getFrameKickoff:function(timestamp){if(!this.hasVsyncs)
-throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.appVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex<1)
-return undefined;return this.appVsyncTimestamps_[firstGreaterIndex-1];},getFrameDeadline:function(timestamp){if(!this.hasVsyncs)
-throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.sfVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex>=this.sfVsyncTimestamps_.length)
-return undefined;return this.sfVsyncTimestamps_[firstGreaterIndex];}};return{AndroidSurfaceFlinger:AndroidSurfaceFlinger};});'use strict';tr.exportTo('tr.e.audits',function(){var AndroidApp=tr.e.audits.AndroidApp;var AndroidSurfaceFlinger=tr.e.audits.AndroidSurfaceFlinger;var IMPORTANT_SURFACE_FLINGER_SLICES={'doComposition':true,'updateTexImage':true,'postFramebuffer':true};var IMPORTANT_UI_THREAD_SLICES={'Choreographer#doFrame':true,'performTraversals':true,'deliverInputEvent':true};var IMPORTANT_RENDER_THREAD_SLICES={'doFrame':true};function iterateImportantThreadSlices(thread,important,callback){if(!thread)
-return;thread.sliceGroup.slices.forEach(function(slice){if(slice.title in important)
-callback(slice);});}
-function AndroidModelHelper(model){this.model=model;this.apps=[];this.surfaceFlinger=undefined;var processes=model.getAllProcesses();for(var i=0;i<processes.length&&!this.surfaceFlinger;i++){this.surfaceFlinger=AndroidSurfaceFlinger.createForProcessIfPossible(processes[i]);}
-model.getAllProcesses().forEach(function(process){var app=AndroidApp.createForProcessIfPossible(process,this.surfaceFlinger);if(app)
-this.apps.push(app);},this);};AndroidModelHelper.prototype={iterateImportantSlices:function(callback){if(this.surfaceFlinger){iterateImportantThreadSlices(this.surfaceFlinger.thread,IMPORTANT_SURFACE_FLINGER_SLICES,callback);}
-this.apps.forEach(function(app){iterateImportantThreadSlices(app.uiThread,IMPORTANT_UI_THREAD_SLICES,callback);iterateImportantThreadSlices(app.renderThread,IMPORTANT_RENDER_THREAD_SLICES,callback);});}};return{AndroidModelHelper:AndroidModelHelper};});'use strict';tr.exportTo('tr.e.audits',function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var Auditor=tr.c.Auditor;var AndroidModelHelper=tr.e.audits.AndroidModelHelper;var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS=tr.model.FRAME_PERF_CLASS;var InteractionRecord=tr.model.InteractionRecord;var Alert=tr.model.Alert;var EventInfo=tr.model.EventInfo;var TimeDuration=tr.b.u.TimeDuration;var EXPECTED_FRAME_TIME_MS=16.67;function getStart(e){return e.start;}
-function getDuration(e){return e.duration;}
-function getCpuDuration(e){return(e.cpuDuration!==undefined)?e.cpuDuration:e.duration;}
-function frameIsActivityStart(frame){for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='activityStart')
-return true;}
-return false;}
-var Auditor=tr.c.Auditor;var AndroidModelHelper=tr.e.audits.AndroidModelHelper;function frameMissedDeadline(frame){return frame.args['deadline']&&frame.args['deadline']<frame.end;}
-function DocLinkBuilder(){this.docLinks=[];}
-DocLinkBuilder.prototype={addAppVideo:function(name,videoId){this.docLinks.push({label:'Video Link',textContent:('Android Performance Patterns: '+name),href:'https://www.youtube.com/watch?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&v='+videoId});return this;},addDacRef:function(name,link){this.docLinks.push({label:'Doc Link',textContent:(name+' documentation'),href:'https://developer.android.com/reference/'+link});return this;},build:function(){return this.docLinks;}};function AndroidAuditor(model){Auditor.call(this,model);var helper=new AndroidModelHelper(model);if(helper.apps.length||helper.surfaceFlinger)
-this.helper=helper;};AndroidAuditor.viewAlphaAlertInfo_=new EventInfo('Inefficient View alpha usage','Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('View#setAlpha()','android/view/View.html#setAlpha(float)').build());AndroidAuditor.saveLayerAlertInfo_=new EventInfo('Expensive rendering with Canvas#saveLayer()','Canvas#saveLayer() incurs extremely high rendering cost. They disrupt the rendering pipeline when drawn, forcing a flush of drawing content. Instead use View hardware layers, or static Bitmaps. This enables the offscreen buffers to be reused in between frames, and avoids the disruptive render target switch.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('Canvas#saveLayerAlpha()','android/graphics/Canvas.html#saveLayerAlpha(android.graphics.RectF, int, int)').build());AndroidAuditor.getSaveLayerAlerts_=function(frame){var badAlphaRegEx=/^(.+) alpha caused (unclipped )?saveLayer (\d+)x(\d+)$/;var saveLayerRegEx=/^(unclipped )?saveLayer (\d+)x(\d+)$/;var ret=[];var events=[];frame.associatedEvents.forEach(function(slice){var match=badAlphaRegEx.exec(slice.title);if(match){var args={'view name':match[1],width:parseInt(match[3]),height:parseInt(match[4])};ret.push(new Alert(AndroidAuditor.viewAlphaAlertInfo_,slice.start,[slice],args));}else if(saveLayerRegEx.test(slice.title))
-events.push(slice);},this);if(events.length>ret.length){var unclippedSeen=Statistics.sum(events,function(slice){return saveLayerRegEx.exec(slice.title)[1]?1:0;});var clippedSeen=events.length-unclippedSeen;var earliestStart=Statistics.min(events,function(slice){return slice.start;});var args={'Unclipped saveLayer count (especially bad!)':unclippedSeen,'Clipped saveLayer count':clippedSeen};events.push(frame);ret.push(new Alert(AndroidAuditor.saveLayerAlertInfo_,earliestStart,events,args));}
-return ret;};AndroidAuditor.pathAlertInfo_=new EventInfo('Path texture churn','Paths are drawn with a mask texture, so when a path is modified / newly drawn, that texture must be generated and uploaded to the GPU. Ensure that you cache paths between frames and do not unnecessarily call Path#reset(). You can cut down on this cost by sharing Path object instances between drawables/views.');AndroidAuditor.getPathAlert_=function(frame){var uploadRegEx=/^Generate Path Texture$/;var events=frame.associatedEvents.filter(function(event){return event.title=='Generate Path Texture';});var start=Statistics.min(events,getStart);var duration=Statistics.sum(events,getDuration);if(duration<3)
-return undefined;events.push(frame);return new Alert(AndroidAuditor.pathAlertInfo_,start,events,{'Time spent':new TimeDuration(duration)});}
-AndroidAuditor.uploadAlertInfo_=new EventInfo('Expensive Bitmap uploads','Bitmaps that have been modified / newly drawn must be uploaded to the GPU. Since this is expensive if the total number of pixels uploaded is large, reduce the amount of Bitmap churn in this animation/context, per frame.');AndroidAuditor.getUploadAlert_=function(frame){var uploadRegEx=/^Upload (\d+)x(\d+) Texture$/;var events=[];var start=Number.POSITIVE_INFINITY;var duration=0;var pixelsUploaded=0;frame.associatedEvents.forEach(function(event){var match=uploadRegEx.exec(event.title);if(match){events.push(event);start=Math.min(start,event.start);duration+=event.duration;pixelsUploaded+=parseInt(match[1])*parseInt(match[2]);}});if(events.length==0||duration<3)
-return undefined;var mPixels=(pixelsUploaded/1000000).toFixed(2)+' million';var args={'Pixels uploaded':mPixels,'Time spent':new TimeDuration(duration)};events.push(frame);return new Alert(AndroidAuditor.uploadAlertInfo_,start,events,args);}
-AndroidAuditor.ListViewInflateAlertInfo_=new EventInfo('Inflation during ListView recycling','ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.');AndroidAuditor.ListViewBindAlertInfo_=new EventInfo('Inefficient ListView recycling/rebinding','ListView recycling taking too much time per frame. Ensure your Adapter#getView() binds data efficiently.');AndroidAuditor.getListViewAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='obtainView'||event.title=='setupListItem';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
-return undefined;var hasInflation=false;for(var i=0;i<events.length;i++){if(events[i]instanceof tr.model.Slice&&events[i].findDescendentSlice('inflate')){hasInflation=true;break;}}
-var start=Statistics.min(events,getStart);var args={'Time spent':new TimeDuration(duration)};args['ListView items '+(hasInflation?'inflated':'rebound')]=events.length/2;var eventInfo=hasInflation?AndroidAuditor.ListViewInflateAlertInfo_:AndroidAuditor.ListViewBindAlertInfo_;events.push(frame);return new Alert(eventInfo,start,events,args);}
-AndroidAuditor.measureLayoutAlertInfo_=new EventInfo('Expensive measure/layout pass','Measure/Layout took a significant time, contributing to jank. Avoid triggering layout during animations.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').build());AndroidAuditor.getMeasureLayoutAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='measure'||event.title=='layout';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
-return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.measureLayoutAlertInfo_,start,events,{'Time spent':new TimeDuration(duration)});}
-AndroidAuditor.viewDrawAlertInfo_=new EventInfo('Long View#draw()','Recording the drawing commands of invalidated Views took a long time. Avoid significant work in View or Drawable custom drawing, especially allocations or drawing to Bitmaps.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getViewDrawAlert_=function(frame){var slice=undefined;for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='getDisplayList'||frame.associatedEvents[i].title=='Record View#draw()'){slice=frame.associatedEvents[i];break;}}
-if(!slice||getCpuDuration(slice)<3)
-return undefined;return new Alert(AndroidAuditor.viewDrawAlertInfo_,slice.start,[slice,frame],{'Time spent':new TimeDuration(getCpuDuration(slice))});}
-AndroidAuditor.blockingGcAlertInfo_=new EventInfo('Blocking Garbage Collection','Blocking GCs are caused by object churn, and made worse by having large numbers of objects in the heap. Avoid allocating objects during animations/scrolling, and recycle Bitmaps to avoid triggering garbage collection.',new DocLinkBuilder().addAppVideo('Garbage Collection in Android','pzfzz50W5Uo').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getBlockingGcAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='DVM Suspend'||event.title=='GC: Wait For Concurrent';});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<3)
-return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.blockingGcAlertInfo_,start,events,{'Blocked duration':new TimeDuration(blockedDuration)});};AndroidAuditor.lockContentionAlertInfo_=new EventInfo('Lock contention','UI thread lock contention is caused when another thread holds a lock that the UI thread is trying to use. UI thread progress is blocked until the lock is released. Inspect locking done within the UI thread, and ensure critical sections are short.');AndroidAuditor.getLockContentionAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return/^Lock Contention on /.test(event.title);});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<1)
-return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.lockContentionAlertInfo_,start,events,{'Blocked duration':new TimeDuration(blockedDuration)});};AndroidAuditor.schedulingAlertInfo_=new EventInfo('Scheduling delay','Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn\'t block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.');AndroidAuditor.getSchedulingAlert_=function(frame){var totalDuration=0;var totalStats={};frame.threadTimeRanges.forEach(function(ttr){var stats=ttr.thread.getSchedulingStatsForRange(ttr.start,ttr.end);tr.b.iterItems(stats,function(key,value){if(!(key in totalStats))
-totalStats[key]=0;totalStats[key]+=value;totalDuration+=value;});});if(!(SCHEDULING_STATE.RUNNING in totalStats)||totalDuration==0||totalDuration-totalStats[SCHEDULING_STATE.RUNNING]<3)
-return;var args={};tr.b.iterItems(totalStats,function(key,value){if(key===SCHEDULING_STATE.RUNNABLE)
-key='Not scheduled, but runnable';else if(key===SCHEDULING_STATE.UNINTR_SLEEP)
-key='Blocking I/O delay';args[key]=new TimeDuration(value);});return new Alert(AndroidAuditor.schedulingAlertInfo_,frame.start,[frame],args);};AndroidAuditor.prototype={__proto__:Auditor.prototype,renameAndSort_:function(){this.model.kernel.important=false;this.model.getAllProcesses().forEach(function(process){if(this.helper.surfaceFlinger&&process==this.helper.surfaceFlinger.process){if(!process.name)
-process.name='SurfaceFlinger';process.sortIndex=Number.NEGATIVE_INFINITY;process.important=false;return;}
-var uiThread=process.getThread(process.pid);if(!process.name&&uiThread&&uiThread.name){if(/^ndroid\./.test(uiThread.name))
-uiThread.name='a'+uiThread.name;process.name=uiThread.name;uiThread.name='UI Thread';}
-process.sortIndex=0;for(var tid in process.threads){process.sortIndex-=process.threads[tid].sliceGroup.slices.length;}},this);this.model.getAllThreads().forEach(function(thread){if(thread.tid==thread.parent.pid)
-thread.sortIndex=-3;if(thread.name=='RenderThread')
-thread.sortIndex=-2;if(/^hwuiTask/.test(thread.name))
-thread.sortIndex=-1;});},pushFramesAndJudgeJank_:function(){var badFramesObserved=0;var framesObserved=0;var surfaceFlinger=this.helper.surfaceFlinger;this.helper.apps.forEach(function(app){app.process.frames=app.getFrames();app.process.frames.forEach(function(frame){if(frame.totalDuration>EXPECTED_FRAME_TIME_MS*2){badFramesObserved+=2;frame.perfClass=FRAME_PERF_CLASS.TERRIBLE;}else if(frame.totalDuration>EXPECTED_FRAME_TIME_MS||frameMissedDeadline(frame)){badFramesObserved++;frame.perfClass=FRAME_PERF_CLASS.BAD;}else{frame.perfClass=FRAME_PERF_CLASS.GOOD;}});framesObserved+=app.process.frames.length;});if(framesObserved){var portionBad=badFramesObserved/framesObserved;if(portionBad>0.3)
-this.model.faviconHue='red';else if(portionBad>0.05)
-this.model.faviconHue='yellow';else
-this.model.faviconHue='green';}},pushEventInfo_:function(){var appAnnotator=new AppAnnotator();this.helper.apps.forEach(function(app){if(app.uiThread)
-appAnnotator.applyEventInfos(app.uiThread.sliceGroup);if(app.renderThread)
-appAnnotator.applyEventInfos(app.renderThread.sliceGroup);});},runAnnotate:function(){if(!this.helper)
-return;this.renameAndSort_();this.pushFramesAndJudgeJank_();this.pushEventInfo_();this.helper.iterateImportantSlices(function(slice){slice.important=true;});},runAudit:function(){if(!this.helper)
-return;var alerts=this.model.alerts;this.helper.apps.forEach(function(app){app.getFrames().forEach(function(frame){alerts.push.apply(alerts,AndroidAuditor.getSaveLayerAlerts_(frame));if(frame.perfClass==FRAME_PERF_CLASS.NEUTRAL||frame.perfClass==FRAME_PERF_CLASS.GOOD)
-return;var alert=AndroidAuditor.getPathAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getUploadAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getListViewAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getMeasureLayoutAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getViewDrawAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getBlockingGcAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getLockContentionAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getSchedulingAlert_(frame);if(alert)
-alerts.push(alert);});},this);this.addRenderingInteractionRecords();this.addInputInteractionRecords();},addRenderingInteractionRecords:function(){var events=[];this.helper.apps.forEach(function(app){events.push.apply(events,app.getAnimationAsyncSlices());events.push.apply(events,app.getFrames());});var mergerFunction=function(events){var ir=new InteractionRecord(this.model,'Rendering',ColorScheme.getColorIdForGeneralPurposeString('mt_rendering'),events[0].min,events[events.length-1].max-events[0].min);this.model.addInteractionRecord(ir);}.bind(this);tr.b.mergeRanges(tr.b.convertEventsToRanges(events),30,mergerFunction);},addInputInteractionRecords:function(){var inputSamples=[];this.helper.apps.forEach(function(app){inputSamples.push.apply(inputSamples,app.getInputSamples());});var mergerFunction=function(events){var ir=new InteractionRecord(this.model,'Input',ColorScheme.getColorIdForGeneralPurposeString('mt_input'),events[0].min,events[events.length-1].max-events[0].min);this.model.addInteractionRecord(ir);}.bind(this);var inputRanges=inputSamples.map(function(sample){return tr.b.Range.fromExplicitRange(sample.timestamp,sample.timestamp);});tr.b.mergeRanges(inputRanges,30,mergerFunction);}};Auditor.register(AndroidAuditor);function AppAnnotator(){this.titleInfoLookup={};this.titleParentLookup={};this.build_();}
-AppAnnotator.prototype={build_:function(){var registerEventInfo=function(dict){this.titleInfoLookup[dict.title]=new EventInfo(dict.title,dict.description,dict.docLinks);if(dict.parents)
-this.titleParentLookup[dict.title]=dict.parents;}.bind(this);registerEventInfo({title:'inflate',description:'Constructing a View hierarchy from pre-processed XML via LayoutInflater#layout. This includes constructing all of the View objects in the hierarchy, and applying styled attributes.'});registerEventInfo({title:'obtainView',description:'Adapter#getView() called to bind content to a recycled View that is being presented.'});registerEventInfo({title:'setupListItem',description:'Attached a newly-bound, recycled View to its parent ListView.'});registerEventInfo({title:'setupGridItem',description:'Attached a newly-bound, recycled View to its parent GridView.'});var choreographerLinks=new DocLinkBuilder().addDacRef('Choreographer','android/view/Choreographer.html').build();registerEventInfo({title:'Choreographer#doFrame',docLinks:choreographerLinks,description:'Choreographer executes frame callbacks for inputs, animations, and rendering traversals. When this work is done, a frame will be presented to the user.'});registerEventInfo({title:'input',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Input callbacks are processed. This generally encompasses dispatching input to Views, as well as any work the Views do to process this input/gesture.'});registerEventInfo({title:'animation',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Animation callbacks are processed. This is generally minimal work, as animations determine progress for the frame, and push new state to animated objects (such as setting View properties).'});registerEventInfo({title:'traversals',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Primary draw traversals. This is the primary traversal of the View hierarchy, including layout and draw passes.'});var traversalParents=['Choreographer#doFrame','performTraversals'];var layoutLinks=new DocLinkBuilder().addDacRef('View#Layout','android/view/View.html#Layout').build();registerEventInfo({title:'performTraversals',description:'A drawing traversal of the View hierarchy, comprised of all layout and drawing needed to produce the frame.'});registerEventInfo({title:'measure',parents:traversalParents,docLinks:layoutLinks,description:'First of two phases in view hierarchy layout. Views are asked to size themselves according to constraints supplied by their parent. Some ViewGroups may measure a child more than once to help satisfy their own constraints. Nesting ViewGroups that measure children more than once can lead to excessive and repeated work.'});registerEventInfo({title:'layout',parents:traversalParents,docLinks:layoutLinks,description:'Second of two phases in view hierarchy layout, repositioning content and child Views into their new locations.'});var drawString='Draw pass over the View hierarchy. Every invalidated View will have its drawing commands recorded. On Android versions prior to Lollipop, this would also include the issuing of draw commands to the GPU. Starting with Lollipop, it only includes the recording of commands, and syncing that information to the RenderThread.';registerEventInfo({title:'draw',parents:traversalParents,description:drawString});var recordString='Every invalidated View\'s drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded.';registerEventInfo({title:'getDisplayList',parents:['draw'],description:recordString});registerEventInfo({title:'Record View#draw()',parents:['draw'],description:recordString});registerEventInfo({title:'drawDisplayList',parents:['draw'],description:'Execution of recorded draw commands to generate a frame. This represents the actual formation and issuing of drawing commands to the GPU. On Android L and higher devices, this work is done on a dedicated RenderThread, instead of on the UI Thread.'});registerEventInfo({title:'DrawFrame',description:'RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.'});registerEventInfo({title:'doFrame',description:'RenderThread animation frame. Represents drawing work done by the RenderThread on a frame where the UI thread did not produce new drawing content.'});registerEventInfo({title:'syncFrameState',description:'Sync stage between the UI thread and the RenderThread, where the UI thread hands off a frame (including information about modified Views). Time in this method primarily consists of uploading modified Bitmaps to the GPU. After this sync is completed, the UI thread is unblocked, and the RenderThread starts to render the frame.'});registerEventInfo({title:'flush drawing commands',description:'Issuing the now complete drawing commands to the GPU.'});registerEventInfo({title:'eglSwapBuffers',description:'Complete GPU rendering of the frame.'});registerEventInfo({title:'RV Scroll',description:'RecyclerView is calculating a scroll. If there are too many of these in Systrace, some Views inside RecyclerView might be causing it. Try to avoid using EditText, focusable views or handle them with care.'});registerEventInfo({title:'RV OnLayout',description:'OnLayout has been called by the View system. If this shows up too many times in Systrace, make sure the children of RecyclerView do not update themselves directly. This will cause a full re-layout but when it happens via the Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.'});registerEventInfo({title:'RV FullInvalidate',description:'NotifyDataSetChanged or equal has been called. If this is taking a long time, try sending granular notify adapter changes instead of just calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter might help.'});registerEventInfo({title:'RV PartialInvalidate',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV OnBindView',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV CreateView',description:'RecyclerView is creating a new View. If too many of these are present: 1) There might be a problem in Recycling (e.g. custom Animations that set transient state and prevent recycling or ItemAnimator not implementing the contract properly. See Adapter#onFailedToRecycleView(ViewHolder). 2) There may be too many item view types. Try merging them. 3) There might be too many itemChange animations and not enough space in RecyclerPool. Try increasing your pool size and item cache size.'});registerEventInfo({title:'eglSwapBuffers',description:'The CPU has finished producing drawing commands, and is flushing drawing work to the GPU, and posting that buffer to the consumer (which is often SurfaceFlinger window composition). Once this is completed, the GPU can produce the frame content without any involvement from the CPU.'});},applyEventInfosRecursive_:function(parentNames,slice){var checkExpectedParentNames=function(expectedParentNames){if(!expectedParentNames)
-return true;return expectedParentNames.some(function(name){return name in parentNames;});}
-if(slice.title in this.titleInfoLookup){if(checkExpectedParentNames(this.titleParentLookup[slice.title]))
-slice.info=this.titleInfoLookup[slice.title];}
-if(slice.subSlices.length>0){if(!(slice.title in parentNames))
-parentNames[slice.title]=0;parentNames[slice.title]++;slice.subSlices.forEach(function(subSlice){this.applyEventInfosRecursive_(parentNames,subSlice);},this);parentNames[slice.title]--;if(parentNames[slice.title]==0)
-delete parentNames[slice.title];}},applyEventInfos:function(sliceGroup){sliceGroup.topLevelSlices.forEach(function(slice){this.applyEventInfosRecursive_({},slice);},this);}};return{AndroidAuditor:AndroidAuditor};});'use strict';tr.exportTo('tr.e.audits',function(){var VSYNC_COUNTER_PRECISIONS={'android.VSYNC-app':15,'android.VSYNC':15};var VSYNC_SLICE_PRECISIONS={'RenderWidgetHostViewAndroid::OnVSync':5,'VSYNC':10,'vblank':10,'DisplayLinkMac::GetVSyncParameters':5};var BEGIN_FRAME_SLICE_PRECISION={'Scheduler::BeginFrame':10};function VSyncAuditor(model){tr.c.Auditor.call(this,model);};VSyncAuditor.prototype={__proto__:tr.c.Auditor.prototype,runAnnotate:function(){this.model.device.vSyncTimestamps=this.findVSyncTimestamps(this.model);},findVSyncTimestamps:function(model){var times=[];var maxPrecision=Number.NEGATIVE_INFINITY;var maxTitle=undefined;function useInstead(title,precisions){var precision=precisions[title];if(precision===undefined)
+this.lines_.push([line,eventBase,parseInt(eventBase.cpuNumber),parseInt(eventBase.pid),parseFloat(eventBase.timestamp)*1000]);}},forEachLine_:function(handler){for(var i=0;i<this.lines_.length;++i){var line=this.lines_[i];handler.apply(this,line);}}};tr.importer.Importer.register(FTraceImporter);return{FTraceImporter:FTraceImporter,_FTraceImporterTestExports:TestExports};});'use strict';tr.exportTo('tr.e.audits',function(){var VSYNC_COUNTER_PRECISIONS={'android.VSYNC-app':15,'android.VSYNC':15};var VSYNC_SLICE_PRECISIONS={'RenderWidgetHostViewAndroid::OnVSync':5,'VSYNC':10,'vblank':10,'DisplayLinkMac::GetVSyncParameters':5};var BEGIN_FRAME_SLICE_PRECISION={'Scheduler::BeginFrame':10};function VSyncAuditor(model){tr.c.Auditor.call(this,model);};VSyncAuditor.prototype={__proto__:tr.c.Auditor.prototype,runAnnotate:function(){this.model.device.vSyncTimestamps=this.findVSyncTimestamps(this.model);},findVSyncTimestamps:function(model){var times=[];var maxPrecision=Number.NEGATIVE_INFINITY;var maxTitle=undefined;function useInstead(title,precisions){var precision=precisions[title];if(precision===undefined)
 return false;if(title===maxTitle)
 return true;if(precision<=maxPrecision){if(precision===maxPrecision){console.warn('Encountered two different VSync events ('+
 maxTitle+', '+title+') with the same precision, '+'ignoring the newer one ('+title+')');}
@@ -4164,763 +5058,331 @@
 for(var tid in process.threads){var thread=process.threads[tid];for(var i=0;i<thread.sliceGroup.slices.length;i++){var slice=thread.sliceGroup.slices[i];if(useInstead(slice.title,VSYNC_SLICE_PRECISIONS))
 times.push(slice.start);else if(useInstead(slice.title,BEGIN_FRAME_SLICE_PRECISION)&&slice.args.args&&slice.args.args.frame_time_us)
 times.push(slice.args.args.frame_time_us/1000.0);}}}
-times.sort(function(x,y){return x-y;});return times;}};tr.c.Auditor.register(VSyncAuditor);return{VSyncAuditor:VSyncAuditor};});'use strict';tr.exportTo('tr.b',function(){var tmpVec2s=[];for(var i=0;i<8;i++)
-tmpVec2s[i]=vec2.create();var tmpVec2a=vec4.create();var tmpVec4a=vec4.create();var tmpVec4b=vec4.create();var tmpMat4=mat4.create();var tmpMat4b=mat4.create();var p00=vec2.createXY(0,0);var p10=vec2.createXY(1,0);var p01=vec2.createXY(0,1);var p11=vec2.createXY(1,1);var lerpingVecA=vec2.create();var lerpingVecB=vec2.create();function lerpVec2(out,a,b,amt){vec2.scale(lerpingVecA,a,amt);vec2.scale(lerpingVecB,b,1-amt);vec2.add(out,lerpingVecA,lerpingVecB);vec2.normalize(out,out);return out;}
-function Quad(){this.p1=vec2.create();this.p2=vec2.create();this.p3=vec2.create();this.p4=vec2.create();}
-Quad.fromXYWH=function(x,y,w,h){var q=new Quad();vec2.set(q.p1,x,y);vec2.set(q.p2,x+w,y);vec2.set(q.p3,x+w,y+h);vec2.set(q.p4,x,y+h);return q;}
-Quad.fromRect=function(r){return new Quad.fromXYWH(r.x,r.y,r.width,r.height);}
-Quad.from4Vecs=function(p1,p2,p3,p4){var q=new Quad();vec2.set(q.p1,p1[0],p1[1]);vec2.set(q.p2,p2[0],p2[1]);vec2.set(q.p3,p3[0],p3[1]);vec2.set(q.p4,p4[0],p4[1]);return q;}
-Quad.from8Array=function(arr){if(arr.length!=8)
-throw new Error('Array must be 8 long');var q=new Quad();q.p1[0]=arr[0];q.p1[1]=arr[1];q.p2[0]=arr[2];q.p2[1]=arr[3];q.p3[0]=arr[4];q.p3[1]=arr[5];q.p4[0]=arr[6];q.p4[1]=arr[7];return q;};Quad.prototype={pointInside:function(point){return pointInImplicitQuad(point,this.p1,this.p2,this.p3,this.p4);},boundingRect:function(){var x0=Math.min(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y0=Math.min(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);var x1=Math.max(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y1=Math.max(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);return new tr.b.Rect.fromXYWH(x0,y0,x1-x0,y1-y0);},clone:function(){var q=new Quad();vec2.copy(q.p1,this.p1);vec2.copy(q.p2,this.p2);vec2.copy(q.p3,this.p3);vec2.copy(q.p4,this.p4);return q;},scale:function(s){var q=new Quad();this.scaleFast(q,s);return q;},scaleFast:function(dstQuad,s){vec2.copy(dstQuad.p1,this.p1,s);vec2.copy(dstQuad.p2,this.p2,s);vec2.copy(dstQuad.p3,this.p3,s);vec2.copy(dstQuad.p3,this.p3,s);},isRectangle:function(){var bounds=this.boundingRect();return(bounds.x==this.p1[0]&&bounds.y==this.p1[1]&&bounds.width==this.p2[0]-this.p1[0]&&bounds.y==this.p2[1]&&bounds.width==this.p3[0]-this.p1[0]&&bounds.height==this.p3[1]-this.p2[1]&&bounds.x==this.p4[0]&&bounds.height==this.p4[1]-this.p2[1]);},projectUnitRect:function(rect){var q=new Quad();this.projectUnitRectFast(q,rect);return q;},projectUnitRectFast:function(dstQuad,rect){var v12=tmpVec2s[0];var v14=tmpVec2s[1];var v23=tmpVec2s[2];var v43=tmpVec2s[3];var l12,l14,l23,l43;vec2.sub(v12,this.p2,this.p1);l12=vec2.length(v12);vec2.scale(v12,v12,1/l12);vec2.sub(v14,this.p4,this.p1);l14=vec2.length(v14);vec2.scale(v14,v14,1/l14);vec2.sub(v23,this.p3,this.p2);l23=vec2.length(v23);vec2.scale(v23,v23,1/l23);vec2.sub(v43,this.p3,this.p4);l43=vec2.length(v43);vec2.scale(v43,v43,1/l43);var b12=tmpVec2s[0];var b14=tmpVec2s[1];var b23=tmpVec2s[2];var b43=tmpVec2s[3];lerpVec2(b12,v12,v43,rect.y);lerpVec2(b43,v12,v43,1-rect.bottom);lerpVec2(b14,v14,v23,rect.x);lerpVec2(b23,v14,v23,1-rect.right);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*rect.x,b14,l14*rect.y);vec2.add(dstQuad.p1,this.p1,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*-(1.0-rect.right),b23,l23*rect.y);vec2.add(dstQuad.p2,this.p2,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*-(1.0-rect.right),b23,l23*-(1.0-rect.bottom));vec2.add(dstQuad.p3,this.p3,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*rect.left,b14,l14*-(1.0-rect.bottom));vec2.add(dstQuad.p4,this.p4,tmpVec2a);},toString:function(){return'Quad('+
-vec2.toString(this.p1)+', '+
-vec2.toString(this.p2)+', '+
-vec2.toString(this.p3)+', '+
-vec2.toString(this.p4)+')';}};function sign(p1,p2,p3){return(p1[0]-p3[0])*(p2[1]-p3[1])-
-(p2[0]-p3[0])*(p1[1]-p3[1]);}
-function pointInTriangle2(pt,p1,p2,p3){var b1=sign(pt,p1,p2)<0.0;var b2=sign(pt,p2,p3)<0.0;var b3=sign(pt,p3,p1)<0.0;return((b1==b2)&&(b2==b3));}
-function pointInImplicitQuad(point,p1,p2,p3,p4){return pointInTriangle2(point,p1,p2,p3)||pointInTriangle2(point,p1,p3,p4);}
-return{pointInTriangle2:pointInTriangle2,pointInImplicitQuad:pointInImplicitQuad,Quad:Quad};});'use strict';tr.exportTo('tr.model.source_info',function(){function SourceInfo(file,opt_line,opt_column){this.file_=file;this.line_=opt_line||-1;this.column_=opt_column||-1;}
-SourceInfo.prototype={get file(){return this.file_;},get line(){return this.line_;},get column(){return this.column_;},get domain(){if(!this.file_)
-return undefined;var domain=this.file_.match(/(.*:\/\/[^:\/]*)/i);return domain?domain[1]:undefined;},toString:function(){var str='';if(this.file_)
-str+=this.file_;if(this.line_>0)
-str+=':'+this.line_;if(this.column_>0)
-str+=':'+this.column_;return str;}};return{SourceInfo:SourceInfo};});'use strict';tr.exportTo('tr.model.source_info',function(){function JSSourceInfo(file,line,column,isNative,scriptId,state){tr.model.source_info.SourceInfo.call(this,file,line,column);this.isNative_=isNative;this.scriptId_=scriptId;this.state_=state;}
-JSSourceInfo.prototype={__proto__:tr.model.source_info.SourceInfo.prototype,get state(){return this.state_;},get isNative(){return this.isNative_;},get scriptId(){return this.scriptId_;},toString:function(){var str=this.isNative_?'[native v8] ':'';return str+
-tr.model.source_info.SourceInfo.prototype.toString.call(this);}};return{JSSourceInfo:JSSourceInfo,JSSourceState:{COMPILED:'compiled',OPTIMIZABLE:'optimizable',OPTIMIZED:'optimized',UNKNOWN:'unknown'}};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeEntry(address,size,name,scriptId){this.id_=tr.b.GUID.allocate();this.address_=address;this.size_=size;var rePrefix=/^(\w*:)?([*~]?)(.*)$/m;var tokens=rePrefix.exec(name);var prefix=tokens[1];var state=tokens[2];var body=tokens[3];if(state==='*'){state=tr.model.source_info.JSSourceState.OPTIMIZED;}else if(state==='~'){state=tr.model.source_info.JSSourceState.OPTIMIZABLE;}else if(state===''){state=tr.model.source_info.JSSourceState.COMPILED;}else{console.warning('Unknown v8 code state '+state);state=tr.model.source_info.JSSourceState.UNKNOWN;}
-var rawName;var rawUrl;if(prefix==='Script:'){rawName='';rawUrl=body;}else{var spacePos=body.lastIndexOf(' ');rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):'';}
-function splitLineAndColumn(url){var lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;var lineColumnMatch=lineColumnRegEx.exec(url);var lineNumber;var columnNumber;if(typeof(lineColumnMatch[1])==='string'){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
-if(typeof(lineColumnMatch[2])==='string'){columnNumber=parseInt(lineColumnMatch[2],10);columnNumber=isNaN(columnNumber)?undefined:columnNumber-1;}
-return{url:url.substring(0,url.length-lineColumnMatch[0].length),lineNumber:lineNumber,columnNumber:columnNumber};}
-var nativeSuffix=' native';var isNative=rawName.endsWith(nativeSuffix);this.name_=isNative?rawName.slice(0,-nativeSuffix.length):rawName;var urlData=splitLineAndColumn(rawUrl);var url=urlData.url||'';var line=urlData.lineNumber||0;var column=urlData.columnNumber||0;this.sourceInfo_=new tr.model.source_info.JSSourceInfo(url,line,column,isNative,scriptId,state);};TraceCodeEntry.prototype={get id(){return this.id_;},get sourceInfo(){return this.sourceInfo_;},get name(){return this.name_;},set address(address){this.address_=address;},get address(){return this.address_;},set size(size){this.size_=size;},get size(){return this.size_;}};return{TraceCodeEntry:TraceCodeEntry};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeMap(){this.banks_=new Map();}
-TraceCodeMap.prototype={addEntry:function(addressHex,size,name,scriptId){var entry=new tr.e.importer.TraceCodeEntry(this.getAddress_(addressHex),size,name,scriptId);this.addEntry_(addressHex,entry);},moveEntry:function(oldAddressHex,newAddressHex,size){var entry=this.getBank_(oldAddressHex).removeEntry(this.getAddress_(oldAddressHex));if(!entry)
-return;entry.address=this.getAddress_(newAddressHex);entry.size=size;this.addEntry_(newAddressHex,entry);},lookupEntry:function(addressHex){return this.getBank_(addressHex).lookupEntry(this.getAddress_(addressHex));},addEntry_:function(addressHex,entry){this.getBank_(addressHex).addEntry(entry);},getAddress_:function(addressHex){var bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);},getBank_:function(addressHex){addressHex=addressHex.slice(2);var bankSizeHexDigits=13;var maxHexDigits=16;var bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);var bank=this.banks_.get(bankName);if(!bank){bank=new TraceCodeBank();this.banks_.set(bankName,bank);}
-return bank;}};function TraceCodeBank(){this.entries_=[];}
-TraceCodeBank.prototype={removeEntry:function(address){if(this.entries_.length===0)
-return undefined;var index=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},address);var entry=this.entries_[index];if(!entry||entry.address!==address)
-return undefined;this.entries_.splice(index,1);return entry;},lookupEntry:function(address){var index=tr.b.findHighIndexInSortedArray(this.entries_,function(e){return address-e.address;})-1;var entry=this.entries_[index];return entry&&address<entry.address+entry.size?entry:undefined;},addEntry:function(newEntry){if(this.entries_.length===0)
-this.entries_.push(newEntry);var endAddress=newEntry.address+newEntry.size;var lastIndex=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},endAddress);var index;for(index=lastIndex-1;index>=0;--index){var entry=this.entries_[index];var entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address)
-break;}
-++index;this.entries_.splice(index,lastIndex-index,newEntry);}};return{TraceCodeMap:TraceCodeMap};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function SplayTree(){};SplayTree.prototype.root_=null;SplayTree.prototype.isEmpty=function(){return!this.root_;};SplayTree.prototype.insert=function(key,value){if(this.isEmpty()){this.root_=new SplayTree.Node(key,value);return;}
-this.splay_(key);if(this.root_.key==key){return;}
-var node=new SplayTree.Node(key,value);if(key>this.root_.key){node.left=this.root_;node.right=this.root_.right;this.root_.right=null;}else{node.right=this.root_;node.left=this.root_.left;this.root_.left=null;}
-this.root_=node;};SplayTree.prototype.remove=function(key){if(this.isEmpty()){throw Error('Key not found: '+key);}
-this.splay_(key);if(this.root_.key!=key){throw Error('Key not found: '+key);}
-var removed=this.root_;if(!this.root_.left){this.root_=this.root_.right;}else{var right=this.root_.right;this.root_=this.root_.left;this.splay_(key);this.root_.right=right;}
-return removed;};SplayTree.prototype.find=function(key){if(this.isEmpty()){return null;}
-this.splay_(key);return this.root_.key==key?this.root_:null;};SplayTree.prototype.findMin=function(){if(this.isEmpty()){return null;}
-var current=this.root_;while(current.left){current=current.left;}
-return current;};SplayTree.prototype.findMax=function(opt_startNode){if(this.isEmpty()){return null;}
-var current=opt_startNode||this.root_;while(current.right){current=current.right;}
-return current;};SplayTree.prototype.findGreatestLessThan=function(key){if(this.isEmpty()){return null;}
-this.splay_(key);if(this.root_.key<=key){return this.root_;}else if(this.root_.left){return this.findMax(this.root_.left);}else{return null;}};SplayTree.prototype.exportKeysAndValues=function(){var result=[];this.traverse_(function(node){result.push([node.key,node.value]);});return result;};SplayTree.prototype.exportValues=function(){var result=[];this.traverse_(function(node){result.push(node.value);});return result;};SplayTree.prototype.splay_=function(key){if(this.isEmpty()){return;}
-var dummy,left,right;dummy=left=right=new SplayTree.Node(null,null);var current=this.root_;while(true){if(key<current.key){if(!current.left){break;}
-if(key<current.left.key){var tmp=current.left;current.left=tmp.right;tmp.right=current;current=tmp;if(!current.left){break;}}
-right.left=current;right=current;current=current.left;}else if(key>current.key){if(!current.right){break;}
-if(key>current.right.key){var tmp=current.right;current.right=tmp.left;tmp.left=current;current=tmp;if(!current.right){break;}}
-left.right=current;left=current;current=current.right;}else{break;}}
-left.right=current.left;right.left=current.right;current.left=dummy.right;current.right=dummy.left;this.root_=current;};SplayTree.prototype.traverse_=function(f){var nodesToVisit=[this.root_];while(nodesToVisit.length>0){var node=nodesToVisit.shift();if(node==null){continue;}
-f(node);nodesToVisit.push(node.left);nodesToVisit.push(node.right);}};SplayTree.Node=function(key,value){this.key=key;this.value=value;};SplayTree.Node.prototype.left=null;SplayTree.Node.prototype.right=null;return{SplayTree:SplayTree};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CodeMap(){this.dynamics_=new tr.e.importer.v8.SplayTree();this.dynamicsNameGen_=new tr.e.importer.v8.CodeMap.NameGenerator();this.statics_=new tr.e.importer.v8.SplayTree();this.libraries_=new tr.e.importer.v8.SplayTree();this.pages_=[];};CodeMap.PAGE_ALIGNMENT=12;CodeMap.PAGE_SIZE=1<<CodeMap.PAGE_ALIGNMENT;CodeMap.prototype.addCode=function(start,codeEntry){this.deleteAllCoveredNodes_(this.dynamics_,start,start+codeEntry.size);this.dynamics_.insert(start,codeEntry);};CodeMap.prototype.moveCode=function(from,to){var removedNode=this.dynamics_.remove(from);this.deleteAllCoveredNodes_(this.dynamics_,to,to+removedNode.value.size);this.dynamics_.insert(to,removedNode.value);};CodeMap.prototype.deleteCode=function(start){var removedNode=this.dynamics_.remove(start);};CodeMap.prototype.addLibrary=function(start,codeEntry){this.markPages_(start,start+codeEntry.size);this.libraries_.insert(start,codeEntry);};CodeMap.prototype.addStaticCode=function(start,codeEntry){this.statics_.insert(start,codeEntry);};CodeMap.prototype.markPages_=function(start,end){for(var addr=start;addr<=end;addr+=CodeMap.PAGE_SIZE){this.pages_[addr>>>CodeMap.PAGE_ALIGNMENT]=1;}};CodeMap.prototype.deleteAllCoveredNodes_=function(tree,start,end){var to_delete=[];var addr=end-1;while(addr>=start){var node=tree.findGreatestLessThan(addr);if(!node)break;var start2=node.key,end2=start2+node.value.size;if(start2<end&&start<end2)to_delete.push(start2);addr=start2-1;}
-for(var i=0,l=to_delete.length;i<l;++i)tree.remove(to_delete[i]);};CodeMap.prototype.isAddressBelongsTo_=function(addr,node){return addr>=node.key&&addr<(node.key+node.value.size);};CodeMap.prototype.findInTree_=function(tree,addr){var node=tree.findGreatestLessThan(addr);return node&&this.isAddressBelongsTo_(addr,node)?node.value:null;};CodeMap.prototype.findEntry=function(addr){var pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.statics_,addr)||this.findInTree_(this.libraries_,addr);}
-var min=this.dynamics_.findMin();var max=this.dynamics_.findMax();if(max!=null&&addr<(max.key+max.value.size)&&addr>=min.key){var dynaEntry=this.findInTree_(this.dynamics_,addr);if(dynaEntry==null)return null;if(!dynaEntry.nameUpdated_){dynaEntry.name=this.dynamicsNameGen_.getName(dynaEntry.name);dynaEntry.nameUpdated_=true;}
-return dynaEntry;}
-return null;};CodeMap.prototype.findDynamicEntryByStartAddress=function(addr){var node=this.dynamics_.find(addr);return node?node.value:null;};CodeMap.prototype.getAllDynamicEntries=function(){return this.dynamics_.exportValues();};CodeMap.prototype.getAllDynamicEntriesWithAddresses=function(){return this.dynamics_.exportKeysAndValues();};CodeMap.prototype.getAllStaticEntries=function(){return this.statics_.exportValues();};CodeMap.prototype.getAllLibrariesEntries=function(){return this.libraries_.exportValues();};CodeMap.CodeEntry=function(size,opt_name){this.id=tr.b.GUID.allocate();this.size=size;this.name=opt_name||'';this.nameUpdated_=false;};CodeMap.CodeEntry.prototype.getName=function(){return this.name;};CodeMap.CodeEntry.prototype.toString=function(){return this.name+': '+this.size.toString(16);};CodeMap.NameGenerator=function(){this.knownNames_={};};CodeMap.NameGenerator.prototype.getName=function(name){if(!(name in this.knownNames_)){this.knownNames_[name]=0;return name;}
-var count=++this.knownNames_[name];return name+' {'+count+'}';};return{CodeMap:CodeMap};});'use strict';tr.exportTo('tr.model',function(){function YComponent(stableId,yPercentOffset){this.stableId=stableId;this.yPercentOffset=yPercentOffset;}
-YComponent.prototype={toDict:function(){return{stableId:this.stableId,yPercentOffset:this.yPercentOffset};}};function Location(xWorld,yComponents){this.xWorld_=xWorld;this.yComponents_=yComponents;};Location.fromViewCoordinates=function(viewport,viewX,viewY){var dt=viewport.currentDisplayTransform;var xWorld=dt.xViewToWorld(viewX);var yComponents=[];var elem=document.elementFromPoint(viewX+viewport.modelTrackContainer.canvas.offsetLeft,viewY+viewport.modelTrackContainer.canvas.offsetTop);while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(viewY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
-elem=elem.parentElement;}
-if(yComponents.length==0)
-return;return new Location(xWorld,yComponents);}
-Location.fromStableIdAndTimestamp=function(viewport,stableId,ts){var xWorld=ts;var yComponents=[];var containerToTrack=viewport.containerToTrackMap;var elem=containerToTrack.getTrackByStableId(stableId);if(!elem)
-return;var firstY=elem.getBoundingClientRect().top;while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(firstY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
-elem=elem.parentElement;}
-if(yComponents.length==0)
-return;return new Location(xWorld,yComponents);}
-Location.prototype={get xWorld(){return this.xWorld_;},getContainingTrack:function(viewport){var containerToTrack=viewport.containerToTrackMap;for(var i in this.yComponents_){var yComponent=this.yComponents_[i];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined)
-return track;}},toViewCoordinates:function(viewport){var dt=viewport.currentDisplayTransform;var containerToTrack=viewport.containerToTrackMap;var viewX=dt.xWorldToView(this.xWorld_);var viewY=-1;for(var index in this.yComponents_){var yComponent=this.yComponents_[index];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined){var boundRect=track.getBoundingClientRect();viewY=yComponent.yPercentOffset*boundRect.height+boundRect.top;break;}}
-return{viewX:viewX,viewY:viewY};},toDict:function(){return{xWorld:this.xWorld_,yComponents:this.yComponents_};}};return{Location:Location};});'use strict';tr.exportTo('tr.model',function(){function Annotation(){this.guid_=tr.b.GUID.allocate();this.view_=undefined;};Annotation.fromDictIfPossible=function(args){if(args.typeName===undefined)
-throw new Error('Missing typeName argument');var typeInfo=Annotation.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.typeName===args.typeName;});if(typeInfo===undefined)
-return undefined;return typeInfo.constructor.fromDict(args);};Annotation.fromDict=function(){throw new Error('Not implemented');}
-Annotation.prototype={get guid(){return this.guid_;},onRemove:function(){},toDict:function(){throw new Error('Not implemented');},getOrCreateView:function(viewport){if(!this.view_)
-this.view_=this.createView_(viewport);return this.view_;},createView_:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Annotation,options);Annotation.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict'))
-throw new Error('Must have fromDict method');if(!e.typeInfo.metadata.typeName)
-throw new Error('Registered Annotations must provide typeName');});return{Annotation:Annotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function AnnotationView(viewport,annotation){}
-AnnotationView.prototype={draw:function(ctx){throw new Error('Not implemented');}};return{AnnotationView:AnnotationView};});'use strict';tr.exportTo('tr.ui.annotations',function(){function RectAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
-RectAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var startCoords=this.annotation_.startLocation.toViewCoordinates(this.viewport_);var endCoords=this.annotation_.endLocation.toViewCoordinates(this.viewport_);var startY=startCoords.viewY-ctx.canvas.getBoundingClientRect().top;var sizeY=endCoords.viewY-startCoords.viewY;if(startY+sizeY<0){startY=sizeY;}else if(startY<0){startY=0;}
-ctx.fillStyle=this.annotation_.fillStyle;ctx.fillRect(startCoords.viewX,startY,endCoords.viewX-startCoords.viewX,sizeY);}};return{RectAnnotationView:RectAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function RectAnnotation(start,end){tr.model.Annotation.apply(this,arguments);this.startLocation_=start;this.endLocation_=end;this.fillStyle='rgba(255, 180, 0, 0.3)';}
-RectAnnotation.fromDict=function(dict){var args=dict.args;var startLoc=new tr.model.Location(args.start.xWorld,args.start.yComponents);var endLoc=new tr.model.Location(args.end.xWorld,args.end.yComponents);return new tr.model.RectAnnotation(startLoc,endLoc);}
-RectAnnotation.prototype={__proto__:tr.model.Annotation.prototype,get startLocation(){return this.startLocation_;},get endLocation(){return this.endLocation_;},toDict:function(){return{typeName:'rect',args:{start:this.startLocation.toDict(),end:this.endLocation.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.RectAnnotationView(viewport,this);}};tr.model.Annotation.register(RectAnnotation,{typeName:'rect'});return{RectAnnotation:RectAnnotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function CommentBoxAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;this.textArea_=undefined;this.styleWidth=250;this.styleHeight=50;this.fontSize=10;this.rightOffset=50;this.topOffset=25;}
-CommentBoxAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,removeTextArea:function(){this.textArea_.parentNode.removeChild(this.textArea_);},draw:function(ctx){var coords=this.annotation_.location.toViewCoordinates(this.viewport_);if(coords.viewX<0){if(this.textArea_)
-this.textArea_.style.visibility='hidden';return;}
-if(!this.textArea_){this.textArea_=document.createElement('textarea');this.textArea_.style.position='absolute';this.textArea_.readOnly=true;this.textArea_.value=this.annotation_.text;this.textArea_.style.zIndex=1;ctx.canvas.parentNode.appendChild(this.textArea_);}
-this.textArea_.style.width=this.styleWidth+'px';this.textArea_.style.height=this.styleHeight+'px';this.textArea_.style.fontSize=this.fontSize+'px';this.textArea_.style.visibility='visible';this.textArea_.style.left=coords.viewX+ctx.canvas.getBoundingClientRect().left+
-this.rightOffset+'px';this.textArea_.style.top=coords.viewY-ctx.canvas.getBoundingClientRect().top-
-this.topOffset+'px';ctx.strokeStyle='rgb(0, 0, 0)';ctx.lineWidth=2;ctx.beginPath();tr.ui.b.drawLine(ctx,coords.viewX,coords.viewY-ctx.canvas.getBoundingClientRect().top,coords.viewX+this.rightOffset,coords.viewY-this.topOffset-
-ctx.canvas.getBoundingClientRect().top);ctx.stroke();}};return{CommentBoxAnnotationView:CommentBoxAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function CommentBoxAnnotation(location,text){tr.model.Annotation.apply(this,arguments);this.location=location;this.text=text;}
-CommentBoxAnnotation.fromDict=function(dict){var args=dict.args;var location=new tr.model.Location(args.location.xWorld,args.location.yComponents);return new tr.model.CommentBoxAnnotation(location,args.text);};CommentBoxAnnotation.prototype={__proto__:tr.model.Annotation.prototype,onRemove:function(){this.view_.removeTextArea();},toDict:function(){return{typeName:'comment_box',args:{text:this.text,location:this.location.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.CommentBoxAnnotationView(viewport,this);}};tr.model.Annotation.register(CommentBoxAnnotation,{typeName:'comment_box'});return{CommentBoxAnnotation:CommentBoxAnnotation};});'use strict';tr.exportTo('tr.model',function(){function HeapEntry(heapDump,leafStackFrame,size){this.heapDump=heapDump;this.leafStackFrame=leafStackFrame;this.size=size;}
-function HeapDump(processMemoryDump,allocatorName){this.processMemoryDump=processMemoryDump;this.allocatorName=allocatorName;this.entries=[];}
-HeapDump.prototype={addEntry:function(leafStackFrame,size){var entry=new HeapEntry(this,leafStackFrame,size);this.entries.push(entry);return entry;}};return{HeapEntry:HeapEntry,HeapDump:HeapDump};});'use strict';tr.exportTo('tr.ui.annotations',function(){function XMarkerAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
-XMarkerAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var viewX=dt.xWorldToView(this.annotation_.timestamp);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,ctx.canvas.height);ctx.strokeStyle=this.annotation_.strokeStyle;ctx.stroke();}};return{XMarkerAnnotationView:XMarkerAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function XMarkerAnnotation(timestamp){tr.model.Annotation.apply(this,arguments);this.timestamp=timestamp;this.strokeStyle='rgba(0, 0, 255, 0.5)';}
-XMarkerAnnotation.fromDict=function(dict){return new XMarkerAnnotation(dict.args.timestamp);}
-XMarkerAnnotation.prototype={__proto__:tr.model.Annotation.prototype,toDict:function(){return{typeName:'xmarker',args:{timestamp:this.timestamp}};},createView_:function(viewport){return new tr.ui.annotations.XMarkerAnnotationView(viewport,this);}};tr.model.Annotation.register(XMarkerAnnotation,{typeName:'xmarker'});return{XMarkerAnnotation:XMarkerAnnotation};});'use strict';tr.exportTo('tr.e.importer',function(){var deepCopy=tr.b.deepCopy;var ColorScheme=tr.b.ColorScheme;function getEventColor(event,opt_customName){if(event.cname)
-return ColorScheme.getColorIdForReservedName(event.cname);else if(opt_customName||event.name){return ColorScheme.getColorIdForGeneralPurposeString(opt_customName||event.name);}}
-var timestampFromUs=tr.b.u.Units.timestampFromUs;var maybeTimestampFromUs=tr.b.u.Units.maybeTimestampFromUs;var PRODUCER='producer';var CONSUMER='consumer';var STEP='step';function TraceEventImporter(model,eventData){this.importPriority=1;this.model_=model;this.events_=undefined;this.sampleEvents_=undefined;this.stackFrameEvents_=undefined;this.systemTraceEvents_=undefined;this.battorData_=undefined;this.eventsWereFromString_=false;this.softwareMeasuredCpuCount_=undefined;this.allAsyncEvents_=[];this.allFlowEvents_=[];this.allObjectEvents_=[];this.traceEventSampleStackFramesByName_={};this.v8ProcessCodeMaps_={};this.v8ProcessRootStackFrame_={};this.allMemoryDumpEvents_={};if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();if(eventData[0]==='['){eventData=eventData.replace(/\s*,\s*$/,'');if(eventData[eventData.length-1]!==']')
-eventData=eventData+']';}
-this.events_=JSON.parse(eventData);this.eventsWereFromString_=true;}else{this.events_=eventData;}
-this.traceAnnotations_=this.events_.traceAnnotations;if(this.events_.traceEvents){var container=this.events_;this.events_=this.events_.traceEvents;this.systemTraceEvents_=container.systemTraceEvents;this.battorData_=container.battorLogAsString;this.sampleEvents_=container.samples;this.stackFrameEvents_=container.stackFrames;if(container.displayTimeUnit){var unitName=container.displayTimeUnit;var unit=tr.b.u.TimeDisplayModes[unitName];if(unit===undefined){throw new Error('Unit '+unitName+' is not supported.');}
-this.model_.intrinsicTimeUnit=unit;}
-var knownFieldNames={battorLogAsString:true,samples:true,stackFrames:true,systemTraceEvents:true,traceAnnotations:true,traceEvents:true};for(var fieldName in container){if(fieldName in knownFieldNames)
-continue;this.model_.metadata.push({name:fieldName,value:container[fieldName]});}}}
-TraceEventImporter.canImport=function(eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();return eventData[0]==='{'||eventData[0]==='[';}
-if(eventData instanceof Array&&eventData.length&&eventData[0].ph)
-return true;if(eventData.traceEvents){if(eventData.traceEvents instanceof Array){if(eventData.traceEvents.length&&eventData.traceEvents[0].ph)
-return true;if(eventData.samples.length&&eventData.stackFrames!==undefined)
-return true;}}
-return false;};TraceEventImporter.prototype={__proto__:tr.importer.Importer.prototype,extractSubtraces:function(){var systemEventsTmp=this.systemTraceEvents_;var battorDataTmp=this.battorData_;this.systemTraceEvents_=undefined;this.battorData_=undefined;var subTraces=systemEventsTmp?[systemEventsTmp]:[];if(battorDataTmp)
-subTraces.push(battorDataTmp);return subTraces;},deepCopyIfNeeded_:function(obj){if(obj===undefined)
-obj={};if(this.eventsWereFromString_)
-return obj;return deepCopy(obj);},deepCopyAlways_:function(obj){if(obj===undefined)
-obj={};return deepCopy(obj);},processAsyncEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allAsyncEvents_.push({sequenceNumber:this.allAsyncEvents_.length,event:event,thread:thread});},processFlowEvent:function(event,opt_slice){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allFlowEvents_.push({refGuid:tr.b.GUID.getLastGuid(),sequenceNumber:this.allFlowEvents_.length,event:event,slice:opt_slice,thread:thread});},processCounterEvent:function(event){var ctr_name;if(event.id!==undefined)
-ctr_name=event.name+'['+event.id+']';else
-ctr_name=event.name;var ctr=this.model_.getOrCreateProcess(event.pid).getOrCreateCounter(event.cat,ctr_name);var reservedColorId=event.cname?getEventColor(event):undefined;if(ctr.numSeries===0){for(var seriesName in event.args){var colorId=reservedColorId||getEventColor(event,ctr.name+'.'+seriesName);ctr.addSeries(new tr.model.CounterSeries(seriesName,colorId));}
-if(ctr.numSeries===0){this.model_.importWarning({type:'counter_parse_error',message:'Expected counter '+event.name+' to have at least one argument to use as a value.'});delete ctr.parent.counters[ctr.name];return;}}
-var ts=timestampFromUs(event.ts);ctr.series.forEach(function(series){var val=event.args[series.name]?event.args[series.name]:0;series.addCounterSample(ts,val);});},processObjectEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allObjectEvents_.push({sequenceNumber:this.allObjectEvents_.length,event:event,thread:thread});},processDurationEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var ts=timestampFromUs(event.ts);if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'duration_parse_error',message:'Timestamps are moving backward.'});return;}
-if(event.ph==='B'){var slice=thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));slice.startStackFrame=this.getStackFrameForEvent_(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){if(event.s!==undefined&&event.s!=='t')
-throw new Error('This should never happen');thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts));slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=undefined;}else{if(!thread.sliceGroup.openSliceCount){this.model_.importWarning({type:'duration_parse_error',message:'E phase event without a matching B phase event.'});return;}
-var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts),getEventColor(event));if(event.name&&slice.title!=event.name){this.model_.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
-slice.title+' in openSlice, and is '+
-event.name+' in endSlice'});}
-slice.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(slice.args,event.args,slice.title);}},mergeArgsInto_:function(dstArgs,srcArgs,eventName){for(var arg in srcArgs){if(dstArgs[arg]!==undefined){this.model_.importWarning({type:'arg_merge_error',message:'Different phases of '+eventName+' provided values for argument '+arg+'.'+' The last provided value will be used.'});}
-dstArgs[arg]=this.deepCopyIfNeeded_(srcArgs[arg]);}},processCompleteEvent:function(event){if(event.cat!==undefined&&event.cat.indexOf('trace_event_overhead')>-1)
-return undefined;var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(event.flow_out){if(event.flow_in)
-event.flowPhase=STEP;else
-event.flowPhase=PRODUCER;}else if(event.flow_in){event.flowPhase=CONSUMER;}
-var slice=thread.sliceGroup.pushCompleteSlice(event.cat,event.name,timestampFromUs(event.ts),maybeTimestampFromUs(event.dur),maybeTimestampFromUs(event.tts),maybeTimestampFromUs(event.tdur),this.deepCopyIfNeeded_(event.args),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=this.getStackFrameForEvent_(event,true);return slice;},processMetadataEvent:function(event){if(event.argsStripped)
-return;if(event.name==='process_name'){var process=this.model_.getOrCreateProcess(event.pid);process.name=event.args.name;}else if(event.name==='process_labels'){var process=this.model_.getOrCreateProcess(event.pid);var labels=event.args.labels.split(',');for(var i=0;i<labels.length;i++)
-process.addLabelIfNeeded(labels[i]);}else if(event.name==='process_sort_index'){var process=this.model_.getOrCreateProcess(event.pid);process.sortIndex=event.args.sort_index;}else if(event.name==='thread_name'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.args.name;}else if(event.name==='thread_sort_index'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.args.sort_index;}else if(event.name==='num_cpus'){var n=event.args.number;if(this.softwareMeasuredCpuCount_!==undefined)
-n=Math.max(n,this.softwareMeasuredCpuCount_);this.softwareMeasuredCpuCount_=n;}else if(event.name==='stackFrames'){var stackFrames=event.args.stackFrames;if(stackFrames===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No stack frames found in a \''+event.name+'\' metadata event'});}else{this.importStackFrames_(stackFrames,'p'+event.pid+':',true);}}else{this.model_.importWarning({type:'metadata_parse_error',message:'Unrecognized metadata name: '+event.name});}},processJitCodeEvent:function(event){if(this.v8ProcessCodeMaps_[event.pid]===undefined)
-this.v8ProcessCodeMaps_[event.pid]=new tr.e.importer.TraceCodeMap();var map=this.v8ProcessCodeMaps_[event.pid];var data=event.args.data;if(event.name==='JitCodeMoved')
-map.moveEntry(data.code_start,data.new_code_start,data.code_len);else
-map.addEntry(data.code_start,data.code_len,data.name,data.script_id);},processInstantEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.processJitCodeEvent(event);return;}
-if(event.s==='t'||event.s===undefined){this.processDurationEvent(event);return;}
-var constructor;switch(event.s){case'g':constructor=tr.model.GlobalInstantEvent;break;case'p':constructor=tr.model.ProcessInstantEvent;break;default:this.model_.importWarning({type:'instant_parse_error',message:'I phase event with unknown "s" field value.'});return;}
-var instantEvent=new constructor(event.cat,event.name,getEventColor(event),timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args));switch(instantEvent.type){case tr.model.InstantEventType.GLOBAL:this.model_.pushInstantEvent(instantEvent);break;case tr.model.InstantEventType.PROCESS:var process=this.model_.getOrCreateProcess(event.pid);process.pushInstantEvent(instantEvent);break;default:throw new Error('Unknown instant event type: '+event.s);}},processV8Sample:function(event){var data=event.args.data;if(data.vm_state==='js'&&!data.stack.length)
-return;var rootStackFrame=this.v8ProcessRootStackFrame_[event.pid];if(!rootStackFrame){rootStackFrame=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8ProcessRootStackFrame_[event.pid]=rootStackFrame;}
-function findChildWithEntryID(stackFrame,entryID){return tr.b.findFirstInArray(stackFrame.children,function(child){return child.entryID===entryID;});}
-var model=this.model_;function addStackFrame(lastStackFrame,entry){var childFrame=findChildWithEntryID(lastStackFrame,entry.id);if(childFrame)
-return childFrame;var frame=new tr.model.StackFrame(lastStackFrame,tr.b.GUID.allocate(),entry.name,ColorScheme.getColorIdForGeneralPurposeString(entry.name),entry.sourceInfo);frame.entryID=entry.id;model.addStackFrame(frame);return frame;}
-var lastStackFrame=rootStackFrame;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){var map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();for(var i=0;i<data.stack.length;i++){var entry=map.lookupEntry(data.stack[i]);if(entry===undefined){entry={id:'unknown',name:'unknown',sourceInfo:undefined};}
-lastStackFrame=addStackFrame(lastStackFrame,entry);}}else{var entry={id:data.vm_state,name:data.vm_state,sourceInfo:undefined};lastStackFrame=addStackFrame(lastStackFrame,entry);}
-var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'V8 Sample',timestampFromUs(event.ts),lastStackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},processTraceSampleEvent:function(event){if(event.name==='V8Sample'){this.processV8Sample(event);return;}
-var stackFrame=this.getStackFrameForEvent_(event);if(stackFrame===undefined){stackFrame=this.traceEventSampleStackFramesByName_[event.name];}
-if(stackFrame===undefined){var id='te-'+tr.b.GUID.allocate();stackFrame=new tr.model.StackFrame(undefined,id,event.name,ColorScheme.getColorIdForGeneralPurposeString(event.name));this.model_.addStackFrame(stackFrame);this.traceEventSampleStackFramesByName_[event.name]=stackFrame;}
-var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'Trace Event Sample',timestampFromUs(event.ts),stackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},getOrCreateMemoryDumpEvents_:function(dumpId){if(this.allMemoryDumpEvents_[dumpId]===undefined){this.allMemoryDumpEvents_[dumpId]={global:undefined,process:[]};}
-return this.allMemoryDumpEvents_[dumpId];},processMemoryDumpEvent:function(event){if(event.id===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:event.ph+' phase event without a dump ID.'});return;}
-var events=this.getOrCreateMemoryDumpEvents_(event.id);if(event.ph==='v'){events.process.push(event);}else if(event.ph==='V'){if(events.global!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple V phase events with the same dump ID.'});return;}
-events.global=event;}else{throw new Error('Invalid memory dump event phase "'+event.ph+'".');}},importEvents:function(){var csr=new tr.ClockSyncRecord('ftrace_importer',0,{});this.model_.clockSyncRecords.push(csr);if(this.stackFrameEvents_){this.importStackFrames_(this.stackFrameEvents_,'g',false);}
-if(this.traceAnnotations_)
-this.importAnnotations_();var events=this.events_;for(var eI=0;eI<events.length;eI++){var event=events[eI];if(event.args==='__stripped__'){event.argsStripped=true;event.args=undefined;}
-if(event.ph==='B'||event.ph==='E'){this.processDurationEvent(event);}else if(event.ph==='X'){var slice=this.processCompleteEvent(event);if(slice!==undefined&&event.bind_id!==undefined)
-this.processFlowEvent(event,slice);}else if(event.ph==='b'||event.ph==='e'||event.ph==='n'||event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){this.processAsyncEvent(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){this.processInstantEvent(event);}else if(event.ph==='P'){this.processTraceSampleEvent(event);}else if(event.ph==='C'){this.processCounterEvent(event);}else if(event.ph==='M'){this.processMetadataEvent(event);}else if(event.ph==='N'||event.ph==='D'||event.ph==='O'){this.processObjectEvent(event);}else if(event.ph==='s'||event.ph==='t'||event.ph==='f'){this.processFlowEvent(event);}else if(event.ph==='v'||event.ph==='V'){this.processMemoryDumpEvent(event);}else{this.model_.importWarning({type:'parse_error',message:'Unrecognized event phase: '+
-event.ph+' ('+event.name+')'});}}
-tr.b.iterItems(this.v8ProcessRootStackFrame_,function(name,frame){frame.removeAllChildren();});},importStackFrames_:function(rawStackFrames,idPrefix,addRootFrame){var model=this.model_;var rootStackFrame;if(addRootFrame){rootStackFrame=new tr.model.StackFrame(undefined,idPrefix,undefined,undefined);model.addStackFrame(rootStackFrame);}else{rootStackFrame=undefined;}
-for(var id in rawStackFrames){var rawStackFrame=rawStackFrames[id];var fullId=idPrefix+id;var textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;var stackFrame=new tr.model.StackFrame(undefined,fullId,rawStackFrame.name,ColorScheme.getColorIdForGeneralPurposeString(textForColor));model.addStackFrame(stackFrame);}
-for(var id in rawStackFrames){var fullId=idPrefix+id;var stackFrame=model.stackFrames[fullId];if(stackFrame===undefined)
-throw new Error('Internal error');var rawStackFrame=rawStackFrames[id];var parentId=rawStackFrame.parent;var parentStackFrame;if(parentId===undefined){parentStackFrame=rootStackFrame;}else{var parentFullId=idPrefix+parentId;parentStackFrame=model.stackFrames[parentFullId];if(parentStackFrame===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentFullId+' for stack frame \''+stackFrame.name+'\' (ID '+fullId+').'});parentStackFrame=rootStackFrame;}}
-stackFrame.parentFrame=parentStackFrame;}},importAnnotations_:function(){for(var id in this.traceAnnotations_){var annotation=tr.model.Annotation.fromDictIfPossible(this.traceAnnotations_[id]);if(!annotation){this.model_.importWarning({type:'annotation_warning',message:'Unrecognized traceAnnotation typeName \"'+
-this.traceAnnotations_[id].typeName+'\"'});continue;}
-this.model_.addAnnotation(annotation);}},finalizeImport:function(){if(this.softwareMeasuredCpuCount_!==undefined){this.model_.kernel.softwareMeasuredCpuCount=this.softwareMeasuredCpuCount_;}
-this.createAsyncSlices_();this.createFlowSlices_();this.createExplicitObjects_();this.createImplicitObjects_();this.createMemoryDumps_();},getStackFrameForEvent_:function(event,opt_lookForEndEvent){var sf;var stack;if(opt_lookForEndEvent){sf=event.esf;stack=event.estack;}else{sf=event.sf;stack=event.stack;}
-if(stack!==undefined&&sf!==undefined){this.model_.importWarning({type:'stack_frame_and_stack_error',message:'Event at '+event.ts+' cannot have both a stack and a stackframe.'});return undefined;}
-if(stack!==undefined)
-return this.model_.resolveStackToStackFrame_(event.pid,stack);if(sf===undefined)
-return undefined;var stackFrame=this.model_.stackFrames['g'+sf];if(stackFrame===undefined){this.model_.importWarning({type:'sample_import_error',message:'No frame for '+sf});return;}
-return stackFrame;},resolveStackToStackFrame_:function(pid,stack){return undefined;},importSampleData:function(){if(!this.sampleEvents_)
-return;var m=this.model_;var events=this.sampleEvents_;if(this.events_.length===0){for(var i=0;i<events.length;i++){var event=events[i];m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);}}
-var threadsByTid={};m.getAllThreads().forEach(function(t){threadsByTid[t.tid]=t;});for(var i=0;i<events.length;i++){var event=events[i];var thread=threadsByTid[event.tid];if(thread===undefined){m.importWarning({type:'sample_import_error',message:'Thread '+events.tid+'not found'});continue;}
-var cpu;if(event.cpu!==undefined)
-cpu=m.kernel.getOrCreateCpu(event.cpu);var stackFrame=this.getStackFrameForEvent_(event);var sample=new tr.model.Sample(cpu,thread,event.name,timestampFromUs(event.ts),stackFrame,event.weight);m.samples.push(sample);}},joinRefs:function(){this.joinObjectRefs_();},createAsyncSlices_:function(){if(this.allAsyncEvents_.length===0)
-return;this.allAsyncEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!==0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var legacyEvents=[];var nestableAsyncEventsByKey={};for(var i=0;i<this.allAsyncEvents_.length;i++){var asyncEventState=this.allAsyncEvents_[i];var event=asyncEventState.event;if(event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){legacyEvents.push(asyncEventState);continue;}
-if(event.cat===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'cat parameter.'});continue;}
-if(event.name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'name parameter.'});continue;}
-if(event.id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require an '+'id parameter.'});continue;}
-var key=event.cat+':'+event.id;if(nestableAsyncEventsByKey[key]===undefined)
-nestableAsyncEventsByKey[key]=[];nestableAsyncEventsByKey[key].push(asyncEventState);}
-this.createLegacyAsyncSlices_(legacyEvents);for(var key in nestableAsyncEventsByKey){var eventStateEntries=nestableAsyncEventsByKey[key];var parentStack=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'){var parentIndex=-1;for(var k=parentStack.length-1;k>=0;--k){if(parentStack[k].event.name===eventStateEntry.event.name){parentIndex=k;break;}}
-if(parentIndex===-1){eventStateEntry.finished=false;}else{parentStack[parentIndex].end=eventStateEntry;while(parentIndex<parentStack.length){parentStack.pop();}}}
-if(parentStack.length>0)
-eventStateEntry.parentEntry=parentStack[parentStack.length-1];if(eventStateEntry.event.ph==='b')
-parentStack.push(eventStateEntry);}
-var topLevelSlices=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'&&eventStateEntry.finished===undefined){continue;}
-var startState=undefined;var endState=undefined;var sliceArgs=eventStateEntry.event.args||{};var sliceError=undefined;if(eventStateEntry.event.ph==='n'){startState=eventStateEntry;endState=eventStateEntry;}else if(eventStateEntry.event.ph==='b'){if(eventStateEntry.end===undefined){eventStateEntry.end=eventStateEntries[eventStateEntries.length-1];sliceError='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async BEGIN event at '+
-eventStateEntry.event.ts+' with name='+
-eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});}else{function concatenateArguments(args1,args2){if(args1.params===undefined||args2.params===undefined)
-return tr.b.concatenateObjects(args1,args2);var args3={};args3.params=tr.b.concatenateObjects(args1.params,args2.params);return tr.b.concatenateObjects(args1,args2,args3);}
-var endArgs=eventStateEntry.end.event.args||{};sliceArgs=concatenateArguments(sliceArgs,endArgs);}
-startState=eventStateEntry;endState=eventStateEntry.end;}else{sliceError='Slice has no matching BEGIN. Start time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async END event at '+
-eventStateEntry.event.ts+' with name='+
-eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});startState=eventStateEntries[0];endState=eventStateEntry;}
-var isTopLevel=(eventStateEntry.parentEntry===undefined);var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(eventStateEntry.event.cat,eventStateEntry.event.name);var thread_start=undefined;var thread_duration=undefined;if(startState.event.tts&&startState.event.use_async_tts){thread_start=timestampFromUs(startState.event.tts);if(endState.event.tts){var thread_end=timestampFromUs(endState.event.tts);thread_duration=thread_end-thread_start;}}
-var slice=new asyncSliceConstructor(eventStateEntry.event.cat,eventStateEntry.event.name,getEventColor(endState.event),timestampFromUs(startState.event.ts),sliceArgs,timestampFromUs(endState.event.ts-startState.event.ts),isTopLevel,thread_start,thread_duration,startState.event.argsStripped);slice.startThread=startState.thread;slice.endThread=endState.thread;slice.startStackFrame=this.getStackFrameForEvent_(startState.event);slice.endStackFrame=this.getStackFrameForEvent_(endState.event);slice.id=key;if(sliceError!==undefined)
-slice.error=sliceError;eventStateEntry.slice=slice;if(isTopLevel){topLevelSlices.push(slice);}else if(eventStateEntry.parentEntry.slice!==undefined){eventStateEntry.parentEntry.slice.subSlices.push(slice);}}
-for(var si=0;si<topLevelSlices.length;si++){topLevelSlices[si].startThread.asyncSliceGroup.push(topLevelSlices[si]);}}},createLegacyAsyncSlices_:function(legacyEvents){if(legacyEvents.length===0)
-return;legacyEvents.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var asyncEventStatesByNameThenID={};for(var i=0;i<legacyEvents.length;i++){var asyncEventState=legacyEvents[i];var event=asyncEventState.event;var name=event.name;if(name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require a name '+' parameter.'});continue;}
-var id=event.id;if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require an id parameter.'});continue;}
-if(event.ph==='S'){if(asyncEventStatesByNameThenID[name]===undefined)
-asyncEventStatesByNameThenID[name]={};if(asyncEventStatesByNameThenID[name][id]){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', a slice of the same id '+id+' was alrady open.'});continue;}
-asyncEventStatesByNameThenID[name][id]=[];asyncEventStatesByNameThenID[name][id].push(asyncEventState);}else{if(asyncEventStatesByNameThenID[name]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' was open.'});continue;}
-if(asyncEventStatesByNameThenID[name][id]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' with id='+id+' was open.'});continue;}
-var events=asyncEventStatesByNameThenID[name][id];events.push(asyncEventState);if(event.ph==='F'){var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,name);var slice=new asyncSliceConstructor(events[0].event.cat,name,getEventColor(events[0].event),timestampFromUs(events[0].event.ts),tr.b.concatenateObjects(events[0].event.args,events[events.length-1].event.args),timestampFromUs(event.ts-events[0].event.ts),true,undefined,undefined,events[0].event.argsStripped);slice.startThread=events[0].thread;slice.endThread=asyncEventState.thread;slice.id=id;var stepType=events[1].event.ph;var isValid=true;for(var j=1;j<events.length-1;++j){if(events[j].event.ph==='T'||events[j].event.ph==='p'){isValid=this.assertStepTypeMatches_(stepType,events[j]);if(!isValid)
-break;}
-if(events[j].event.ph==='S'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
-event.event.name+' with id='+event.event.id+' had a step before the start event.'});continue;}
-if(events[j].event.ph==='F'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
-event.event.name+' with id='+event.event.id+' had a step after the finish event.'});continue;}
-var startIndex=j+(stepType==='T'?0:-1);var endIndex=startIndex+1;var subName=events[j].event.name;if(!events[j].event.argsStripped&&(events[j].event.ph==='T'||events[j].event.ph==='p'))
-subName=subName+':'+events[j].event.args.step;var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,subName);var subSlice=new asyncSliceConstructor(events[0].event.cat,subName,getEventColor(event,subName+j),timestampFromUs(events[startIndex].event.ts),this.deepCopyIfNeeded_(events[j].event.args),timestampFromUs(events[endIndex].event.ts-events[startIndex].event.ts),undefined,undefined,events[startIndex].event.argsStripped);subSlice.startThread=events[startIndex].thread;subSlice.endThread=events[endIndex].thread;subSlice.id=id;slice.subSlices.push(subSlice);}
-if(isValid){slice.startThread.asyncSliceGroup.push(slice);}
-delete asyncEventStatesByNameThenID[name][id];}}}},assertStepTypeMatches_:function(stepType,event){if(stepType!=event.event.ph){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
-event.event.name+' with id='+event.event.id+' had both begin and end steps, which is not allowed.'});return false;}
-return true;},createFlowSlices_:function(){if(this.allFlowEvents_.length===0)
-return;var that=this;function validateFlowEvent(){if(event.name===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require a name parameter.'});return false;}
-if(event.ph==='s'||event.ph==='f'||event.ph==='t'){if(event.id===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require an id parameter.'});return false;}
-return true;}
-if(event.bind_id){if(event.flow_in===undefined&&event.flow_out===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow producer or consumer require flow_in or flow_out.'});return false;}
-return true;}
-return false;}
-function createFlowEvent(thread,event,opt_slice){var startSlice,flowId,flowStartTs;if(event.bind_id){startSlice=opt_slice;flowId=event.bind_id;flowStartTs=timestampFromUs(event.ts+event.dur);}else{var ts=timestampFromUs(event.ts);startSlice=thread.sliceGroup.findSliceAtTs(ts);if(startSlice===undefined)
-return undefined;flowId=event.id;flowStartTs=ts;}
-var flowEvent=new tr.model.FlowEvent(event.cat,flowId,event.name,getEventColor(event),flowStartTs,that.deepCopyAlways_(event.args));flowEvent.startSlice=startSlice;flowEvent.startStackFrame=that.getStackFrameForEvent_(event);flowEvent.endStackFrame=undefined;startSlice.outFlowEvents.push(flowEvent);return flowEvent;}
-function finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent,opt_slice){var endSlice;if(event.bind_id){endSlice=opt_slice;}else{var ts=timestampFromUs(event.ts);if(bindToParent){endSlice=thread.sliceGroup.findSliceAtTs(ts);}else{endSlice=thread.sliceGroup.findNextSliceAfter(ts,refGuid);}
-if(endSlice===undefined)
-return false;}
-endSlice.inFlowEvents.push(flowEvent);flowEvent.endSlice=endSlice;flowEvent.duration=timestampFromUs(event.ts)-flowEvent.start;flowEvent.endStackFrame=that.getStackFrameForEvent_(event);that.mergeArgsInto_(flowEvent.args,event.args,flowEvent.title);return true;}
-function processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice){var flowEvent=flowIdToEvent[event.bind_id];if(flowEvent===undefined){that.model_.importWarning({type:'flow_slice_ordering_error',message:'Flow consumer '+event.bind_id+' does not have '+'a flow producer'});return false;}else if(flowEvent.endSlice){var flowProducer=flowEvent.startSlice;flowEvent=createFlowEvent(undefined,sliceGuidToEvent[flowProducer.guid],flowProducer);}
-var ok=finishFlowEventWith(flowEvent,undefined,event,refGuid,undefined,slice);if(ok){that.model_.flowEvents.push(flowEvent);}else{that.model_.importWarning({type:'flow_slice_end_error',message:'Flow consumer '+event.bind_id+' does not end '+'at an actual slice, so cannot be created.'});return false;}
-return true;}
-function processFlowProducer(flowIdToEvent,flowStatus,event,slice){if(flowIdToEvent[event.bind_id]&&flowStatus[event.bind_id]){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' already seen'});return false;}
-var flowEvent=createFlowEvent(undefined,event,slice);if(!flowEvent){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' does not start'+'a flow'});return false;}
-flowIdToEvent[event.bind_id]=flowEvent;return;}
-this.allFlowEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var flowIdToEvent={};var sliceGuidToEvent={};var flowStatus={};for(var i=0;i<this.allFlowEvents_.length;++i){var data=this.allFlowEvents_[i];var refGuid=data.refGuid;var event=data.event;var thread=data.thread;if(!validateFlowEvent(event))
-continue;if(event.bind_id){var slice=data.slice;sliceGuidToEvent[slice.guid]=event;if(event.flowPhase===PRODUCER){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
-continue;flowStatus[event.bind_id]=true;}
-else{if(!processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice))
-continue;flowStatus[event.bind_id]=false;if(event.flowPhase===STEP){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
-continue;flowStatus[event.bind_id]=true;}}
-continue;}
-var flowEvent;if(event.ph==='s'){if(flowIdToEvent[event.id]){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' already seen when '+'encountering start of flow event.'});continue;}
-flowEvent=createFlowEvent(thread,event);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' does not start '+'at an actual slice, so cannot be created.'});continue;}
-flowIdToEvent[event.id]=flowEvent;}else if(event.ph==='t'||event.ph==='f'){flowEvent=flowIdToEvent[event.id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Found flow phase '+event.ph+' for id: '+event.id+' but no flow start found.'});continue;}
-var bindToParent=event.ph==='t';if(event.ph==='f'){if(event.bp===undefined){if(event.cat.indexOf('input')>-1)
-bindToParent=true;else if(event.cat.indexOf('ipc.flow')>-1)
-bindToParent=true;}else{if(event.bp!=='e'){this.model_.importWarning({type:'flow_slice_bind_point_error',message:'Flow event with invalid binding point (event.bp).'});continue;}
-bindToParent=true;}}
-var ok=finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent);if(ok){that.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'event id '+event.id+' does not end '+'at an actual slice, so cannot be created.'});}
-flowIdToEvent[event.id]=undefined;if(ok&&event.ph==='t'){flowEvent=createFlowEvent(thread,event);flowIdToEvent[event.id]=flowEvent;}}}},createExplicitObjects_:function(){if(this.allObjectEvents_.length===0)
-return;function processEvent(objectEventState){var event=objectEventState.event;var thread=objectEventState.thread;if(event.name===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an name parameter.'});}
-if(event.id===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an id parameter.'});}
-var process=thread.parent;var ts=timestampFromUs(event.ts);var instance;if(event.ph==='N'){try{instance=process.objects.idWasCreated(event.id,event.cat,event.name,ts);}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing create of '+
-event.id+' at ts='+ts+': '+e});return;}}else if(event.ph==='O'){if(event.args.snapshot===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+event.id+' at ts='+ts+': '+'Snapshots must have args: {snapshot: ...}'});return;}
-var snapshot;try{var args=this.deepCopyIfNeeded_(event.args.snapshot);var cat;if(args.cat){cat=args.cat;delete args.cat;}else{cat=event.cat;}
-var baseTypename;if(args.base_type){baseTypename=args.base_type;delete args.base_type;}else{baseTypename=undefined;}
-snapshot=process.objects.addSnapshot(event.id,cat,event.name,ts,args,baseTypename);snapshot.snapshottedOnThread=thread;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing snapshot of '+
-event.id+' at ts='+ts+': '+e});return;}
-instance=snapshot.objectInstance;}else if(event.ph==='D'){try{process.objects.idWasDeleted(event.id,event.cat,event.name,ts);var instanceMap=process.objects.getOrCreateInstanceMap_(event.id);instance=instanceMap.lastInstance;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing delete of '+
-event.id+' at ts='+ts+': '+e});return;}}
-if(instance)
-instance.colorId=getEventColor(event,instance.typeName);}
-this.allObjectEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var allObjectEvents=this.allObjectEvents_;for(var i=0;i<allObjectEvents.length;i++){var objectEventState=allObjectEvents[i];try{processEvent.call(this,objectEventState);}catch(e){this.model_.importWarning({type:'object_parse_error',message:e.message});}}},createImplicitObjects_:function(){tr.b.iterItems(this.model_.processes,function(pid,process){this.createImplicitObjectsForProcess_(process);},this);},createImplicitObjectsForProcess_:function(process){function processField(referencingObject,referencingObjectFieldName,referencingObjectFieldValue,containingSnapshot){if(!referencingObjectFieldValue)
-return;if(referencingObjectFieldValue instanceof
-tr.model.ObjectSnapshot)
-return null;if(referencingObjectFieldValue.id===undefined)
-return;var implicitSnapshot=referencingObjectFieldValue;var rawId=implicitSnapshot.id;var m=/(.+)\/(.+)/.exec(rawId);if(!m)
-throw new Error('Implicit snapshots must have names.');delete implicitSnapshot.id;var name=m[1];var id=m[2];var res;var cat;if(implicitSnapshot.cat!==undefined)
-cat=implicitSnapshot.cat;else
-cat=containingSnapshot.objectInstance.category;var baseTypename;if(implicitSnapshot.base_type)
-baseTypename=implicitSnapshot.base_type;else
-baseTypename=undefined;try{res=process.objects.addSnapshot(id,cat,name,containingSnapshot.ts,implicitSnapshot,baseTypename);}catch(e){this.model_.importWarning({type:'object_snapshot_parse_error',message:'While processing implicit snapshot of '+
-rawId+' at ts='+containingSnapshot.ts+': '+e});return;}
-res.objectInstance.hasImplicitSnapshots=true;res.containingSnapshot=containingSnapshot;res.snapshottedOnThread=containingSnapshot.snapshottedOnThread;referencingObject[referencingObjectFieldName]=res;if(!(res instanceof tr.model.ObjectSnapshot))
-throw new Error('Created object must be instanceof snapshot');return res.args;}
-function iterObject(object,func,containingSnapshot,thisArg){if(!(object instanceof Object))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++){var res=func.call(thisArg,object,i,object[i],containingSnapshot);if(res===null)
-continue;if(res)
-iterObject(res,func,containingSnapshot,thisArg);else
-iterObject(object[i],func,containingSnapshot,thisArg);}
-return;}
-for(var key in object){var res=func.call(thisArg,object,key,object[key],containingSnapshot);if(res===null)
-continue;if(res)
-iterObject(res,func,containingSnapshot,thisArg);else
-iterObject(object[key],func,containingSnapshot,thisArg);}}
-process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(snapshot){if(snapshot.args.id!==undefined)
-throw new Error('args cannot have an id field inside it');iterObject(snapshot.args,processField,snapshot,this);},this);},this);},createMemoryDumps_:function(){tr.b.iterItems(this.allMemoryDumpEvents_,function(id,events){var range=new tr.b.Range();if(events.global!==undefined)
-range.addValue(timestampFromUs(events.global.ts));for(var i=0;i<events.process.length;i++)
-range.addValue(timestampFromUs(events.process[i].ts));var globalMemoryDump=new tr.model.GlobalMemoryDump(this.model_,range.min);globalMemoryDump.duration=range.range;this.model_.globalMemoryDumps.push(globalMemoryDump);if(events.process.length===0){this.model_.importWarning({type:'memory_dump_parse_error',message:'No process memory dumps associated with global memory'+' dump '+id+'.'});}
-var allMemoryAllocatorDumpsByGuid={};var globalMemoryAllocatorDumpsByFullName={};var LEVELS_OF_DETAIL=[undefined,'light','detailed'];var globalLevelOfDetailIndex=undefined;events.process.forEach(function(processEvent){var pid=processEvent.pid;if(pid in globalMemoryDump.processMemoryDumps){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple process memory dumps with pid='+pid+' for dump id '+id+'.'});return;}
-var dumps=processEvent.args.dumps;if(dumps===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'dumps not found in process memory dump for '+'pid='+pid+' and dump id='+id+'.'});return;}
-var process=this.model_.getOrCreateProcess(pid);var processMemoryDump=new tr.model.ProcessMemoryDump(globalMemoryDump,process,timestampFromUs(processEvent.ts));var processLevelOfDetail=dumps.level_of_detail;var processLevelOfDetailIndex=LEVELS_OF_DETAIL.indexOf(processLevelOfDetail);if(processLevelOfDetailIndex<0){this.model_.importWarning({type:'memory_dump_parse_error',message:'unknown level of detail \''+processLevelOfDetail+'\' of process memory dump for pid='+pid+' and dump id='+id+'.'});}else{processMemoryDump.levelOfDetail=processLevelOfDetail;if(globalLevelOfDetailIndex===undefined){globalLevelOfDetailIndex=processLevelOfDetailIndex;}else if(globalLevelOfDetailIndex!==processLevelOfDetailIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail of process memory dumps '+'for dump id='+id+'.'});globalLevelOfDetailIndex=Math.max(globalLevelOfDetailIndex,processLevelOfDetailIndex);}}
-var rawTotals=dumps.process_totals;if(rawTotals!==undefined){processMemoryDump.totals={};if(rawTotals.resident_set_bytes!==undefined){processMemoryDump.totals.residentBytes=parseInt(rawTotals.resident_set_bytes,16);}
-if(rawTotals.peak_resident_set_bytes!==undefined){if(rawTotals.is_peak_rss_resetable===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field peak_resident_set_bytes found'+' but is_peak_rss_resetable not found in'+' process memory dump for pid='+pid+' and dump id='+id+'.'});}
-processMemoryDump.totals.peakResidentBytes=parseInt(rawTotals.peak_resident_set_bytes,16);}
-if(rawTotals.is_peak_rss_resetable!==undefined){if(rawTotals.peak_resident_set_bytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field is_peak_rss_resetable found'+' but peak_resident_set_bytes not found in'+' process memory dump for pid='+pid+' and dump id='+id+'.'});}
-processMemoryDump.totals.arePeakResidentBytesResettable=!!rawTotals.is_peak_rss_resetable;}}
-if(processMemoryDump.totals===undefined||processMemoryDump.totals.residentBytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Mandatory field resident_set_bytes not found in'+' process memory dump for pid='+pid+' and dump id='+id+'.'});}
-if(dumps.process_mmaps&&dumps.process_mmaps.vm_regions){function parseByteStat(rawValue){if(rawValue===undefined)
-return undefined;return parseInt(rawValue,16);}
-processMemoryDump.vmRegions=dumps.process_mmaps.vm_regions.map(function(rawRegion){var byteStats=new tr.model.VMRegionByteStats(parseByteStat(rawRegion.bs.pc),parseByteStat(rawRegion.bs.pd),parseByteStat(rawRegion.bs.sc),parseByteStat(rawRegion.bs.sd),parseByteStat(rawRegion.bs.pss),parseByteStat(rawRegion.bs.sw));return new tr.model.VMRegion(parseInt(rawRegion.sa,16),parseInt(rawRegion.sz,16),rawRegion.pf,rawRegion.mf,byteStats);});}
-var processMemoryAllocatorDumpsByFullName={};if(dumps.allocators!==undefined){tr.b.iterItems(dumps.allocators,function(fullName,rawAllocatorDump){var guid=rawAllocatorDump.guid;if(guid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' from pid='+pid+' does not have a GUID.'});}
-var GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX='global/';var containerMemoryDump;var dstIndex;if(fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)){fullName=fullName.substring(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length);containerMemoryDump=globalMemoryDump;dstIndex=globalMemoryAllocatorDumpsByFullName;}else{containerMemoryDump=processMemoryDump;dstIndex=processMemoryAllocatorDumpsByFullName;}
-var allocatorDump=allMemoryAllocatorDumpsByGuid[guid];if(allocatorDump===undefined){if(fullName in dstIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple GUIDs provided for'+' memory allocator dump '+fullName+': '+
-dstIndex[fullName].guid+', '+guid+' (ignored).'});return;}
-allocatorDump=new tr.model.MemoryAllocatorDump(containerMemoryDump,fullName,guid);dstIndex[fullName]=allocatorDump;if(guid!==undefined)
-allMemoryAllocatorDumpsByGuid[guid]=allocatorDump;}else{if(allocatorDump.containerMemoryDump!==containerMemoryDump){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') dumped in different contexts.'});return;}
-if(allocatorDump.fullName!==fullName){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump with GUID='+guid+' has multiple names: '+allocatorDump.fullName+', '+fullName+' (ignored).'});return;}}
-var attributes=rawAllocatorDump.attrs;if(attributes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' from pid='+pid+' (GUID='+guid+') does not'+' have attributes.'});attributes={};}
-tr.b.iterItems(attributes,function(attrName,attrArgs){if(attrName in allocatorDump.attributes){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for attribute '+
-attrName+' of memory allocator dump '+fullName+' (GUID='+guid+').'});return;}
-var attrValue=tr.model.Attribute.fromDictIfPossible(attrArgs);allocatorDump.addAttribute(attrName,attrValue);},this);},this);}
-processMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(processMemoryAllocatorDumpsByFullName);if(dumps.heaps!==undefined){processMemoryDump.heapDumps=tr.b.mapItems(dumps.heaps,this.parseHeapDump_.bind(this,processMemoryDump));}
-process.memoryDumps.push(processMemoryDump);globalMemoryDump.processMemoryDumps[pid]=processMemoryDump;},this);globalMemoryDump.levelOfDetail=LEVELS_OF_DETAIL[globalLevelOfDetailIndex];globalMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(globalMemoryAllocatorDumpsByFullName);events.process.forEach(function(processEvent){var dumps=processEvent.args.dumps;if(dumps===undefined)
-return;var edges=dumps.allocators_graph;if(edges===undefined)
-return;edges.forEach(function(rawEdge){var sourceGuid=rawEdge.source;var sourceDump=allMemoryAllocatorDumpsByGuid[sourceGuid];if(sourceDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge is missing source memory allocator dump (GUID='+
-sourceGuid+')'});return;}
-var targetGuid=rawEdge.target;var targetDump=allMemoryAllocatorDumpsByGuid[targetGuid];if(targetDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge is missing target memory allocator dump (GUID='+
-targetGuid+')'});return;}
-var importance=rawEdge.importance;var edge=new tr.model.MemoryAllocatorDumpLink(sourceDump,targetDump,importance);switch(rawEdge.type){case'ownership':if(sourceDump.owns!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+sourceDump.fullName+' (GUID='+sourceGuid+') already owns a memory'+' allocator dump ('+
-sourceDump.owns.target.fullName+').'});return;}
-sourceDump.owns=edge;targetDump.ownedBy.push(edge);break;case'retention':sourceDump.retains.push(edge);targetDump.retainedBy.push(edge);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Invalid edge type: '+rawEdge.type+' (source='+sourceGuid+', target='+targetGuid+', importance='+importance+').'});}},this);},this);},this);},inferMemoryAllocatorDumpTree_:function(memoryAllocatorDumpsByFullName){var rootAllocatorDumps=[];var fullNames=Object.keys(memoryAllocatorDumpsByFullName);fullNames.sort();fullNames.forEach(function(fullName){var allocatorDump=memoryAllocatorDumpsByFullName[fullName];while(true){var lastSlashIndex=fullName.lastIndexOf('/');if(lastSlashIndex===-1){rootAllocatorDumps.push(allocatorDump);break;}
-var parentFullName=fullName.substring(0,lastSlashIndex);var parentAllocatorDump=memoryAllocatorDumpsByFullName[parentFullName];var parentAlreadyExisted=true;if(parentAllocatorDump===undefined){parentAlreadyExisted=false;parentAllocatorDump=new tr.model.MemoryAllocatorDump(allocatorDump.containerMemoryDump,parentFullName);memoryAllocatorDumpsByFullName[parentFullName]=parentAllocatorDump;}
-allocatorDump.parent=parentAllocatorDump;parentAllocatorDump.children.push(allocatorDump);if(parentAlreadyExisted)
-break;fullName=parentFullName;allocatorDump=parentAllocatorDump;}},this);return rootAllocatorDumps;},parseHeapDump_:function(processMemoryDump,allocatorName,rawHeapDump){var pid=processMemoryDump.process.pid;var entries=rawHeapDump.entries;if(entries===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing heap entries in a '+allocatorName+' heap dump for pid='+pid+'.'});return undefined;}
-var model=this.model_;var heapDump=new tr.model.HeapDump(processMemoryDump,allocatorName);var idPrefix='p'+pid+':';for(var i=0;i<entries.length;i++){var entry=entries[i];var size=parseInt(entry.size,16);var leafStackFrameIndex=entry.bt;var leafStackFrame;if(leafStackFrameIndex===undefined){leafStackFrame=undefined;}else{var leafStackFrameId=idPrefix+leafStackFrameIndex;leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+leafStackFrameId+') of heap entry '+i+' (size '+size+') in a '+
-allocatorName+' heap dump for pid='+pid+'.'});continue;}}
-heapDump.addEntry(leafStackFrame,size);}
-return heapDump;},joinObjectRefs_:function(){tr.b.iterItems(this.model_.processes,function(pid,process){this.joinObjectRefsForProcess_(process);},this);},joinObjectRefsForProcess_:function(process){var patchupsToApply=[];tr.b.iterItems(process.threads,function(tid,thread){thread.asyncSliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(patchupsToApply,process.objects,'start',item);},this);thread.sliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(patchupsToApply,process.objects,'start',item);},this);},this);process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(item){this.searchItemForIDRefs_(patchupsToApply,process.objects,'ts',item);},this);},this);patchupsToApply.forEach(function(patchup){patchup.object[patchup.field]=patchup.value;});},searchItemForIDRefs_:function(patchupsToApply,objectCollection,itemTimestampField,item){if(!item.args)
-throw new Error('item is missing its args');function handleField(object,fieldName,fieldValue){if(!fieldValue||(!fieldValue.id_ref&&!fieldValue.idRef))
-return;var id=fieldValue.id_ref||fieldValue.idRef;var ts=item[itemTimestampField];var snapshot=objectCollection.getSnapshotAt(id,ts);if(!snapshot)
-return;patchupsToApply.push({object:object,field:fieldName,value:snapshot});}
-function iterObjectFieldsRecursively(object){if(!(object instanceof Object))
-return;if((object instanceof tr.model.ObjectSnapshot)||(object instanceof Float32Array)||(object instanceof tr.b.Quad))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++){handleField(object,i,object[i]);iterObjectFieldsRecursively(object[i]);}
-return;}
-for(var key in object){var value=object[key];handleField(object,key,value);iterObjectFieldsRecursively(value);}}
-iterObjectFieldsRecursively(item.args);}};tr.importer.Importer.register(TraceEventImporter);return{TraceEventImporter:TraceEventImporter};});'use strict';tr.exportTo('tr.e.importer',function(){var GZIP_MEMBER_HEADER_ID_SIZE=3;var GZIP_HEADER_ID1=0x1f;var GZIP_HEADER_ID2=0x8b;var GZIP_DEFLATE_COMPRESSION=8;function GzipImporter(model,eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=JSZip.utils.transformTo('uint8array',eventData);}else if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}else
-throw new Error('Unknown gzip data format');this.model_=model;this.gzipData_=eventData;}
-GzipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
-header=new Uint8Array(eventData.slice(0,GZIP_MEMBER_HEADER_ID_SIZE));else if(typeof(eventData)==='string'||eventData instanceof String){header=eventData.substring(0,GZIP_MEMBER_HEADER_ID_SIZE);header=JSZip.utils.transformTo('uint8array',header);}else
-return false;return header[0]==GZIP_HEADER_ID1&&header[1]==GZIP_HEADER_ID2&&header[2]==GZIP_DEFLATE_COMPRESSION;};GzipImporter.inflateGzipData_=function(data){var position=0;function getByte(){if(position>=data.length)
-throw new Error('Unexpected end of gzip data');return data[position++];}
-function getWord(){var low=getByte();var high=getByte();return(high<<8)+low;}
-function skipBytes(amount){position+=amount;}
-function skipZeroTerminatedString(){while(getByte()!=0){}}
-var id1=getByte();var id2=getByte();if(id1!==GZIP_HEADER_ID1||id2!==GZIP_HEADER_ID2)
-throw new Error('Not gzip data');var compression_method=getByte();if(compression_method!==GZIP_DEFLATE_COMPRESSION)
-throw new Error('Unsupported compression method: '+compression_method);var flags=getByte();var have_header_crc=flags&(1<<1);var have_extra_fields=flags&(1<<2);var have_file_name=flags&(1<<3);var have_comment=flags&(1<<4);skipBytes(4+1+1);if(have_extra_fields){var bytes_to_skip=getWord();skipBytes(bytes_to_skip);}
-if(have_file_name)
-skipZeroTerminatedString();if(have_comment)
-skipZeroTerminatedString();if(have_header_crc)
-getWord();var inflated_data=JSZip.compressions['DEFLATE'].uncompress(data.subarray(position));return JSZip.utils.transformTo('string',inflated_data);},GzipImporter.prototype={__proto__:tr.importer.Importer.prototype,isTraceDataContainer:function(){return true;},extractSubtraces:function(){var eventData=GzipImporter.inflateGzipData_(this.gzipData_);return eventData?[eventData]:[];}};tr.importer.Importer.register(GzipImporter);return{GzipImporter:GzipImporter};});'use strict';tr.exportTo('tr.e.importer',function(){function ZipImporter(model,eventData){if(eventData instanceof ArrayBuffer)
-eventData=new Uint8Array(eventData);this.model_=model;this.eventData_=eventData;}
-ZipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
-header=new Uint8Array(eventData.slice(0,2));else if(typeof(eventData)==='string'||eventData instanceof String)
-header=[eventData.charCodeAt(0),eventData.charCodeAt(1)];else
-return false;return header[0]==='P'.charCodeAt(0)&&header[1]==='K'.charCodeAt(0);};ZipImporter.prototype={__proto__:tr.importer.Importer.prototype,isTraceDataContainer:function(){return true;},extractSubtraces:function(){var zip=new JSZip(this.eventData_);var subtraces=[];for(var idx in zip.files)
-subtraces.push(zip.files[idx].asBinary());return subtraces;}};tr.importer.Importer.register(ZipImporter);return{ZipImporter:ZipImporter};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CsvParser(){};CsvParser.CSV_FIELD_RE_=/^"((?:[^"]|"")*)"|([^,]*)/;CsvParser.DOUBLE_QUOTE_RE_=/""/g;CsvParser.prototype.parseLine=function(line){var fieldRe=CsvParser.CSV_FIELD_RE_;var doubleQuoteRe=CsvParser.DOUBLE_QUOTE_RE_;var pos=0;var endPos=line.length;var fields=[];if(endPos>0){do{var fieldMatch=fieldRe.exec(line.substr(pos));if(typeof fieldMatch[1]==='string'){var field=fieldMatch[1];pos+=field.length+3;fields.push(field.replace(doubleQuoteRe,'"'));}else{var field=fieldMatch[2];pos+=field.length+1;fields.push(field);}}while(pos<=endPos);}
-return fields;};function LogReader(dispatchTable){this.dispatchTable_=dispatchTable;this.lineNum_=0;this.csvParser_=new CsvParser();};LogReader.prototype.printError=function(str){};LogReader.prototype.processLogChunk=function(chunk){this.processLog_(chunk.split('\n'));};LogReader.prototype.processLogLine=function(line){this.processLog_([line]);};LogReader.prototype.processStack=function(pc,func,stack){var fullStack=func?[pc,func]:[pc];var prevFrame=pc;for(var i=0,n=stack.length;i<n;++i){var frame=stack[i];var firstChar=frame.charAt(0);if(firstChar=='+'||firstChar=='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!='o'){fullStack.push(parseInt(frame,16));}}
-return fullStack;};LogReader.prototype.skipDispatch=function(dispatch){return false;};LogReader.prototype.dispatchLogRow_=function(fields){var command=fields[0];if(!(command in this.dispatchTable_))return;var dispatch=this.dispatchTable_[command];if(dispatch===null||this.skipDispatch(dispatch)){return;}
-var parsedFields=[];for(var i=0;i<dispatch.parsers.length;++i){var parser=dispatch.parsers[i];if(parser===null){parsedFields.push(fields[1+i]);}else if(typeof parser=='function'){parsedFields.push(parser(fields[1+i]));}else{parsedFields.push(fields.slice(1+i));break;}}
-dispatch.processor.apply(this,parsedFields);};LogReader.prototype.processLog_=function(lines){for(var i=0,n=lines.length;i<n;++i,++this.lineNum_){var line=lines[i];if(!line){continue;}
-try{var fields=this.csvParser_.parseLine(line);this.dispatchLogRow_(fields);}catch(e){this.printError('line '+(this.lineNum_+1)+': '+
-(e.message||e));}}};return{LogReader:LogReader};});'use strict';tr.exportTo('tr.e.importer.v8',function(){var ColorScheme=tr.b.ColorScheme;function V8LogImporter(model,eventData){this.importPriority=3;this.model_=model;this.logData_=eventData;this.code_map_=new tr.e.importer.v8.CodeMap();this.v8_timer_thread_=undefined;this.v8_thread_=undefined;this.root_stack_frame_=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8_stack_timeline_=new Array();}
-var kV8BinarySuffixes=['/d8','/libv8.so'];var TimerEventDefaultArgs={'V8.Execute':{pause:false,no_execution:false},'V8.External':{pause:false,no_execution:true},'V8.CompileFullCode':{pause:true,no_execution:true},'V8.RecompileSynchronous':{pause:true,no_execution:true},'V8.RecompileParallel':{pause:false,no_execution:false},'V8.CompileEval':{pause:true,no_execution:true},'V8.Parse':{pause:true,no_execution:true},'V8.PreParse':{pause:true,no_execution:true},'V8.ParseLazy':{pause:true,no_execution:true},'V8.GCScavenger':{pause:true,no_execution:true},'V8.GCCompactor':{pause:true,no_execution:true},'V8.GCContext':{pause:true,no_execution:true}};V8LogImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
-return false;return eventData.substring(0,11)=='v8-version,'||eventData.substring(0,12)=='timer-event,'||eventData.substring(0,5)=='tick,'||eventData.substring(0,15)=='shared-library,'||eventData.substring(0,9)=='profiler,'||eventData.substring(0,14)=='code-creation,';};V8LogImporter.prototype={__proto__:tr.importer.Importer.prototype,processTimerEvent_:function(name,start,length){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;length/=1000;var colorId=ColorScheme.getColorIdForGeneralPurposeString(name);var slice=new tr.model.Slice('v8',name,colorId,start,args,length);this.v8_timer_thread_.sliceGroup.pushSlice(slice);},processTimerEventStart_:function(name,start){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;this.v8_timer_thread_.sliceGroup.beginSlice('v8',name,start,args);},processTimerEventEnd_:function(name,end){end/=1000;this.v8_timer_thread_.sliceGroup.endSlice(end);},processCodeCreateEvent_:function(type,kind,address,size,name){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(size,name);code_entry.kind=kind;this.code_map_.addCode(address,code_entry);},processCodeMoveEvent_:function(from,to){this.code_map_.moveCode(from,to);},processCodeDeleteEvent_:function(address){this.code_map_.deleteCode(address);},processSharedLibrary_:function(name,start,end){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(end-start,name);code_entry.kind=-3;for(var i=0;i<kV8BinarySuffixes.length;i++){var suffix=kV8BinarySuffixes[i];if(name.indexOf(suffix,name.length-suffix.length)>=0){code_entry.kind=-1;break;}}
-this.code_map_.addLibrary(start,code_entry);},findCodeKind_:function(kind){for(name in CodeKinds){if(CodeKinds[name].kinds.indexOf(kind)>=0){return CodeKinds[name];}}},processTickEvent_:function(pc,start,unused_x,unused_y,vmstate,stack){start/=1000;function findChildWithEntryID(stackFrame,entryID){for(var i=0;i<stackFrame.children.length;i++){if(stackFrame.children[i].entryID==entryID)
-return stackFrame.children[i];}
-return undefined;}
-var lastStackFrame;if(stack&&stack.length){lastStackFrame=this.root_stack_frame_;stack=stack.reverse();for(var i=0;i<stack.length;i++){if(!stack[i])
-break;var entry=this.code_map_.findEntry(stack[i]);var entryID=entry?entry.id:'Unknown';var childFrame=findChildWithEntryID(lastStackFrame,entryID);if(childFrame===undefined){var entryName=entry?entry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(lastStackFrame,'v8sf-'+tr.b.GUID.allocate(),entryName,ColorScheme.getColorIdForGeneralPurposeString(entryName));lastStackFrame.entryID=entryID;this.model_.addStackFrame(lastStackFrame);}else{lastStackFrame=childFrame;}}}else{var pcEntry=this.code_map_.findEntry(pc);var pcEntryID='v8pc-'+(pcEntry?pcEntry.id:'Unknown');if(this.model_.stackFrames[pcEntryID]===undefined){var pcEntryName=pcEntry?pcEntry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(undefined,pcEntryID,pcEntryName,ColorScheme.getColorIdForGeneralPurposeString(pcEntryName));this.model_.addStackFrame(lastStackFrame);}
-lastStackFrame=this.model_.stackFrames[pcEntryID];}
-var sample=new tr.model.Sample(undefined,this.v8_thread_,'V8 PC',start,lastStackFrame,1);this.model_.samples.push(sample);},processDistortion_:function(distortion_in_picoseconds){distortion_per_entry=distortion_in_picoseconds/1000000;},processPlotRange_:function(start,end){xrange_start_override=start;xrange_end_override=end;},processV8Version_:function(major,minor,build,patch,candidate){},importEvents:function(){var logreader=new tr.e.importer.v8.LogReader({'timer-event':{parsers:[null,parseInt,parseInt],processor:this.processTimerEvent_.bind(this)},'shared-library':{parsers:[null,parseInt,parseInt],processor:this.processSharedLibrary_.bind(this)},'timer-event-start':{parsers:[null,parseInt],processor:this.processTimerEventStart_.bind(this)},'timer-event-end':{parsers:[null,parseInt],processor:this.processTimerEventEnd_.bind(this)},'code-creation':{parsers:[null,parseInt,parseInt,parseInt,null],processor:this.processCodeCreateEvent_.bind(this)},'code-move':{parsers:[parseInt,parseInt],processor:this.processCodeMoveEvent_.bind(this)},'code-delete':{parsers:[parseInt],processor:this.processCodeDeleteEvent_.bind(this)},'tick':{parsers:[parseInt,parseInt,null,null,parseInt,'var-args'],processor:this.processTickEvent_.bind(this)},'distortion':{parsers:[parseInt],processor:this.processDistortion_.bind(this)},'plot-range':{parsers:[parseInt,parseInt],processor:this.processPlotRange_.bind(this)},'v8-version':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt],processor:this.processV8Version_.bind(this)}});this.v8_timer_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(1);this.v8_timer_thread_.name='V8 Timers';this.v8_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(2);this.v8_thread_.name='V8';var lines=this.logData_.split('\n');for(var i=0;i<lines.length;i++){logreader.processLogLine(lines[i]);}
-this.root_stack_frame_.removeAllChildren();function addSlices(slices,thread){for(var i=0;i<slices.length;i++){var duration=slices[i].end-slices[i].start;var slice=new tr.model.Slice('v8',slices[i].name,ColorScheme.getColorIdForGeneralPurposeString(slices[i].name),slices[i].start,{},duration);thread.sliceGroup.pushSlice(slice);addSlices(slices[i].children,thread);}}
-addSlices(this.v8_stack_timeline_,this.v8_thread_);}};tr.importer.Importer.register(V8LogImporter);return{V8LogImporter:V8LogImporter};});'use strict';tr.exportTo('tr.e.importer.etw',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
-Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser:Parser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='68FDD900-4A3E-11D1-84F4-0000F80464E3';var kEventTraceHeaderOpcode=0;function EventTraceParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kEventTraceHeaderOpcode,EventTraceParser.prototype.decodeHeader.bind(this));}
-EventTraceParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version!=2)
-throw new Error('Incompatible EventTrace event version.');var bufferSize=decoder.decodeUInt32();var version=decoder.decodeUInt32();var providerVersion=decoder.decodeUInt32();var numberOfProcessors=decoder.decodeUInt32();var endTime=decoder.decodeUInt64ToString();var timerResolution=decoder.decodeUInt32();var maxFileSize=decoder.decodeUInt32();var logFileMode=decoder.decodeUInt32();var buffersWritten=decoder.decodeUInt32();var startBuffers=decoder.decodeUInt32();var pointerSize=decoder.decodeUInt32();var eventsLost=decoder.decodeUInt32();var cpuSpeed=decoder.decodeUInt32();var loggerName=decoder.decodeUInteger(header.is64);var logFileName=decoder.decodeUInteger(header.is64);var timeZoneInformation=decoder.decodeTimeZoneInformation();var padding=decoder.decodeUInt32();var bootTime=decoder.decodeUInt64ToString();var perfFreq=decoder.decodeUInt64ToString();var startTime=decoder.decodeUInt64ToString();var reservedFlags=decoder.decodeUInt32();var buffersLost=decoder.decodeUInt32();var sessionNameString=decoder.decodeW16String();var logFileNameString=decoder.decodeW16String();return{bufferSize:bufferSize,version:version,providerVersion:providerVersion,numberOfProcessors:numberOfProcessors,endTime:endTime,timerResolution:timerResolution,maxFileSize:maxFileSize,logFileMode:logFileMode,buffersWritten:buffersWritten,startBuffers:startBuffers,pointerSize:pointerSize,eventsLost:eventsLost,cpuSpeed:cpuSpeed,loggerName:loggerName,logFileName:logFileName,timeZoneInformation:timeZoneInformation,bootTime:bootTime,perfFreq:perfFreq,startTime:startTime,reservedFlags:reservedFlags,buffersLost:buffersLost,sessionNameString:sessionNameString,logFileNameString:logFileNameString};},decodeHeader:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(EventTraceParser);return{EventTraceParser:EventTraceParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';var kProcessStartOpcode=1;var kProcessEndOpcode=2;var kProcessDCStartOpcode=3;var kProcessDCEndOpcode=4;var kProcessDefunctOpcode=39;function ProcessParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kProcessStartOpcode,ProcessParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kProcessEndOpcode,ProcessParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kProcessDCStartOpcode,ProcessParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kProcessDCEndOpcode,ProcessParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kProcessDefunctOpcode,ProcessParser.prototype.decodeDefunct.bind(this));}
-ProcessParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>5)
-throw new Error('Incompatible Process event version.');var pageDirectoryBase;if(header.version==1)
-pageDirectoryBase=decoder.decodeUInteger(header.is64);var uniqueProcessKey;if(header.version>=2)
-uniqueProcessKey=decoder.decodeUInteger(header.is64);var processId=decoder.decodeUInt32();var parentId=decoder.decodeUInt32();var sessionId;var exitStatus;if(header.version>=1){sessionId=decoder.decodeUInt32();exitStatus=decoder.decodeInt32();}
-var directoryTableBase;if(header.version>=3)
-directoryTableBase=decoder.decodeUInteger(header.is64);var flags;if(header.version>=4)
-flags=decoder.decodeUInt32();var userSID=decoder.decodeSID(header.is64);var imageFileName;if(header.version>=1)
-imageFileName=decoder.decodeString();var commandLine;if(header.version>=2)
-commandLine=decoder.decodeW16String();var packageFullName;var applicationId;if(header.version>=4){packageFullName=decoder.decodeW16String();applicationId=decoder.decodeW16String();}
-var exitTime;if(header.version==5&&header.opcode==kProcessDefunctOpcode)
-exitTime=decoder.decodeUInt64ToString();return{pageDirectoryBase:pageDirectoryBase,uniqueProcessKey:uniqueProcessKey,processId:processId,parentId:parentId,sessionId:sessionId,exitStatus:exitStatus,directoryTableBase:directoryTableBase,flags:flags,userSID:userSID,imageFileName:imageFileName,commandLine:commandLine,packageFullName:packageFullName,applicationId:applicationId,exitTime:exitTime};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
-process.name=fields.imageFileName;return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended'))
-throw new Error('Process clash detected.');process.name=fields.imageFileName;return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDefunct:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(ProcessParser);return{ProcessParser:ProcessParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadStartOpcode=1;var kThreadEndOpcode=2;var kThreadDCStartOpcode=3;var kThreadDCEndOpcode=4;var kThreadCSwitchOpcode=36;function ThreadParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kThreadStartOpcode,ThreadParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kThreadEndOpcode,ThreadParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kThreadDCStartOpcode,ThreadParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kThreadDCEndOpcode,ThreadParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kThreadCSwitchOpcode,ThreadParser.prototype.decodeCSwitch.bind(this));}
-ThreadParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>3)
-throw new Error('Incompatible Thread event version.');var processId=decoder.decodeUInt32();var threadId=decoder.decodeUInt32();var stackBase;var stackLimit;var userStackBase;var userStackLimit;var affinity;var startAddr;var win32StartAddr;var tebBase;var subProcessTag;var basePriority;var pagePriority;var ioPriority;var threadFlags;var waitMode;if(header.version==1){if(header.opcode==kThreadStartOpcode||header.opcode==kThreadDCStartOpcode){stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);startAddr=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);waitMode=decoder.decodeInt8();decoder.skip(3);}}else{stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);if(header.version==2)
-startAddr=decoder.decodeUInteger(header.is64);else
-affinity=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);tebBase=decoder.decodeUInteger(header.is64);subProcessTag=decoder.decodeUInt32();if(header.version==3){basePriority=decoder.decodeUInt8();pagePriority=decoder.decodeUInt8();ioPriority=decoder.decodeUInt8();threadFlags=decoder.decodeUInt8();}}
-return{processId:processId,threadId:threadId,stackBase:stackBase,stackLimit:stackLimit,userStackBase:userStackBase,userStackLimit:userStackLimit,affinity:affinity,startAddr:startAddr,win32StartAddr:win32StartAddr,tebBase:tebBase,subProcessTag:subProcessTag,waitMode:waitMode,basePriority:basePriority,pagePriority:pagePriority,ioPriority:ioPriority,threadFlags:threadFlags};},decodeCSwitchFields:function(header,decoder){if(header.version!=2)
-throw new Error('Incompatible Thread event version.');var newThreadId=decoder.decodeUInt32();var oldThreadId=decoder.decodeUInt32();var newThreadPriority=decoder.decodeInt8();var oldThreadPriority=decoder.decodeInt8();var previousCState=decoder.decodeUInt8();var spareByte=decoder.decodeInt8();var oldThreadWaitReason=decoder.decodeInt8();var oldThreadWaitMode=decoder.decodeInt8();var oldThreadState=decoder.decodeInt8();var oldThreadWaitIdealProcessor=decoder.decodeInt8();var newThreadWaitTime=decoder.decodeUInt32();var reserved=decoder.decodeUInt32();return{newThreadId:newThreadId,oldThreadId:oldThreadId,newThreadPriority:newThreadPriority,oldThreadPriority:oldThreadPriority,previousCState:previousCState,spareByte:spareByte,oldThreadWaitReason:oldThreadWaitReason,oldThreadWaitMode:oldThreadWaitMode,oldThreadState:oldThreadState,oldThreadWaitIdealProcessor:oldThreadWaitIdealProcessor,newThreadWaitTime:newThreadWaitTime,reserved:reserved};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeCSwitch:function(header,decoder){var fields=this.decodeCSwitchFields(header,decoder);var cpu=this.importer.getOrCreateCpu(header.cpu);var new_thread=this.importer.getThreadFromWindowsTid(fields.newThreadId);var new_thread_name;if(new_thread&&new_thread.userFriendlyName){new_thread_name=new_thread.userFriendlyName;}else{var new_process_id=this.importer.getPidFromWindowsTid(fields.newThreadId);var new_process=this.model.getProcess(new_process_id);var new_process_name;if(new_process)
-new_process_name=new_process.name;else
-new_process_name='Unknown process';new_thread_name=new_process_name+' (tid '+fields.newThreadId+')';}
-cpu.switchActiveThread(header.timestamp,{},fields.newThreadId,new_thread_name,fields);return true;}};Parser.register(ThreadParser);return{ThreadParser:ThreadParser};});'use strict';tr.exportTo('tr.b',function(){function Base64(){}
-function b64ToUint6(nChr){if(nChr>64&&nChr<91)
-return nChr-65;if(nChr>96&&nChr<123)
-return nChr-71;if(nChr>47&&nChr<58)
-return nChr+4;if(nChr===43)
-return 62;if(nChr===47)
-return 63;return 0;}
-Base64.getDecodedBufferLength=function(input){return input.length*3+1>>2;}
-Base64.EncodeArrayBufferToString=function(input){var binary='';var bytes=new Uint8Array(input);var len=bytes.byteLength;for(var i=0;i<len;i++)
-binary+=String.fromCharCode(bytes[i]);return btoa(binary);}
-Base64.DecodeToTypedArray=function(input,output){var nInLen=input.length;var nOutLen=nInLen*3+1>>2;var nMod3=0;var nMod4=0;var nUint24=0;var nOutIdx=0;if(nOutLen>output.byteLength)
-throw new Error('Output buffer too small to decode.');for(var nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(input.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){output.setUint8(nOutIdx,nUint24>>>(16>>>nMod3&24)&255);}
-nUint24=0;}}
-return nOutIdx-1;}
-return{Base64:Base64};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var kThreadGuid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadDCStartOpcode=3;function Decoder(){this.payload_=new DataView(new ArrayBuffer(256));};Decoder.prototype={__proto__:Object.prototype,reset:function(base64_payload){var decoded_size=tr.b.Base64.getDecodedBufferLength(base64_payload);if(decoded_size>this.payload_.byteLength)
-this.payload_=new DataView(new ArrayBuffer(decoded_size));tr.b.Base64.DecodeToTypedArray(base64_payload,this.payload_);this.position_=0;},skip:function(length){this.position_+=length;},decodeUInt8:function(){var result=this.payload_.getUint8(this.position_,true);this.position_+=1;return result;},decodeUInt16:function(){var result=this.payload_.getUint16(this.position_,true);this.position_+=2;return result;},decodeUInt32:function(){var result=this.payload_.getUint32(this.position_,true);this.position_+=4;return result;},decodeUInt64ToString:function(){var low=this.decodeUInt32();var high=this.decodeUInt32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},decodeInt8:function(){var result=this.payload_.getInt8(this.position_,true);this.position_+=1;return result;},decodeInt16:function(){var result=this.payload_.getInt16(this.position_,true);this.position_+=2;return result;},decodeInt32:function(){var result=this.payload_.getInt32(this.position_,true);this.position_+=4;return result;},decodeInt64ToString:function(){return this.decodeUInt64ToString();},decodeUInteger:function(is64){if(is64)
-return this.decodeUInt64ToString();return this.decodeUInt32();},decodeString:function(){var str='';while(true){var c=this.decodeUInt8();if(!c)
-return str;str=str+String.fromCharCode(c);}},decodeW16String:function(){var str='';while(true){var c=this.decodeUInt16();if(!c)
-return str;str=str+String.fromCharCode(c);}},decodeFixedW16String:function(length){var old_position=this.position_;var str='';for(var i=0;i<length;i++){var c=this.decodeUInt16();if(!c)
-break;str=str+String.fromCharCode(c);}
-this.position_=old_position+2*length;return str;},decodeBytes:function(length){var bytes=[];for(var i=0;i<length;++i){var c=this.decodeUInt8();bytes.push(c);}
-return bytes;},decodeSID:function(is64){var pSid=this.decodeUInteger(is64);var attributes=this.decodeUInt32();if(is64)
-this.decodeUInt32();var revision=this.decodeUInt8();var subAuthorityCount=this.decodeUInt8();this.decodeUInt16();this.decodeUInt32();if(revision!=1)
-throw'Invalid SID revision: could not decode the SID structure.';var sid=this.decodeBytes(4*subAuthorityCount);return{pSid:pSid,attributes:attributes,sid:sid};},decodeSystemTime:function(){var wYear=this.decodeInt16();var wMonth=this.decodeInt16();var wDayOfWeek=this.decodeInt16();var wDay=this.decodeInt16();var wHour=this.decodeInt16();var wMinute=this.decodeInt16();var wSecond=this.decodeInt16();var wMilliseconds=this.decodeInt16();return{wYear:wYear,wMonth:wMonth,wDayOfWeek:wDayOfWeek,wDay:wDay,wHour:wHour,wMinute:wMinute,wSecond:wSecond,wMilliseconds:wMilliseconds};},decodeTimeZoneInformation:function(){var bias=this.decodeUInt32();var standardName=this.decodeFixedW16String(32);var standardDate=this.decodeSystemTime();var standardBias=this.decodeUInt32();var daylightName=this.decodeFixedW16String(32);var daylightDate=this.decodeSystemTime();var daylightBias=this.decodeUInt32();return{bias:bias,standardName:standardName,standardDate:standardDate,standardBias:standardBias,daylightName:daylightName,daylightDate:daylightDate,daylightBias:daylightBias};}};function EtwImporter(model,events){this.importPriority=3;this.model_=model;this.events_=events;this.handlers_={};this.decoder_=new Decoder();this.walltime_=undefined;this.ticks_=undefined;this.is64bit_=undefined;this.tidsToPid_={};var allTypeInfos=tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();this.parsers_=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);}
-EtwImporter.canImport=function(events){if(!events.hasOwnProperty('name')||!events.hasOwnProperty('content')||events.name!=='ETW'){return false;}
-return true;};EtwImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},createThreadIfNeeded:function(pid,tid){this.tidsToPid_[tid]=pid;},removeThreadIfPresent:function(tid){this.tidsToPid_[tid]=undefined;},getPidFromWindowsTid:function(tid){if(tid==0)
-return 0;var pid=this.tidsToPid_[tid];if(pid==undefined){return 0;}
-return pid;},getThreadFromWindowsTid:function(tid){var pid=this.getPidFromWindowsTid(tid);var process=this.model_.getProcess(pid);if(!process)
-return undefined;return process.getThread(tid);},getOrCreateCpu:function(cpuNumber){var cpu=this.model_.kernel.getOrCreateCpu(cpuNumber);return cpu;},importEvents:function(isSecondaryImport){this.events_.content.forEach(this.parseInfo.bind(this));if(this.walltime_==undefined||this.ticks_==undefined)
-throw Error('Cannot find clock sync information in the system trace.');if(this.is64bit_==undefined)
-throw Error('Cannot determine pointer size of the system trace.');this.events_.content.forEach(this.parseEvent.bind(this));},importTimestamp:function(timestamp){var ts=parseInt(timestamp,16);return(ts-this.walltime_+this.ticks_)/1000.;},parseInfo:function(event){if(event.hasOwnProperty('guid')&&event.hasOwnProperty('walltime')&&event.hasOwnProperty('tick')&&event.guid==='ClockSync'){this.walltime_=parseInt(event.walltime,16);this.ticks_=parseInt(event.tick,16);}
-if(this.is64bit_==undefined&&event.hasOwnProperty('guid')&&event.hasOwnProperty('op')&&event.hasOwnProperty('ver')&&event.hasOwnProperty('payload')&&event.guid===kThreadGuid&&event.op==kThreadDCStartOpcode){var decoded_size=tr.b.Base64.getDecodedBufferLength(event.payload);if(event.ver==1){if(decoded_size>=52)
-this.is64bit_=true;else
-this.is64bit_=false;}else if(event.ver==2){if(decoded_size>=64)
-this.is64bit_=true;else
-this.is64bit_=false;}else if(event.ver==3){if(decoded_size>=60)
-this.is64bit_=true;else
-this.is64bit_=false;}}
-return true;},parseEvent:function(event){if(!event.hasOwnProperty('guid')||!event.hasOwnProperty('op')||!event.hasOwnProperty('ver')||!event.hasOwnProperty('cpu')||!event.hasOwnProperty('ts')||!event.hasOwnProperty('payload')){return false;}
-var timestamp=this.importTimestamp(event.ts);var header={guid:event.guid,opcode:event.op,version:event.ver,cpu:event.cpu,timestamp:timestamp,is64:this.is64bit_};var decoder=this.decoder_;decoder.reset(event.payload);var handler=this.getEventHandler(header.guid,header.opcode);if(!handler)
-return false;if(!handler(header,decoder)){this.model_.importWarning({type:'parse_error',message:'Malformed '+header.guid+' event ('+text+')'});return false;}
-return true;},registerEventHandler:function(guid,opcode,handler){if(this.handlers_[guid]==undefined)
-this.handlers_[guid]=[];this.handlers_[guid][opcode]=handler;},getEventHandler:function(guid,opcode){if(this.handlers_[guid]==undefined)
-return undefined;return this.handlers_[guid][opcode];}};tr.importer.Importer.register(EtwImporter);return{EtwImporter:EtwImporter};});'use strict';tr.exportTo('tr.e.importer',function(){function Trace2HTMLImporter(model,events){this.importPriority=0;}
-Trace2HTMLImporter.subtraces_=[];function _extractEventsFromHTML(text){Trace2HTMLImporter.subtraces_=[];var r=new tr.importer.SimpleLineReader(text);while(true){if(!r.advanceToLineMatching(new RegExp('^<\s*script id="viewer-data" '+'type="(application\/json|text\/plain)">$')))
-break;r.beginSavingLines();if(!r.advanceToLineMatching(/^<\/\s*script>$/))
-return failure;var raw_events=r.endSavingLinesAndGetResult();raw_events=raw_events.slice(1,raw_events.length-1);var data64=raw_events.join('\n');var buffer=new ArrayBuffer(tr.b.Base64.getDecodedBufferLength(data64));var len=tr.b.Base64.DecodeToTypedArray(data64,new DataView(buffer));Trace2HTMLImporter.subtraces_.push(buffer.slice(0,len));}}
-function _canImportFromHTML(text){if(/^<!DOCTYPE html>/.test(text)===false)
-return false;_extractEventsFromHTML(text);if(Trace2HTMLImporter.subtraces_.length===0)
-return false;return true;}
-Trace2HTMLImporter.canImport=function(events){return _canImportFromHTML(events);};Trace2HTMLImporter.prototype={__proto__:tr.importer.Importer.prototype,isTraceDataContainer:function(){return true;},extractSubtraces:function(){return Trace2HTMLImporter.subtraces_;},importEvents:function(){}};tr.importer.Importer.register(Trace2HTMLImporter);return{Trace2HTMLImporter:Trace2HTMLImporter};});'use strict';tr.exportTo('tr.e.net',function(){var AsyncSlice=tr.model.AsyncSlice;function NetAsyncSlice(){AsyncSlice.apply(this,arguments);this.isTitleComputed_=false;}
-NetAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return'NetLog';},get title(){if(this.isTitleComputed_||!this.isTopLevel){return this.title_;}
-var getUrl=function(slice){if(slice.args!==undefined&&slice.args.params!==undefined&&slice.args.params.url!==undefined){return slice.args.params.url;}
-if(slice.subSlices===undefined||slice.subSlices.length===0)
-return undefined;for(var i=0;i<slice.subSlices.length;i++){var result=getUrl(slice.subSlices[i]);if(result!==undefined)
-return result;}
-return undefined;};var url=getUrl(this);if(url!==undefined&&url.length>0){this.title_=url;}else if(this.args!==undefined&&this.args.source_type!==undefined){this.title_=this.args.source_type;}
-this.isTitleComputed_=true;return this.title_;},set title(title){this.title_=title;}};AsyncSlice.register(NetAsyncSlice,{categoryParts:['netlog','disabled-by-default-netlog']});return{NetAsyncSlice:NetAsyncSlice};});'use strict';tr.exportTo('tr.e.chrome',function(){var KNOWN_PROPERTIES={children:1,name:1,address:1};function LayoutObject(snapshot,args){this.snapshot_=snapshot;this.id_=args.address;this.name_=args.name;this.childLayoutObjects_=[];this.otherProperties_={};if(args.children){args.children.forEach(function(child){this.childLayoutObjects_.push(new LayoutObject(snapshot,child));}.bind(this));}
-for(var property in args){if(!KNOWN_PROPERTIES[property])
-this.otherProperties_[property]=args[property];}}
-LayoutObject.prototype={get snapshot(){return this.snapshot_;},get id(){return this.id_;},get name(){return this.name_;},get hasChildLayoutObjects(){return this.childLayoutObjects_.length>0;},get childLayoutObjects(){return this.childLayoutObjects_;},traverseTree:function(cb,opt_this){cb.call(opt_this,this);if(!this.hasChildLayoutObjects)
-return;this.childLayoutObjects.forEach(function(child){child.traverseTree(cb,opt_this);});},get otherPropertyNames(){var names=[];for(var name in this.otherProperties_){names.push(name);}
-return names;},getProperty:function(name){return this.otherProperties_[name];},get previousSnapshotLayoutObject(){if(!this.snapshot.previousSnapshot)
-return undefined;return this.snapshot.previousSnapshot.getLayoutObjectById(this.id);},get nextSnapshotLayoutObject(){if(!this.snapshot.nextSnapshot)
-return undefined;return this.snapshot.nextSnapshot.getLayoutObjectById(this.id);}};return{LayoutObject:LayoutObject};});'use strict';tr.exportTo('tr.e.audits',function(){var MAIN_FRAMETIME_TYPE='main_frametime_type';var IMPL_FRAMETIME_TYPE='impl_frametime_type';var MAIN_RENDERING_STATS='BenchmarkInstrumentation::MainThreadRenderingStats';var IMPL_RENDERING_STATS='BenchmarkInstrumentation::ImplThreadRenderingStats';function getSlicesIntersectingRange(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRange(slice.start,slice.end))
-slicesInFilterRange.push(slice);}
-return slicesInFilterRange;}
-function ChromeProcessHelper(modelHelper,process){this.modelHelper=modelHelper;this.process=process;}
-ChromeProcessHelper.prototype={get pid(){return this.process.pid;},getFrameEventsInRange:function(frametimeType,range){var titleToGet;if(frametimeType==MAIN_FRAMETIME_TYPE)
-titleToGet=MAIN_RENDERING_STATS;else
-titleToGet=IMPL_RENDERING_STATS;var frameEvents=[];this.process.iterateAllEvents(function(event){if(event.title!==titleToGet)
-return;if(range.intersectsExplicitRange(event.start,event.end))
-frameEvents.push(event);});frameEvents.sort(function(a,b){return a.start-b.start});return frameEvents;}};function getFrametimeDataFromEvents(frameEvents){var frametimeData=[];for(var i=1;i<frameEvents.length;i++){var diff=frameEvents[i].start-frameEvents[i-1].start;frametimeData.push({'x':frameEvents[i].start,'frametime':diff});}
-return frametimeData;}
-return{ChromeProcessHelper:ChromeProcessHelper,MAIN_FRAMETIME_TYPE:MAIN_FRAMETIME_TYPE,IMPL_FRAMETIME_TYPE:IMPL_FRAMETIME_TYPE,MAIN_RENDERING_STATS:MAIN_RENDERING_STATS,IMPL_RENDERING_STATS:IMPL_RENDERING_STATS,getSlicesIntersectingRange:getSlicesIntersectingRange,getFrametimeDataFromEvents:getFrametimeDataFromEvents};});'use strict';tr.exportTo('tr.e.audits',function(){function ChromeBrowserHelper(modelHelper,process){tr.e.audits.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrBrowserMain');}
-ChromeBrowserHelper.isBrowserProcess=function(process){return!!process.findAtMostOneThreadNamed('CrBrowserMain');};ChromeBrowserHelper.prototype={__proto__:tr.e.audits.ChromeProcessHelper.prototype,get rendererHelpers(){return this.modelHelper.rendererHelpers;},getLoadingEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title.indexOf('WebContentsImpl Loading')===0&&rangeOfInterest.intersectsExplicitRange(slice.start,slice.end);});},getCommitProvisionalLoadEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title==='RenderFrameImpl::didCommitProvisionalLoad'&&rangeOfInterest.intersectsExplicitRange(slice.start,slice.end);});},get hasLatencyEvents(){var hasLatency=false;this.modelHelper.model.getAllThreads().some(function(thread){thread.iterateAllEvents(function(event){if(!event.isTopLevel)
-return;if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice))
-return;hasLatency=true;});return hasLatency;});return hasLatency;},getLatencyEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return(slice.title.indexOf('InputLatency')===0)&&rangeOfInterest.intersectsExplicitRange(slice.start,slice.end);});},getAllAsyncSlicesMatching:function(pred,opt_this){var events=[];this.iterAllThreads(function(thread){thread.iterateAllEvents(function(slice){if(pred.call(opt_this,slice))
-events.push(slice);});});return events;},getAllNetworkEventsInRange:function(rangeOfInterest){var networkEvents=[];this.modelHelper.model.getAllThreads().forEach(function(thread){thread.asyncSliceGroup.slices.forEach(function(slice){var match=false;if(slice.category=='net'||slice.category=='disabled-by-default-netlog'||slice.category=='netlog'){match=true;}
-if(!match)
-return;if(rangeOfInterest.intersectsExplicitRange(slice.start,slice.end))
-networkEvents.push(slice);});});return networkEvents;},iterAllThreads:function(func,opt_this){tr.b.iterItems(this.process.threads,function(tid,thread){func.call(opt_this,thread);});tr.b.iterItems(this.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;tr.b.iterItems(rendererProcess.threads,function(tid,thread){func.call(opt_this,thread);});},this);}};return{ChromeBrowserHelper:ChromeBrowserHelper};});'use strict';tr.exportTo('tr.e.audits',function(){function ChromeGpuHelper(modelHelper,process){tr.e.audits.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.isGpuProcess=function(process){if(process.findAtMostOneThreadNamed('CrBrowserMain')||process.findAtMostOneThreadNamed('CrRendererMain'))
-return false;return process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.prototype={__proto__:tr.e.audits.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;}};return{ChromeGpuHelper:ChromeGpuHelper};});'use strict';tr.exportTo('tr.e.audits',function(){function ChromeRendererHelper(modelHelper,process){tr.e.audits.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)
-return false;if(t.name.indexOf('CompositorTileWorker')===0)
-return true;if(t.name.indexOf('CompositorRasterWorker')===0)
-return true;return false;});};ChromeRendererHelper.isRenderProcess=function(process){if(!process.findAtMostOneThreadNamed('CrRendererMain'))
-return false;if(!process.findAtMostOneThreadNamed('Compositor'))
-return false;return true;};ChromeRendererHelper.prototype={__proto__:tr.e.audits.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;}};return{ChromeRendererHelper:ChromeRendererHelper};});'use strict';tr.exportTo('tr.e.audits',function(){function findChromeBrowserProcess(model){var browserProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.e.audits.ChromeBrowserHelper.isBrowserProcess(process))
-return;browserProcesses.push(process);},this);if(browserProcesses.length===0)
-return undefined;if(browserProcesses.length>1)
-return undefined;return browserProcesses[0];}
-function findChromeRenderProcesses(model){var rendererProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.e.audits.ChromeRendererHelper.isRenderProcess(process))
-return;rendererProcesses.push(process);});return rendererProcesses;}
-function findChromeGpuProcess(model){var gpuProcesses=model.getAllProcesses().filter(tr.e.audits.ChromeGpuHelper.isGpuProcess);if(gpuProcesses.length!=1)
-return undefined;return gpuProcesses[0];}
-function ChromeModelHelper(model){this.model_=model;this.browserProcess_=findChromeBrowserProcess(model);if(this.browserProcess_){this.browserHelper_=new tr.e.audits.ChromeBrowserHelper(this,this.browserProcess_);}else{this.browserHelper_=undefined;}
-var gpuProcess=findChromeGpuProcess(model);if(gpuProcess){this.gpuHelper_=new tr.e.audits.ChromeGpuHelper(this,gpuProcess);}else{this.gpuHelper_=undefined;}
-var rendererProcesses_=findChromeRenderProcesses(model);this.rendererHelpers_={};rendererProcesses_.forEach(function(renderProcess){var rendererHelper=new tr.e.audits.ChromeRendererHelper(this,renderProcess);this.rendererHelpers_[rendererHelper.pid]=rendererHelper;},this);}
-ChromeModelHelper.supportsModel=function(model){if(findChromeBrowserProcess(model)!==undefined)
-return true;if(findChromeRenderProcesses(model).length)
-return true;return false;}
-ChromeModelHelper.prototype={get pid(){throw new Error('woah');},get process(){throw new Error('woah');},get model(){return this.model_;},get browserProcess(){return this.browserProcess_;},get browserHelper(){return this.browserHelper_;},get gpuHelper(){return this.gpuHelper_;},get rendererHelpers(){return this.rendererHelpers_;}};return{ChromeModelHelper:ChromeModelHelper};});'use strict';tr.exportTo('tr.e.cc',function(){var AsyncSlice=tr.model.AsyncSlice;var EventSet=tr.model.EventSet;var UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';var ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';var BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';var END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';var MAIN_RENDERER_THREAD_NAME='CrRendererMain';var COMPOSITOR_THREAD_NAME='Compositor';var POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';var IPC_FLOW_EVENT='disabled-by-default-ipc.flow';var INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent)
-this.determineModernTypeName_();}
-InputLatencyAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get isLegacyEvent(){return this.title==='InputLatency';},get typeName(){if(!this.typeName_)
-this.determineLegacyTypeName_();return this.typeName_;},checkTypeName_:function(){if(!this.typeName_)
-throw'Unable to determine typeName';var found=false;for(var type_name in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[type_name]){found=true;break;}}
-if(!found)
-this.typeName_=INPUT_EVENT_TYPE_NAMES.UNKNOWN;},determineModernTypeName_:function(){var lastColonIndex=this.title.lastIndexOf(':');if(lastColonIndex<0)
-return;var characterAfterLastColonIndex=lastColonIndex+1;this.typeName_=this.title.slice(characterAfterLastColonIndex);this.checkTypeName_();},determineLegacyTypeName_:function(){this.iterateAllDescendents(function(subSlice){var subSliceIsAInputLatencyAsyncSlice=(subSlice instanceof InputLatencyAsyncSlice);if(!subSliceIsAInputLatencyAsyncSlice)
-return;if(!subSlice.typeName)
-return;if(this.typeName_&&subSlice.typeName_){var subSliceHasDifferentTypeName=(this.typeName_!==subSlice.typeName_);if(subSliceHasDifferentTypeName){throw'InputLatencyAsyncSlice.determineLegacyTypeName_() '+' found multiple typeNames';}}
-this.typeName_=subSlice.typeName_;},this);if(!this.typeName_)
-throw'InputLatencyAsyncSlice.determineLegacyTypeName_() failed';this.checkTypeName_();},getRendererHelper:function(sourceSlices){var traceModel=this.startThread.parent.model;if(!tr.e.audits.ChromeModelHelper.supportsModel(traceModel))
-return undefined;var mainThread=undefined;var compositorThread=undefined;for(var i in sourceSlices){if(sourceSlices[i].parentContainer.name===MAIN_RENDERER_THREAD_NAME)
-mainThread=sourceSlices[i].parentContainer;else if(sourceSlices[i].parentContainer.name===COMPOSITOR_THREAD_NAME)
-compositorThread=sourceSlices[i].parentContainer;if(mainThread&&compositorThread)
-break;}
-var modelHelper=new tr.e.audits.ChromeModelHelper(traceModel);var rendererHelpers=modelHelper.rendererHelpers;var pids=Object.keys(rendererHelpers);for(var i=0;i<pids.length;i++){var pid=pids[i];var rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread)
-return rendererHelper;}
-return undefined;},addEntireSliceHierarchy:function(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents:function(flowEvents){var slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);var newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1)
-slices.push(newSource);},this);var lastFlowEvent=flowEvents[flowEvents.length-1];var lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1)
-slices.push(lastSource);return slices;},addScrollUpdateEvents:function(rendererHelper){if(!rendererHelper||!rendererHelper.compositorThread)
-return;var compositorThread=rendererHelper.compositorThread;var gestureScrollUpdateStart=this.start;var gestureScrollUpdateEnd=this.end;var allCompositorAsyncSlices=compositorThread.asyncSliceGroup.slices;for(var i in allCompositorAsyncSlices){var slice=allCompositorAsyncSlices[i];if(slice.title!=='Latency::ScrollUpdate')
-continue;var parentId=slice.args.data.INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.sequence_number;if(parentId===undefined){if(slice.start<gestureScrollUpdateStart||slice.start>=gestureScrollUpdateEnd)
-continue;}else{if(parseInt(parentId)!==parseInt(this.id))
-continue;}
-slice.associatedEvents.forEach(function(event){this.associatedEvents_.push(event);},this);break;}},belongToOtherInputs:function(slice,flowEvents){var fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)
-return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)
-return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1)
-fromOtherInputs=true;}},this);},this);return fromOtherInputs;},triggerOtherInputs:function(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0)
-return false;var flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice)
-return false;var endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents))
-return true;return false;},followSubsequentSlices:function(event,queue,visited,flowEvents){var stopFollowing=false;var inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)
-return;if(slice.title==='TaskQueueManager::RunTask')
-return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame')
-return;if(slice.title==='Scheduler::ScheduleBeginImplFrameDeadline'){if(this.triggerOtherInputs(slice,flowEvents))
-return;}
-if(slice.title==='CompositorImpl::PostComposite'){if(this.triggerOtherInputs(slice,flowEvents))
-return;}
-if(slice.title==='InputRouterImpl::ProcessInputEventAck')
-inputAck=true;if(inputAck&&slice.title==='InputRouterImpl::FilterAndSendWebInputEvent')
-stopFollowing=true;this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice:function(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);var nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw:function(beginImplFrame,visited){var pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){var nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices:function(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start)
-return a.start-b.start;return a.guid-b.guid;});},addRasterizationEvents:function(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)
-return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads)
-return;var rasterWorkerThreads=rendererHelper.rasterWorkerThreads;var prepare_tile_id=prepareTiles.args.prepare_tiles_id;var pendingEventQueue=[];if(sortedRasterizerSlices.length===0)
-this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);var numFinishedTasks=0;var RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';var IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';var FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(var i=0;i<sortedRasterizerSlices.length;i++){var task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepare_tile_id)
-this.addEntireSliceHierarchy(task.mostTopLevelSlice);}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)
-break;}}}
-while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followSubsequentSlices(event,pendingEventQueue,visited,flowEvents);}},addOtherCausallyRelatedEvents:function(rendererHelper,sourceSlices,flowEvents,sortedRasterizerSlices){var pendingEventQueue=[];var visitedEvents=new EventSet();var beginImplFrame=undefined;var prepareTiles=undefined;var sortedRasterizerSlices=[];sourceSlices.forEach(function(sourceSlice){if(!visitedEvents.contains(sourceSlice)){visitedEvents.push(sourceSlice);pendingEventQueue.push(sourceSlice);}},this);while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followCurrentSlice(event,pendingEventQueue,visitedEvents);this.followSubsequentSlices(event,pendingEventQueue,visitedEvents,flowEvents);var COMPOSITOR_PREPARE_TILES='TileManager::PrepareTiles';prepareTiles=event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);if(prepareTiles)
-this.addRasterizationEvents(prepareTiles,rendererHelper,visitedEvents,flowEvents,sortedRasterizerSlices);var COMPOSITOR_ON_BIFD='Scheduler::OnBeginImplFrameDeadline';beginImplFrame=event.findDescendentSlice(COMPOSITOR_ON_BIFD);if(beginImplFrame)
-this.backtraceFromDraw(beginImplFrame,visitedEvents);}
-var INPUT_GSU='InputLatency::GestureScrollUpdate';if(this.title===INPUT_GSU)
-this.addScrollUpdateEvents(rendererHelper);},get associatedEvents(){if(this.associatedEvents_.length!==0)
-return this.associatedEvents_;var modelIndices=this.startThread.parent.model.modelIndices;var flowEvents=modelIndices.getFlowEventsWithId(this.id);if(flowEvents.length===0)
-return this.associatedEvents_;var sourceSlices=this.addDirectlyAssociatedEvents(flowEvents);var rendererHelper=this.getRendererHelper(sourceSlices);this.addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents);return this.associatedEvents_;},get inputLatency(){if(!('data'in this.args))
-return undefined;var data=this.args.data;if(!(END_COMP_NAME in data))
-return undefined;var latency=0;var endTime=data[END_COMP_NAME].time;if(ORIGINAL_COMP_NAME in data){latency=endTime-data[ORIGINAL_COMP_NAME].time;}else if(UI_COMP_NAME in data){latency=endTime-data[UI_COMP_NAME].time;}else if(BEGIN_COMP_NAME in data){latency=endTime-data[BEGIN_COMP_NAME].time;}else{throw new Error('No valid begin latency component');}
-return latency;}};var eventTypeNames=['Char','ContextMenu','GestureClick','GestureFlingCancel','GestureFlingStart','GestureScrollBegin','GestureScrollEnd','GestureScrollUpdate','GestureShowPress','GestureTap','GestureTapCancel','GestureTapDown','GesturePinchBegin','GesturePinchEnd','GesturePinchUpdate','KeyDown','KeyUp','MouseDown','MouseEnter','MouseLeave','MouseMove','MouseUp','MouseWheel','RawKeyDown','ScrollUpdate','TouchCancel','TouchEnd','TouchMove','TouchStart'];var allTypeNames=['InputLatency'];eventTypeNames.forEach(function(eventTypeName){allTypeNames.push('InputLatency:'+eventTypeName);allTypeNames.push('InputLatency::'+eventTypeName);});AsyncSlice.register(InputLatencyAsyncSlice,{typeNames:allTypeNames,categoryParts:['latencyInfo']});return{InputLatencyAsyncSlice:InputLatencyAsyncSlice,INPUT_EVENT_TYPE_NAMES:INPUT_EVENT_TYPE_NAMES};});'use strict';tr.exportTo('tr.e.rail',function(){var ColorScheme=tr.b.ColorScheme;var COMFORT_IMPORTANCE=2;var ALL_RAIL_TYPE_NAMES=['rail_response','rail_animate','rail_idle','rail_load'];var DOES_RAIL_TYPE_NAME_EXIST={};ALL_RAIL_TYPE_NAMES.forEach(function(railTypeName){DOES_RAIL_TYPE_NAME_EXIST[railTypeName]=true;});var RAIL_ORDER=[];ALL_RAIL_TYPE_NAMES.forEach(function(railTypeName){RAIL_ORDER.push(railTypeName.toUpperCase());RAIL_ORDER.push(userFriendlyRailTypeName(railTypeName).toUpperCase());});function RAILInteractionRecord(parentModel,title,railTypeName,start,duration){if(!DOES_RAIL_TYPE_NAME_EXIST[railTypeName])
-throw new Error(railTypeName+' is not listed in ALL_RAIL_TYPE_NAMES');var colorId=ColorScheme.getColorIdForReservedName(railTypeName);this.railTypeName_=railTypeName;this.name='';tr.model.InteractionRecord.call(this,parentModel,title,colorId,start,duration);}
-RAILInteractionRecord.prototype={__proto__:tr.model.InteractionRecord.prototype,updateArgs:function(){var args={};var layoutSlices=this.associatedEvents.filter(function(event){return event.title==='FrameView::layout';});var timeInLayout=tr.b.Statistics.sum(layoutSlices,function(event){return event.duration;});args['layoutInfo']={'timeInLayout':timeInLayout};this.args=args;},get railTypeName(){return this.railTypeName_;},get railScore(){var comfort=this.normalizedUserComfort;var efficiency=this.normalizedEfficiency;return weightedAverage2(comfort,efficiency,COMFORT_IMPORTANCE);},get normalizedUserComfort(){throw new Error('Not implemented');},get rawCpuMs(){var cpuMs=0;this.associatedEvents.forEach(function(event){if(event.cpuSelfTime)
-cpuMs+=event.cpuSelfTime;});return cpuMs;},get normalizedCpuEfficiency(){var minCpuMs=this.duration*this.minCpuFraction;var maxCpuMs=this.duration*this.maxCpuFraction;var normalizedCpu=tr.b.normalize(this.rawCpuMs,minCpuMs,maxCpuMs);return 1-tr.b.clamp(normalizedCpu,0,1);},get minCpuFraction(){return 0.5;},get maxCpuFraction(){return 1.5;},get normalizedEfficiency(){return this.normalizedCpuEfficiency;}};function computeNormalizedComfort(value,opts){if(typeof value!=='number')
-throw new Error('value must be a number');opts.exponentialBase=opts.exponentialBase||10;if(opts.exponentialBase<=1)
-throw new Error('exponentialBase must be greater than 1');opts.minComfortLinear=opts.minComfortLinear||0.2;if(opts.minComfortLinear<=0||opts.minComfortLinear>=1)
-throw new Error('minComfortLinear must be between 0 and 1 exclusive');opts.maxComfortLinear=opts.maxComfortLinear||0.9;if(opts.maxComfortLinear<=0||opts.maxComfortLinear>=1)
-throw new Error('maxComfortLinear must be between 0 and 1 exclusive');opts.logarithmicScale=opts.logarithmicScale||100;if(opts.logarithmicScale<=0)
-throw new Error('logarithmicScale must be positive');if(opts.minValueExponential>=opts.minValueLinear)
-throw new Error('minValueExponential must be less than minValueLinear');if(opts.minValueLinear>=opts.minValueLogarithmic)
-throw new Error('minValueLinear must be less than minValueLogarithmic');if(opts.minValueLogarithmic>=opts.maxValue)
-throw new Error('minValueLogarithmic must be less than maxValue');['minValueLinear','minValueExponential','minValueLogarithmic','maxValue','exponentialBase','minComfortLinear','maxComfortLinear','logarithmicScale'].forEach(function(opt){if(typeof opts[opt]!=='number')
-throw new Error(opt+' must be a number');});if(value<opts.minValueExponential)
-return 0;if(value<opts.minValueLinear){function computeRawComfort(value){return Math.pow(opts.exponentialBase,value);}
-return computeNormalizedComfortInternal(value,opts.minValueExponential,opts.minValueLinear,0,opts.minComfortLinear,computeRawComfort);}
-if(value<opts.minValueLogarithmic){function computeRawComfort(value){return value;}
-return computeNormalizedComfortInternal(value,opts.minValueLinear,opts.minValueLogarithmic,opts.minComfortLinear,opts.maxComfortLinear,computeRawComfort);}
-if(value<opts.maxValue){function computeRawComfort(value){return Math.log1p(opts.logarithmicScale*value);}
-return computeNormalizedComfortInternal(value,opts.minValueLogarithmic,opts.maxValue,opts.maxComfortLinear,1,computeRawComfort);}
-return 1;}
-function computeNormalizedComfortInternal(value,minValue,maxValue,minScore,maxScore,computeRawComfort){var normalizedValue=tr.b.normalize(value,minValue,maxValue);var rawComfort=computeRawComfort(normalizedValue);var minComfort=computeRawComfort(0);var maxComfort=computeRawComfort(1);var normalizedComfort=tr.b.normalize(rawComfort,minComfort,maxComfort);normalizedComfort=tr.b.lerp(normalizedComfort,minScore,maxScore);return tr.b.clamp(normalizedComfort,minScore,maxScore);}
-function weightedAverage2(x,y,opt_apriori){var numerator=0;var denominator=0;var xWeight=(opt_apriori||1)*Math.exp(1-x);numerator+=xWeight*x;denominator+=xWeight;var yWeight=Math.exp(1-y);numerator+=yWeight*y;denominator+=yWeight;return numerator/denominator;}
-function userFriendlyRailTypeName(railTypeName){if(railTypeName.length<6||railTypeName.indexOf('rail_')!=0)
-return railTypeName;return railTypeName[5].toUpperCase()+railTypeName.slice(6);}
-function railCompare(name1,name2){var i1=RAIL_ORDER.indexOf(name1.toUpperCase());var i2=RAIL_ORDER.indexOf(name2.toUpperCase());if(i1==-1&&i2==-1)
-return name1.localeCompare(name2);if(i1==-1)
-return 1;if(i2==-1)
-return-1;return i1-i2;}
-return{RAILInteractionRecord:RAILInteractionRecord,computeNormalizedComfort:computeNormalizedComfort,weightedAverage2:weightedAverage2,userFriendlyRailTypeName:userFriendlyRailTypeName,railCompare:railCompare,ALL_RAIL_TYPE_NAMES:ALL_RAIL_TYPE_NAMES};});'use strict';tr.exportTo('tr.e.rail',function(){function IdleInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Idle','rail_idle',start,duration);}
-IdleInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get normalizedUserComfort(){return 1;},get minCpuFraction(){return 0.1;},get maxCpuFraction(){return 1;}};return{IdleInteractionRecord:IdleInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){var COMFORT_LATENCY_REGIONS=[1000,5000,20000,60000];function LoadInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Load','rail_load',start,duration);this.renderProcessId=undefined;this.routingId=undefined;this.parentRoutingId=undefined;}
-LoadInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get normalizedUserComfort(){return 1-tr.e.rail.computeNormalizedComfort(this.duration,{minValueExponential:COMFORT_LATENCY_REGIONS[0],minValueLinear:COMFORT_LATENCY_REGIONS[1],minValueLogarithmic:COMFORT_LATENCY_REGIONS[2],maxValue:COMFORT_LATENCY_REGIONS[3]});}};return{LoadInteractionRecord:LoadInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){var COMFORT_FPS_REGIONS=[60,40,30,10];var LONG_FRAME_MS=50;var COMFORT_JANK_REGIONS=[0.05,0.1,0.2,0.3];function AnimationInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Animation','rail_animate',start,duration);this.frameEvents_=undefined;}
-AnimationInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get frameEvents(){if(this.frameEvents_)
-return this.frameEvents_;this.frameEvents_=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event.title===tr.e.audits.IMPL_RENDERING_STATS)
-this.frameEvents_.push(event);},this);return this.frameEvents_;},get normalizedUserComfort(){return tr.e.rail.weightedAverage2(this.normalizedJankComfort,this.normalizedFPSComfort);},get normalizedFPSComfort(){var durationSeconds=this.duration/1000;var avgSpf=durationSeconds/this.frameEvents.length;return 1-tr.e.rail.computeNormalizedComfort(avgSpf,{minValueExponential:1/COMFORT_FPS_REGIONS[0],minValueLinear:1/COMFORT_FPS_REGIONS[1],minValueLogarithmic:1/COMFORT_FPS_REGIONS[2],maxValue:1/COMFORT_FPS_REGIONS[3]});},get normalizedJankComfort(){var frameTimestamps=this.frameEvents.toArray().map(function(event){return event.start;});var absolute=false;var discrepancy=tr.b.Statistics.timestampsDiscrepancy(frameTimestamps,absolute);return 1-tr.e.rail.computeNormalizedComfort(discrepancy,{minValueExponential:COMFORT_JANK_REGIONS[0],minValueLinear:COMFORT_JANK_REGIONS[1],minValueLogarithmic:COMFORT_JANK_REGIONS[2],maxValue:COMFORT_JANK_REGIONS[3]});}};return{AnimationInteractionRecord:AnimationInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){var COMFORT_LATENCY_REGIONS=[150,300,1000,5000];function ResponseInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Response','rail_response',start,duration);}
-ResponseInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get normalizedUserComfort(){return 1-tr.e.rail.computeNormalizedComfort(this.duration,{minValueExponential:COMFORT_LATENCY_REGIONS[0],minValueLinear:COMFORT_LATENCY_REGIONS[1],minValueLogarithmic:COMFORT_LATENCY_REGIONS[2],maxValue:COMFORT_LATENCY_REGIONS[3]});}};return{ResponseInteractionRecord:ResponseInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){function ProtoIR(irType,name){this.irType=irType;this.names=new Set(name?[name]:undefined);this.start=Infinity;this.end=-Infinity;this.associatedEvents=new tr.model.EventSet();}
-ProtoIR.RESPONSE_TYPE='r';ProtoIR.ANIMATION_TYPE='a';ProtoIR.IGNORED_TYPE='ignored';ProtoIR.prototype={get isValid(){return this.end>this.start;},containsTypeNames:function(typeNames){for(var i=0;i<this.associatedEvents.length;++i){if(typeNames.indexOf(this.associatedEvents[i].typeName)>=0)
+times.sort(function(x,y){return x-y;});return times;}};tr.c.Auditor.register(VSyncAuditor);return{VSyncAuditor:VSyncAuditor};});'use strict';tr.exportTo('tr.importer',function(){function EmptyImporter(events){this.importPriority=0;};EmptyImporter.canImport=function(eventData){if(eventData instanceof Array&&eventData.length==0)
+return true;if(typeof(eventData)==='string'||eventData instanceof String){return eventData.length==0;}
+return false;};EmptyImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EmptyImporter';}};tr.importer.Importer.register(EmptyImporter);return{EmptyImporter:EmptyImporter};});'use strict';tr.exportTo('tr.model.um',function(){function AnimationExpectation(parentModel,initiatorTitle,start,duration){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.frameEvents_=undefined;}
+AnimationExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:AnimationExpectation,get frameEvents(){if(this.frameEvents_)
+return this.frameEvents_;this.frameEvents_=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event.title===tr.model.helpers.IMPL_RENDERING_STATS)
+this.frameEvents_.push(event);},this);return this.frameEvents_;}};tr.model.um.UserExpectation.register(AnimationExpectation,{stageTitle:'Animation',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_animation')});return{AnimationExpectation:AnimationExpectation};});'use strict';tr.exportTo('tr.importer',function(){function ProtoExpectation(irType,name){this.irType=irType;this.names=new Set(name?[name]:undefined);this.start=Infinity;this.end=-Infinity;this.associatedEvents=new tr.model.EventSet();this.isAnimationBegin=false;}
+ProtoExpectation.RESPONSE_TYPE='r';ProtoExpectation.ANIMATION_TYPE='a';ProtoExpectation.IGNORED_TYPE='ignored';ProtoExpectation.prototype={get isValid(){return this.end>this.start;},containsTypeNames:function(typeNames){for(var i=0;i<this.associatedEvents.length;++i){if(typeNames.indexOf(this.associatedEvents[i].typeName)>=0)
 return true;}
 return false;},containsSliceTitle:function(title){for(var i=0;i<this.associatedEvents.length;++i){if(title===this.associatedEvents[i].title)
 return true;}
-return false;},getIRConstructor:function(){switch(this.irType){case ProtoIR.RESPONSE_TYPE:return tr.e.rail.ResponseInteractionRecord;case ProtoIR.ANIMATION_TYPE:return tr.e.rail.AnimationInteractionRecord;}
-return undefined;},createInteractionRecord:function(model){if(!this.isValid){console.error('Invalid ProtoIR: '+this.debug()+' File a bug with this trace!');return undefined;}
-var constructor=this.getIRConstructor();if(constructor===undefined)
-return undefined;var ir=new constructor(model,this.start,this.end-this.start);var names=[];this.names.forEach(function(name){names.push(name);});ir.name=names.sort().join(',');ir.sourceEvents.addEventSet(this.associatedEvents);function pushAssociatedEvents(event){ir.associatedEvents.push(event);if(event.associatedEvents)
+return false;},createInteractionRecord:function(model){if(!this.isValid){console.error('Invalid ProtoExpectation: '+this.debug()+' File a bug with this trace!');return undefined;}
+var initiatorTitles=[];this.names.forEach(function(name){initiatorTitles.push(name);});initiatorTitles=initiatorTitles.sort().join(',');var duration=this.end-this.start;var ir=undefined;switch(this.irType){case ProtoExpectation.RESPONSE_TYPE:ir=new tr.model.um.ResponseExpectation(model,initiatorTitles,this.start,duration,this.isAnimationBegin);break;case ProtoExpectation.ANIMATION_TYPE:ir=new tr.model.um.AnimationExpectation(model,initiatorTitles,this.start,duration);break;}
+if(!ir)
+return undefined;ir.sourceEvents.addEventSet(this.associatedEvents);function pushAssociatedEvents(event){ir.associatedEvents.push(event);if(event.associatedEvents)
 ir.associatedEvents.addEventSet(event.associatedEvents);}
 this.associatedEvents.forEach(function(event){pushAssociatedEvents(event);if(event.subSlices)
-event.subSlices.forEach(pushAssociatedEvents);});return ir;},merge:function(other){other.names.forEach(function(name){this.names.add(name);}.bind(this));this.associatedEvents.addEventSet(other.associatedEvents);this.start=Math.min(this.start,other.start);this.end=Math.max(this.end,other.end);},pushEvent:function(event){this.start=Math.min(this.start,event.start);this.end=Math.max(this.end,event.end);this.associatedEvents.push(event);},containsTimestampInclusive:function(timestamp){return(this.start<=timestamp)&&(timestamp<=this.end);},intersects:function(other){return(other.start<this.end)&&(other.end>this.start);},isNear:function(event,threshold){return(this.end+threshold)>event.start;},debug:function(){var debugString=this.irType+'(';debugString+=parseInt(this.start)+' ';debugString+=parseInt(this.end);this.associatedEvents.forEach(function(event){debugString+=' '+event.typeName;});return debugString+')';}};return{ProtoIR:ProtoIR};});'use strict';tr.exportTo('tr.model',function(){function getAssociatedEvents(irs){var allAssociatedEvents=new tr.model.EventSet();irs.forEach(function(ir){ir.associatedEvents.forEach(function(event){if(event instanceof tr.model.FlowEvent)
+event.subSlices.forEach(pushAssociatedEvents);});return ir;},merge:function(other){other.names.forEach(function(name){this.names.add(name);}.bind(this));this.associatedEvents.addEventSet(other.associatedEvents);this.start=Math.min(this.start,other.start);this.end=Math.max(this.end,other.end);if(other.isAnimationBegin)
+this.isAnimationBegin=true;},pushEvent:function(event){this.start=Math.min(this.start,event.start);this.end=Math.max(this.end,event.end);this.associatedEvents.push(event);},containsTimestampInclusive:function(timestamp){return(this.start<=timestamp)&&(timestamp<=this.end);},intersects:function(other){return(other.start<this.end)&&(other.end>this.start);},isNear:function(event,threshold){return(this.end+threshold)>event.start;},debug:function(){var debugString=this.irType+'(';debugString+=parseInt(this.start)+' ';debugString+=parseInt(this.end);this.associatedEvents.forEach(function(event){debugString+=' '+event.typeName;});return debugString+')';}};return{ProtoExpectation:ProtoExpectation};});'use strict';tr.exportTo('tr.importer',function(){var ProtoExpectation=tr.importer.ProtoExpectation;var INPUT_TYPE=tr.e.cc.INPUT_EVENT_TYPE_NAMES;var KEYBOARD_TYPE_NAMES=[INPUT_TYPE.CHAR,INPUT_TYPE.KEY_DOWN_RAW,INPUT_TYPE.KEY_DOWN,INPUT_TYPE.KEY_UP];var MOUSE_RESPONSE_TYPE_NAMES=[INPUT_TYPE.CLICK,INPUT_TYPE.CONTEXT_MENU];var MOUSE_WHEEL_TYPE_NAMES=[INPUT_TYPE.MOUSE_WHEEL];var MOUSE_DRAG_TYPE_NAMES=[INPUT_TYPE.MOUSE_DOWN,INPUT_TYPE.MOUSE_MOVE,INPUT_TYPE.MOUSE_UP];var TAP_TYPE_NAMES=[INPUT_TYPE.TAP,INPUT_TYPE.TAP_CANCEL,INPUT_TYPE.TAP_DOWN];var PINCH_TYPE_NAMES=[INPUT_TYPE.PINCH_BEGIN,INPUT_TYPE.PINCH_END,INPUT_TYPE.PINCH_UPDATE];var FLING_TYPE_NAMES=[INPUT_TYPE.FLING_CANCEL,INPUT_TYPE.FLING_START];var TOUCH_TYPE_NAMES=[INPUT_TYPE.TOUCH_END,INPUT_TYPE.TOUCH_MOVE,INPUT_TYPE.TOUCH_START];var SCROLL_TYPE_NAMES=[INPUT_TYPE.SCROLL_BEGIN,INPUT_TYPE.SCROLL_END,INPUT_TYPE.SCROLL_UPDATE];var ALL_HANDLED_TYPE_NAMES=[].concat(KEYBOARD_TYPE_NAMES,MOUSE_RESPONSE_TYPE_NAMES,MOUSE_WHEEL_TYPE_NAMES,MOUSE_DRAG_TYPE_NAMES,PINCH_TYPE_NAMES,TAP_TYPE_NAMES,FLING_TYPE_NAMES,TOUCH_TYPE_NAMES,SCROLL_TYPE_NAMES);var RENDERER_FLING_TITLE='InputHandlerProxy::HandleGestureFling::started';var CSS_ANIMATION_TITLE='Animation';var INPUT_MERGE_THRESHOLD_MS=200;var ANIMATION_MERGE_THRESHOLD_MS=32;var MOUSE_WHEEL_THRESHOLD_MS=40;var MOUSE_MOVE_THRESHOLD_MS=40;var KEYBOARD_IR_NAME='Keyboard';var MOUSE_IR_NAME='Mouse';var MOUSEWHEEL_IR_NAME='MouseWheel';var TAP_IR_NAME='Tap';var PINCH_IR_NAME='Pinch';var FLING_IR_NAME='Fling';var TOUCH_IR_NAME='Touch';var SCROLL_IR_NAME='Scroll';var CSS_IR_NAME='CSS';function compareEvents(x,y){if(x.start!==y.start)
+return x.start-y.start;if(x.end!==y.end)
+return x.end-y.end;if(x.guid&&y.guid)
+return x.guid-y.guid;return 0;}
+function forEventTypesIn(events,typeNames,cb,opt_this){events.forEach(function(event){if(typeNames.indexOf(event.typeName)>=0){cb.call(opt_this,event);}});}
+function causedFrame(event){for(var i=0;i<event.associatedEvents.length;++i){if(event.associatedEvents[i].title===tr.model.helpers.IMPL_RENDERING_STATS)
+return true;}
+return false;}
+function getSortedInputEvents(modelHelper){var inputEvents=[];var browserProcess=modelHelper.browserHelper.process;var mainThread=browserProcess.findAtMostOneThreadNamed('CrBrowserMain');mainThread.asyncSliceGroup.iterateAllEvents(function(slice){if(!slice.isTopLevel)
+return;if(!(slice instanceof tr.e.cc.InputLatencyAsyncSlice))
+return;if(isNaN(slice.start)||isNaN(slice.duration)||isNaN(slice.end))
+return;inputEvents.push(slice);});return inputEvents.sort(compareEvents);}
+function findProtoExpectations(modelHelper,sortedInputEvents){var protoExpectations=[];var handlers=[handleKeyboardEvents,handleMouseResponseEvents,handleMouseWheelEvents,handleMouseDragEvents,handleTapResponseEvents,handlePinchEvents,handleFlingEvents,handleTouchEvents,handleScrollEvents,handleCSSAnimations];handlers.forEach(function(handler){protoExpectations.push.apply(protoExpectations,handler(modelHelper,sortedInputEvents));});protoExpectations.sort(compareEvents);return protoExpectations;}
+function handleKeyboardEvents(modelHelper,sortedInputEvents){var protoExpectations=[];forEventTypesIn(sortedInputEvents,KEYBOARD_TYPE_NAMES,function(event){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,KEYBOARD_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
+function handleMouseResponseEvents(modelHelper,sortedInputEvents){var protoExpectations=[];forEventTypesIn(sortedInputEvents,MOUSE_RESPONSE_TYPE_NAMES,function(event){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
+function handleMouseWheelEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var prevEvent_=undefined;forEventTypesIn(sortedInputEvents,MOUSE_WHEEL_TYPE_NAMES,function(event){var prevEvent=prevEvent_;prevEvent_=event;if(currentPE&&(prevEvent.start+MOUSE_WHEEL_THRESHOLD_MS)>=event.start){if(currentPE.irType===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,MOUSEWHEEL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+return;}
+currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSEWHEEL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);});return protoExpectations;}
+function handleMouseDragEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var mouseDownEvent=undefined;forEventTypesIn(sortedInputEvents,MOUSE_DRAG_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.MOUSE_DOWN:if(causedFrame(event)){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);}else{mouseDownEvent=event;}
+break;case INPUT_TYPE.MOUSE_MOVE:if(!causedFrame(event)){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}else if(!currentPE||!currentPE.isNear(event,MOUSE_MOVE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);currentPE.pushEvent(event);if(mouseDownEvent){currentPE.associatedEvents.push(mouseDownEvent);mouseDownEvent=undefined;}
+protoExpectations.push(currentPE);}else{if(currentPE.irType===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,MOUSE_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}
+break;case INPUT_TYPE.MOUSE_UP:if(!mouseDownEvent){var pe=new ProtoExpectation(causedFrame(event)?ProtoExpectation.RESPONSE_TYPE:ProtoExpectation.IGNORED_TYPE,MOUSE_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);break;}
+if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);if(mouseDownEvent)
+currentPE.associatedEvents.push(mouseDownEvent);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+mouseDownEvent=undefined;currentPE=undefined;break;}});if(mouseDownEvent){currentPE=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);currentPE.pushEvent(mouseDownEvent);protoExpectations.push(currentPE);}
+return protoExpectations;}
+function handleTapResponseEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;forEventTypesIn(sortedInputEvents,TAP_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TAP_DOWN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TAP_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;case INPUT_TYPE.TAP:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TAP_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+currentPE=undefined;break;case INPUT_TYPE.TAP_CANCEL:if(!currentPE){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TAP_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+currentPE=undefined;break;}});return protoExpectations;}
+function handlePinchEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstUpdate=false;var modelBounds=modelHelper.model.bounds;forEventTypesIn(sortedInputEvents,PINCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.PINCH_BEGIN:if(currentPE&&currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);break;}
+currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,PINCH_IR_NAME);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.PINCH_UPDATE:if(!currentPE||((currentPE.irType===ProtoExpectation.RESPONSE_TYPE)&&sawFirstUpdate)||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,PINCH_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstUpdate=true;}
+break;case INPUT_TYPE.PINCH_END:if(currentPE){currentPE.pushEvent(event);}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+currentPE=undefined;break;}});return protoExpectations;}
+function handleFlingEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;function isRendererFling(event){return event.title===RENDERER_FLING_TITLE;}
+var browserHelper=modelHelper.browserHelper;var flingEvents=browserHelper.getAllAsyncSlicesMatching(isRendererFling);forEventTypesIn(sortedInputEvents,FLING_TYPE_NAMES,function(event){flingEvents.push(event);});flingEvents.sort(compareEvents);flingEvents.forEach(function(event){if(event.title===RENDERER_FLING_TITLE){if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,FLING_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+return;}
+switch(event.typeName){case INPUT_TYPE.FLING_START:if(currentPE){console.error('Another FlingStart? File a bug with this trace!');currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,FLING_IR_NAME);currentPE.pushEvent(event);currentPE.end=0;protoExpectations.push(currentPE);}
+break;case INPUT_TYPE.FLING_CANCEL:if(currentPE){currentPE.pushEvent(event);currentPE.end=event.start;currentPE=undefined;}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+break;}});if(currentPE&&!currentPE.end)
+currentPE.end=modelHelper.model.bounds.max;return protoExpectations;}
+function handleTouchEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstMove=false;forEventTypesIn(sortedInputEvents,TOUCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TOUCH_START:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TOUCH_IR_NAME);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstMove=false;}
+break;case INPUT_TYPE.TOUCH_MOVE:if(!currentPE){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,TOUCH_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;}
+if((sawFirstMove&&(currentPE.irType===ProtoExpectation.RESPONSE_TYPE))||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){var prevEnd=currentPE.end;currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,TOUCH_IR_NAME);currentPE.pushEvent(event);currentPE.start=prevEnd;protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstMove=true;}
+break;case INPUT_TYPE.TOUCH_END:if(!currentPE){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+currentPE=undefined;break;}});return protoExpectations;}
+function handleScrollEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstUpdate=false;forEventTypesIn(sortedInputEvents,SCROLL_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.SCROLL_BEGIN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,SCROLL_IR_NAME);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.SCROLL_UPDATE:if(currentPE){if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)&&((currentPE.irType===ProtoExpectation.ANIMATION_TYPE)||!sawFirstUpdate)){currentPE.pushEvent(event);sawFirstUpdate=true;}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,SCROLL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,SCROLL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+break;case INPUT_TYPE.SCROLL_END:if(!currentPE){console.error('ScrollEnd without ScrollUpdate? '+'File a bug with this trace!');var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+currentPE.pushEvent(event);break;}});return protoExpectations;}
+function handleCSSAnimations(modelHelper,sortedInputEvents){var animationEvents=modelHelper.browserHelper.getAllAsyncSlicesMatching(function(event){return((event.title===CSS_ANIMATION_TITLE)&&event.isTopLevel&&(event.duration>0));});var framesForProcess={};function getFramesForAnimationProcess(animation){var frames=framesForProcess[animation.parentContainer.parent.guid];if(frames===undefined){var rendererHelper=new tr.model.helpers.ChromeRendererHelper(modelHelper,animation.parentContainer.parent);frames=rendererHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds);framesForProcess[animation.parentContainer.parent.guid]=frames;}
+return frames;}
+var animationRanges=[];function pushAnimationRange(start,end,animation){var range=tr.b.Range.fromExplicitRange(start,end);range.animation=animation;range.frames=range.filterArray(getFramesForAnimationProcess(animation),function(frameEvent){return frameEvent.start;});if(range.frames.length===0)
+return;animationRanges.push(range);}
+animationEvents.forEach(function(animation){if(animation.subSlices.length===0){pushAnimationRange(animation.start,animation.end,animation);}else{var start=undefined;animation.subSlices.forEach(function(sub){if((sub.args.state==='running')&&(start===undefined)){start=sub.start;}else if((sub.args.state==='paused')||(sub.args.state==='idle')||(sub.args.state==='finished')){if(start===undefined){start=modelHelper.model.bounds.min;}
+pushAnimationRange(start,sub.start,animation);start=undefined;}});if(start!==undefined)
+pushAnimationRange(start,modelHelper.model.bounds.max,animation);}});function merge(ranges){var protoExpectation=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,CSS_IR_NAME);ranges.forEach(function(range){protoExpectation.start=Math.min(protoExpectation.start,range.min);protoExpectation.end=Math.max(protoExpectation.end,range.max);protoExpectation.associatedEvents.push(range.animation);protoExpectation.associatedEvents.addEventSet(range.frames);});return protoExpectation;}
+return tr.b.mergeRanges(animationRanges,ANIMATION_MERGE_THRESHOLD_MS,merge);}
+function postProcessProtoExpectations(protoExpectations){protoExpectations=mergeIntersectingResponses(protoExpectations);protoExpectations=mergeIntersectingAnimations(protoExpectations);protoExpectations=fixResponseAnimationStarts(protoExpectations);protoExpectations=fixTapResponseTouchAnimations(protoExpectations);return protoExpectations;}
+function mergeIntersectingResponses(protoExpectations){var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);if(pe.irType!==ProtoExpectation.RESPONSE_TYPE)
+continue;for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(otherPE.irType!==pe.irType)
+continue;if(!otherPE.intersects(pe))
+continue;var typeNames=pe.associatedEvents.map(function(event){return event.typeName;});if(otherPE.containsTypeNames(typeNames))
+continue;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+return newPEs;}
+function mergeIntersectingAnimations(protoExpectations){var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);if(pe.irType!==ProtoExpectation.ANIMATION_TYPE)
+continue;var isCSS=pe.containsSliceTitle(CSS_ANIMATION_TITLE);var isFling=pe.containsTypeNames([INPUT_TYPE.FLING_START]);for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(otherPE.irType!==pe.irType)
+continue;if(isCSS!=otherPE.containsSliceTitle(CSS_ANIMATION_TITLE))
+continue;if(!otherPE.intersects(pe))
+continue;if(isFling!=otherPE.containsTypeNames([INPUT_TYPE.FLING_START]))
+continue;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+return newPEs;}
+function fixResponseAnimationStarts(protoExpectations){protoExpectations.forEach(function(ape){if(ape.irType!==ProtoExpectation.ANIMATION_TYPE)
+return;protoExpectations.forEach(function(rpe){if(rpe.irType!==ProtoExpectation.RESPONSE_TYPE)
+return;if(!ape.containsTimestampInclusive(rpe.end))
+return;if(ape.containsTimestampInclusive(rpe.start))
+return;ape.start=rpe.end;});});return protoExpectations;}
+function fixTapResponseTouchAnimations(protoExpectations){function isTapResponse(pe){return(pe.irType===ProtoExpectation.RESPONSE_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TAP]);}
+function isTouchAnimation(pe){return(pe.irType===ProtoExpectation.ANIMATION_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TOUCH_MOVE])&&!pe.containsTypeNames([INPUT_TYPE.SCROLL_UPDATE,INPUT_TYPE.PINCH_UPDATE]);}
+var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);var peIsTapResponse=isTapResponse(pe);var peIsTouchAnimation=isTouchAnimation(pe);if(!peIsTapResponse&&!peIsTouchAnimation)
+continue;for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(!otherPE.intersects(pe))
+continue;if(peIsTapResponse&&!isTouchAnimation(otherPE))
+continue;if(peIsTouchAnimation&&!isTapResponse(otherPE))
+continue;pe.irType=ProtoExpectation.RESPONSE_TYPE;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+return newPEs;}
+function checkAllInputEventsHandled(sortedInputEvents,protoExpectations){var handledEvents=[];protoExpectations.forEach(function(protoExpectation){protoExpectation.associatedEvents.forEach(function(event){if((event.title===CSS_ANIMATION_TITLE)&&(event.subSlices.length>0))
+return;if(handledEvents.indexOf(event)>=0){console.error('double-handled event',event.typeName,parseInt(event.start),parseInt(event.end),protoExpectation);return;}
+handledEvents.push(event);});});sortedInputEvents.forEach(function(event){if(handledEvents.indexOf(event)<0){console.error('UNHANDLED INPUT EVENT!',event.typeName,parseInt(event.start),parseInt(event.end));}});}
+function findInputExpectations(modelHelper){var sortedInputEvents=getSortedInputEvents(modelHelper);var protoExpectations=findProtoExpectations(modelHelper,sortedInputEvents);protoExpectations=postProcessProtoExpectations(protoExpectations);checkAllInputEventsHandled(sortedInputEvents,protoExpectations);var irs=[];protoExpectations.forEach(function(protoExpectation){var ir=protoExpectation.createInteractionRecord(modelHelper.model);if(ir)
+irs.push(ir);});return irs;}
+return{findInputExpectations:findInputExpectations,compareEvents:compareEvents,CSS_ANIMATION_TITLE:CSS_ANIMATION_TITLE};});'use strict';tr.exportTo('tr.model.um',function(){var LOAD_SUBTYPE_NAMES={SUCCESSFUL:'Successful',FAILED:'Failed',STARTUP:'Startup'};var DOES_LOAD_SUBTYPE_NAME_EXIST={};for(var key in LOAD_SUBTYPE_NAMES){DOES_LOAD_SUBTYPE_NAME_EXIST[LOAD_SUBTYPE_NAMES[key]]=true;;}
+function LoadExpectation(parentModel,initiatorTitle,start,duration){if(!DOES_LOAD_SUBTYPE_NAME_EXIST[initiatorTitle])
+throw new Error(initiatorTitle+' is not in LOAD_SUBTYPE_NAMES');tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.renderProcess=undefined;this.renderMainThread=undefined;this.routingId=undefined;this.parentRoutingId=undefined;this.loadFinishedEvent=undefined;}
+LoadExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:LoadExpectation};tr.model.um.UserExpectation.register(LoadExpectation,{stageTitle:'Load',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_load')});return{LOAD_SUBTYPE_NAMES:LOAD_SUBTYPE_NAMES,LoadExpectation:LoadExpectation};});'use strict';tr.exportTo('tr.importer',function(){var NAVIGATION_START='NavigationTiming navigationStart';var FIRST_CONTENTFUL_PAINT_TITLE='firstContentfulPaint';function getAllFrameEvents(modelHelper){var frameEvents=[];frameEvents.push.apply(frameEvents,modelHelper.browserHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));tr.b.iterItems(modelHelper.rendererHelpers,function(pid,renderer){frameEvents.push.apply(frameEvents,renderer.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));});return frameEvents.sort(tr.importer.compareEvents);}
+function getStartupEvents(modelHelper){function isStartupSlice(slice){return slice.title==='BrowserMainLoop::CreateThreads';}
+var events=modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartupSlice);var deduper=new tr.model.EventSet();events.forEach(function(event){var sliceGroup=event.parentContainer.sliceGroup;var slice=sliceGroup&&sliceGroup.findFirstSlice();if(slice)
+deduper.push(slice);});return deduper.toArray();}
+function findLoadExpectationsInternal(modelHelper,subtypeName,openingEvents,closingEvents){var loads=[];openingEvents.forEach(function(openingEvent){closingEvents.forEach(function(closingEvent){if(openingEvent.closingEvent)
+return;if(closingEvent.openingEvent)
+return;if(closingEvent.start<=openingEvent.start)
+return;if(openingEvent.parentContainer.parent.pid!==closingEvent.parentContainer.parent.pid)
+return;openingEvent.closingEvent=closingEvent;closingEvent.openingEvent=openingEvent;var lir=new tr.model.um.LoadExpectation(modelHelper.model,subtypeName,openingEvent.start,closingEvent.end-openingEvent.start);lir.associatedEvents.push(openingEvent);lir.associatedEvents.push(closingEvent);loads.push(lir);});});return loads;}
+function findRenderLoadExpectations(modelHelper){var events=[];modelHelper.model.iterateAllEvents(function(event){if((event.title===NAVIGATION_START)||(event.title===FIRST_CONTENTFUL_PAINT_TITLE))
+events.push(event);});events.sort(tr.importer.compareEvents);var loads=[];var startEvent=undefined;events.forEach(function(event){if(event.title===NAVIGATION_START){startEvent=event;}else if(event.title===FIRST_CONTENTFUL_PAINT_TITLE){if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,event.start-startEvent.start));startEvent=undefined;}}});if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,modelHelper.model.bounds.max-startEvent.start));}
+return loads;}
+function findLoadExpectations(modelHelper){var loads=[];var commitLoadEvents=modelHelper.browserHelper.getCommitProvisionalLoadEventsInRange(modelHelper.model.bounds);var startupEvents=getStartupEvents(modelHelper);var frameEvents=getAllFrameEvents(modelHelper);var startupLoads=findLoadExpectationsInternal(modelHelper,tr.model.um.LOAD_SUBTYPE_NAMES.STARTUP,startupEvents,frameEvents);loads.push.apply(loads,startupLoads);loads.push.apply(loads,findRenderLoadExpectations(modelHelper));return loads;}
+return{findLoadExpectations:findLoadExpectations};});'use strict';tr.exportTo('tr.model',function(){function getAssociatedEvents(irs){var allAssociatedEvents=new tr.model.EventSet();irs.forEach(function(ir){ir.associatedEvents.forEach(function(event){if(event instanceof tr.model.FlowEvent)
 return;allAssociatedEvents.push(event);});});return allAssociatedEvents;}
 function getUnassociatedEvents(model,associatedEvents){var unassociatedEvents=new tr.model.EventSet();model.getAllProcesses().forEach(function(process){for(var tid in process.threads){var thread=process.threads[tid];thread.sliceGroup.iterateAllEvents(function(event){if(!associatedEvents.contains(event))
 unassociatedEvents.push(event);});}});return unassociatedEvents;}
 function getTotalCpuDuration(events){var cpuMs=0;events.forEach(function(event){if(event.cpuSelfTime)
 cpuMs+=event.cpuSelfTime;});return cpuMs;}
-function getIRCoverageFromModel(model){var associatedEvents=getAssociatedEvents(model.interactionRecords);if(!associatedEvents.length)
-return undefined;var unassociatedEvents=getUnassociatedEvents(model,associatedEvents);var associatedCpuMs=getTotalCpuDuration(associatedEvents);var unassociatedCpuMs=getTotalCpuDuration(unassociatedEvents);var totalEventCount=associatedEvents.length+unassociatedEvents.length;var totalCpuMs=associatedCpuMs+unassociatedCpuMs;return{associatedEventsCount:associatedEvents.length,unassociatedEventsCount:unassociatedEvents.length,associatedEventsCpuTimeMs:associatedCpuMs,unassociatedEventsCpuTimeMs:unassociatedCpuMs,coveredEventsCountRatio:associatedEvents.length/totalEventCount,coveredEventsCpuTimeRatio:associatedCpuMs/totalCpuMs};}
-return{getIRCoverageFromModel:getIRCoverageFromModel,getAssociatedEvents:getAssociatedEvents,getUnassociatedEvents:getUnassociatedEvents};});'use strict';tr.exportTo('tr.e.rail',function(){var INPUT_TYPE=tr.e.cc.INPUT_EVENT_TYPE_NAMES;var ProtoIR=tr.e.rail.ProtoIR;function compareEvents(x,y){if(x.start!==y.start)
-return x.start-y.start;if(x.end!==y.end)
-return x.end-y.end;if(x.guid&&y.guid)
-return x.guid-y.guid;return 0;}
-function causedFrame(event){for(var i=0;i<event.associatedEvents.length;++i){if(event.associatedEvents[i].title===tr.e.audits.IMPL_RENDERING_STATS)
-return true;}
-return false;}
-function forEventTypesIn(events,typeNames,cb,opt_this){events.forEach(function(event){if(typeNames.indexOf(event.typeName)>=0){cb.call(opt_this,event);}});}
-var RENDER_FRAME_IMPL_PREFIX='RenderFrameImpl::';var CREATE_CHILD_TITLE=RENDER_FRAME_IMPL_PREFIX+'createChildFrame';var START_LOAD_TITLE=RENDER_FRAME_IMPL_PREFIX+'didStartProvisionalLoad';var FAIL_LOAD_TITLE=RENDER_FRAME_IMPL_PREFIX+'didFailProvisionalLoad';function isRenderFrameImplEvent(event){return event.title.indexOf(RENDER_FRAME_IMPL_PREFIX)===0;}
-var INPUT_MERGE_THRESHOLD_MS=200;var ANIMATION_MERGE_THRESHOLD_MS=1;var MOUSE_WHEEL_THRESHOLD_MS=40;var MOUSE_MOVE_THRESHOLD_MS=40;var INSIGNIFICANT_MS=1;var KEYBOARD_TYPE_NAMES=[INPUT_TYPE.CHAR,INPUT_TYPE.KEY_DOWN_RAW,INPUT_TYPE.KEY_DOWN,INPUT_TYPE.KEY_UP];var MOUSE_RESPONSE_TYPE_NAMES=[INPUT_TYPE.CLICK,INPUT_TYPE.CONTEXT_MENU];var MOUSE_WHEEL_TYPE_NAMES=[INPUT_TYPE.MOUSE_WHEEL];var MOUSE_DRAG_TYPE_NAMES=[INPUT_TYPE.MOUSE_DOWN,INPUT_TYPE.MOUSE_MOVE,INPUT_TYPE.MOUSE_UP];var TAP_TYPE_NAMES=[INPUT_TYPE.TAP,INPUT_TYPE.TAP_CANCEL,INPUT_TYPE.TAP_DOWN];var PINCH_TYPE_NAMES=[INPUT_TYPE.PINCH_BEGIN,INPUT_TYPE.PINCH_END,INPUT_TYPE.PINCH_UPDATE];var FLING_TYPE_NAMES=[INPUT_TYPE.FLING_CANCEL,INPUT_TYPE.FLING_START];var TOUCH_TYPE_NAMES=[INPUT_TYPE.TOUCH_END,INPUT_TYPE.TOUCH_MOVE,INPUT_TYPE.TOUCH_START];var SCROLL_TYPE_NAMES=[INPUT_TYPE.SCROLL_BEGIN,INPUT_TYPE.SCROLL_END,INPUT_TYPE.SCROLL_UPDATE];var ALL_HANDLED_TYPE_NAMES=[].concat(KEYBOARD_TYPE_NAMES,MOUSE_RESPONSE_TYPE_NAMES,MOUSE_WHEEL_TYPE_NAMES,MOUSE_DRAG_TYPE_NAMES,PINCH_TYPE_NAMES,TAP_TYPE_NAMES,FLING_TYPE_NAMES,TOUCH_TYPE_NAMES,SCROLL_TYPE_NAMES);var RENDERER_FLING_TITLE='InputHandlerProxy::HandleGestureFling::started';var CSS_ANIMATION_TITLE='Animation';var LOAD_STARTUP_IR_NAME='Startup';var LOAD_SUCCEEDED_IR_NAME='Succeeded';var LOAD_FAILED_IR_NAME='Failed';var KEYBOARD_IR_NAME='Keyboard';var MOUSE_IR_NAME='Mouse';var MOUSEWHEEL_IR_NAME='MouseWheel';var TAP_IR_NAME='Tap';var PINCH_IR_NAME='Pinch';var FLING_IR_NAME='Fling';var TOUCH_IR_NAME='Touch';var SCROLL_IR_NAME='Scroll';var CSS_IR_NAME='CSS';function RAILIRFinder(model,modelHelper){this.model=model;this.modelHelper=modelHelper;};RAILIRFinder.supportsModelHelper=function(modelHelper){return modelHelper.browserHelper!==undefined;};RAILIRFinder.prototype={findAllInteractionRecords:function(){var rirs=[];rirs.push.apply(rirs,this.findLoadInteractionRecords());rirs.push.apply(rirs,this.findInputInteractionRecords());rirs.push.apply(rirs,this.findIdleInteractionRecords(rirs));this.collectUnassociatedEvents_(rirs);return rirs;},setIRNames_:function(name,irs){irs.forEach(function(ir){ir.name=name;});},collectUnassociatedEvents_:function(rirs){var vacuumIRs=[];rirs.forEach(function(ir){if(ir instanceof tr.e.rail.LoadInteractionRecord||ir instanceof tr.e.rail.IdleInteractionRecord)
+function getIRCoverageFromModel(model){var associatedEvents=getAssociatedEvents(model.userModel.expectations);if(!associatedEvents.length)
+return undefined;var unassociatedEvents=getUnassociatedEvents(model,associatedEvents);var associatedCpuMs=getTotalCpuDuration(associatedEvents);var unassociatedCpuMs=getTotalCpuDuration(unassociatedEvents);var totalEventCount=associatedEvents.length+unassociatedEvents.length;var totalCpuMs=associatedCpuMs+unassociatedCpuMs;var coveredEventsCpuTimeRatio=undefined;if(totalCpuMs!==0)
+coveredEventsCpuTimeRatio=associatedCpuMs/totalCpuMs;return{associatedEventsCount:associatedEvents.length,unassociatedEventsCount:unassociatedEvents.length,associatedEventsCpuTimeMs:associatedCpuMs,unassociatedEventsCpuTimeMs:unassociatedCpuMs,coveredEventsCountRatio:associatedEvents.length/totalEventCount,coveredEventsCpuTimeRatio:coveredEventsCpuTimeRatio};}
+return{getIRCoverageFromModel:getIRCoverageFromModel,getAssociatedEvents:getAssociatedEvents,getUnassociatedEvents:getUnassociatedEvents};});'use strict';tr.exportTo('tr.model.um',function(){function IdleExpectation(parentModel,start,duration){var initiatorTitle='';tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);}
+IdleExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:IdleExpectation};tr.model.um.UserExpectation.register(IdleExpectation,{stageTitle:'Idle',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_idle')});return{IdleExpectation:IdleExpectation};});'use strict';tr.exportTo('tr.importer',function(){var INSIGNIFICANT_MS=1;function UserModelBuilder(model){this.model=model;this.modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);};UserModelBuilder.supportsModelHelper=function(modelHelper){return modelHelper.browserHelper!==undefined;};UserModelBuilder.prototype={buildUserModel:function(){if(!this.modelHelper||!this.modelHelper.browserHelper)
+return;var expectations=undefined;try{expectations=this.findUserExpectations();}catch(error){this.model.importWarning({type:'UserModelBuilder',message:error,showToUser:true});return;}
+expectations.forEach(function(expectation){this.model.userModel.expectations.push(expectation);},this);},findUserExpectations:function(){var expectations=[];expectations.push.apply(expectations,tr.importer.findLoadExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findInputExpectations(this.modelHelper));expectations.push.apply(expectations,this.findIdleExpectations(expectations));this.collectUnassociatedEvents_(expectations);return expectations;},collectUnassociatedEvents_:function(rirs){var vacuumIRs=[];rirs.forEach(function(ir){if(ir instanceof tr.model.um.LoadExpectation||ir instanceof tr.model.um.IdleExpectation)
 vacuumIRs.push(ir);});if(vacuumIRs.length===0)
 return;var allAssociatedEvents=tr.model.getAssociatedEvents(rirs);var unassociatedEvents=tr.model.getUnassociatedEvents(this.model,allAssociatedEvents);unassociatedEvents.forEach(function(event){if(!(event instanceof tr.model.ThreadSlice))
 return;if(!event.isTopLevel)
-return;for(var iri=0;iri<vacuumIRs.length;++iri){var ir=vacuumIRs[iri];if((event.start>=ir.start)&&(event.start<ir.end)){ir.associatedEvents.addEventSet(event.entireHierarchy);return;}}});},findIdleInteractionRecords:function(otherIRs){if(this.model.bounds.isEmpty)
+return;for(var iri=0;iri<vacuumIRs.length;++iri){var ir=vacuumIRs[iri];if((event.start>=ir.start)&&(event.start<ir.end)){ir.associatedEvents.addEventSet(event.entireHierarchy);return;}}});},findIdleExpectations:function(otherIRs){if(this.model.bounds.isEmpty)
 return;var emptyRanges=tr.b.findEmptyRangesBetweenRanges(tr.b.convertEventsToRanges(otherIRs),this.model.bounds);var irs=[];var model=this.model;emptyRanges.forEach(function(range){if(range.max<(range.min+INSIGNIFICANT_MS))
-return;irs.push(new tr.e.rail.IdleInteractionRecord(model,range.min,range.max-range.min));});return irs;},getAllFrameEvents:function(){var frameEvents=[];frameEvents.push.apply(frameEvents,this.modelHelper.browserHelper.getFrameEventsInRange(tr.e.audits.IMPL_FRAMETIME_TYPE,this.model.bounds));tr.b.iterItems(this.modelHelper.rendererHelpers,function(pid,renderer){frameEvents.push.apply(frameEvents,renderer.getFrameEventsInRange(tr.e.audits.IMPL_FRAMETIME_TYPE,this.model.bounds));},this);return frameEvents.sort(compareEvents);},getStartLoadEvents:function(){function isStartLoadSlice(slice){return slice.title===START_LOAD_TITLE;}
-return this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartLoadSlice).sort(compareEvents);},getFailLoadEvents:function(){function isFailLoadSlice(slice){return slice.title===FAIL_LOAD_TITLE;}
-return this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isFailLoadSlice).sort(compareEvents);},getStartupEvents:function(){function isStartupSlice(slice){return slice.title==='BrowserMainLoop::CreateThreads';}
-var events=this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartupSlice);var deduper=new tr.model.EventSet();events.forEach(function(event){var sliceGroup=event.parentContainer.sliceGroup;var slice=sliceGroup&&sliceGroup.findFirstSlice();if(slice)
-deduper.push(slice);});return deduper.toArray();},findLoadInteractionRecords_:function(openingEvents,closingEvents){var lirs=[];var model=this.model;openingEvents.forEach(function(openingEvent){closingEvents.forEach(function(closingEvent){if(openingEvent.closingEvent)
-return;if(closingEvent.openingEvent)
-return;if(closingEvent.start<=openingEvent.start)
-return;if(openingEvent.parentContainer.parent.pid!==closingEvent.parentContainer.parent.pid)
-return;openingEvent.closingEvent=closingEvent;closingEvent.openingEvent=openingEvent;var lir=new tr.e.rail.LoadInteractionRecord(model,openingEvent.start,closingEvent.end-openingEvent.start);lir.associatedEvents.push(openingEvent);lir.associatedEvents.push(closingEvent);if(isRenderFrameImplEvent(openingEvent)){lir.renderProcessId=openingEvent.parentContainer.parent.pid;lir.routingId=openingEvent.args.id;lir.parentRoutingId=this.findLoadParentRoutingId_(lir);}
-lirs.push(lir);},this);},this);return lirs;},findLoadParentRoutingId_:function(lir){function isCreateChildEvent(event){return((event.title===CREATE_CHILD_TITLE)&&(event.parentContainer.parent.pid===lir.renderProcessId)&&(event.args.child===lir.routingId));}
-var parentRoutingId=undefined;this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isCreateChildEvent).forEach(function(event){parentRoutingId=event.args.id;});return parentRoutingId;},findLoadInteractionRecords:function(){var startupEvents=this.getStartupEvents();var commitLoadEvents=this.modelHelper.browserHelper.getCommitProvisionalLoadEventsInRange(this.model.bounds);var frameEvents=this.getAllFrameEvents();var startLoadEvents=this.getStartLoadEvents();var failLoadEvents=this.getFailLoadEvents();var lirs=[];var startupLIRs=this.findLoadInteractionRecords_(startupEvents,frameEvents);this.setIRNames_(LOAD_STARTUP_IR_NAME,startupLIRs);lirs.push.apply(lirs,startupLIRs);var successfulLIRs=this.findLoadInteractionRecords_(commitLoadEvents,frameEvents);this.setIRNames_(LOAD_SUCCEEDED_IR_NAME,successfulLIRs);var renderLIRs=successfulLIRs;var failedLIRs=this.findLoadInteractionRecords_(startLoadEvents,failLoadEvents);this.setIRNames_(LOAD_FAILED_IR_NAME,failedLIRs);renderLIRs.push.apply(renderLIRs,failedLIRs);renderLIRs.forEach(function(lir){if(lir.parentRoutingId===undefined){lirs.push(lir);}},this);return lirs;},findInputInteractionRecords:function(){var sortedInputEvents=this.getSortedInputEvents();var protoIRs=this.findProtoIRs(sortedInputEvents);protoIRs=this.postProcessProtoIRs(protoIRs);this.checkAllInputEventsHandled(sortedInputEvents,protoIRs);var irs=[];var model=this.model;protoIRs.forEach(function(protoIR){var ir=protoIR.createInteractionRecord(model);if(ir)
-irs.push(ir);});return irs;},findProtoIRs:function(sortedInputEvents){var protoIRs=[];var handlers=[this.handleKeyboardEvents,this.handleMouseResponseEvents,this.handleMouseWheelEvents,this.handleMouseDragEvents,this.handleTapResponseEvents,this.handlePinchEvents,this.handleFlingEvents,this.handleTouchEvents,this.handleScrollEvents,this.handleCSSAnimations];handlers.forEach(function(handler){protoIRs.push.apply(protoIRs,handler.call(this,sortedInputEvents));},this);protoIRs.sort(compareEvents);return protoIRs;},getSortedInputEvents:function(){var inputEvents=[];var browserProcess=this.modelHelper.browserHelper.process;var mainThread=browserProcess.findAtMostOneThreadNamed('CrBrowserMain');mainThread.asyncSliceGroup.iterateAllEvents(function(slice){if(!slice.isTopLevel)
-return;if(!(slice instanceof tr.e.cc.InputLatencyAsyncSlice))
-return;if(isNaN(slice.start)||isNaN(slice.duration)||isNaN(slice.end))
-return;inputEvents.push(slice);},this);return inputEvents.sort(compareEvents);},handleKeyboardEvents:function(sortedInputEvents){var protoIRs=[];forEventTypesIn(sortedInputEvents,KEYBOARD_TYPE_NAMES,function(event){var pir=new ProtoIR(ProtoIR.RESPONSE_TYPE,KEYBOARD_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);});return protoIRs;},handleMouseResponseEvents:function(sortedInputEvents){var protoIRs=[];forEventTypesIn(sortedInputEvents,MOUSE_RESPONSE_TYPE_NAMES,function(event){var pir=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);});return protoIRs;},handleMouseWheelEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var prevEvent_=undefined;forEventTypesIn(sortedInputEvents,MOUSE_WHEEL_TYPE_NAMES,function(event){var prevEvent=prevEvent_;prevEvent_=event;if(currentPIR&&(prevEvent.start+MOUSE_WHEEL_THRESHOLD_MS)>=event.start){if(currentPIR.irType===ProtoIR.ANIMATION_TYPE){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,MOUSEWHEEL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
-return;}
-currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSEWHEEL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);});return protoIRs;},handleMouseDragEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var mouseDownEvent=undefined;forEventTypesIn(sortedInputEvents,MOUSE_DRAG_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.MOUSE_DOWN:if(causedFrame(event)){var pir=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);}else{mouseDownEvent=event;}
-break;case INPUT_TYPE.MOUSE_MOVE:if(!causedFrame(event)){var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}else if(!currentPIR||!currentPIR.isNear(event,MOUSE_MOVE_THRESHOLD_MS)){currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);currentPIR.pushEvent(event);if(mouseDownEvent){currentPIR.associatedEvents.push(mouseDownEvent);mouseDownEvent=undefined;}
-protoIRs.push(currentPIR);}else{if(currentPIR.irType===ProtoIR.ANIMATION_TYPE){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,MOUSE_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}}
-break;case INPUT_TYPE.MOUSE_UP:if(!mouseDownEvent){var pir=new ProtoIR(causedFrame(event)?ProtoIR.RESPONSE_TYPE:ProtoIR.IGNORED_TYPE,MOUSE_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);break;}
-if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);if(mouseDownEvent)
-currentPIR.associatedEvents.push(mouseDownEvent);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
-mouseDownEvent=undefined;currentPIR=undefined;break;}});if(mouseDownEvent){currentPIR=new ProtoIR(ProtoIR.IGNORED_TYPE);currentPIR.pushEvent(mouseDownEvent);protoIRs.push(currentPIR);}
-return protoIRs;},handleTapResponseEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;forEventTypesIn(sortedInputEvents,TAP_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TAP_DOWN:currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TAP_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);break;case INPUT_TYPE.TAP:if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TAP_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
-currentPIR=undefined;break;case INPUT_TYPE.TAP_CANCEL:if(!currentPIR){var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);break;}
-if(currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TAP_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
-currentPIR=undefined;break;}});return protoIRs;},handlePinchEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var sawFirstUpdate=false;var modelBounds=this.model.bounds;forEventTypesIn(sortedInputEvents,PINCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.PINCH_BEGIN:if(currentPIR&&currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR.pushEvent(event);break;}
-currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,PINCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);sawFirstUpdate=false;break;case INPUT_TYPE.PINCH_UPDATE:if(!currentPIR||((currentPIR.irType===ProtoIR.RESPONSE_TYPE)&&sawFirstUpdate)||!currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,PINCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}else{currentPIR.pushEvent(event);sawFirstUpdate=true;}
-break;case INPUT_TYPE.PINCH_END:if(currentPIR){currentPIR.pushEvent(event);}else{var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}
-currentPIR=undefined;break;}});return protoIRs;},handleFlingEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;function isRendererFling(event){return event.title===RENDERER_FLING_TITLE;}
-var browserHelper=this.modelHelper.browserHelper;var flingEvents=browserHelper.getAllAsyncSlicesMatching(isRendererFling);forEventTypesIn(sortedInputEvents,FLING_TYPE_NAMES,function(event){flingEvents.push(event);});flingEvents.sort(compareEvents);flingEvents.forEach(function(event){if(event.title===RENDERER_FLING_TITLE){if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,FLING_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
-return;}
-switch(event.typeName){case INPUT_TYPE.FLING_START:if(currentPIR){console.error('Another FlingStart? File a bug with this trace!');currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,FLING_IR_NAME);currentPIR.pushEvent(event);currentPIR.end=0;protoIRs.push(currentPIR);}
-break;case INPUT_TYPE.FLING_CANCEL:if(currentPIR){currentPIR.pushEvent(event);currentPIR.end=event.start;currentPIR=undefined;}else{var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}
-break;}});if(currentPIR&&!currentPIR.end)
-currentPIR.end=this.model.bounds.max;return protoIRs;},handleTouchEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var sawFirstMove=false;forEventTypesIn(sortedInputEvents,TOUCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TOUCH_START:if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TOUCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);sawFirstMove=false;}
-break;case INPUT_TYPE.TOUCH_MOVE:if(!currentPIR){currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,TOUCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);break;}
-if((sawFirstMove&&(currentPIR.irType===ProtoIR.RESPONSE_TYPE))||!currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){var prevEnd=currentPIR.end;currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,TOUCH_IR_NAME);currentPIR.pushEvent(event);currentPIR.start=prevEnd;protoIRs.push(currentPIR);}else{currentPIR.pushEvent(event);sawFirstMove=true;}
-break;case INPUT_TYPE.TOUCH_END:if(!currentPIR){var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);break;}
-if(currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR.pushEvent(event);}else{var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}
-currentPIR=undefined;break;}});return protoIRs;},handleScrollEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var sawFirstUpdate=false;forEventTypesIn(sortedInputEvents,SCROLL_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.SCROLL_BEGIN:currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,SCROLL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);sawFirstUpdate=false;break;case INPUT_TYPE.SCROLL_UPDATE:if(currentPIR){if(currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)&&((currentPIR.irType===ProtoIR.ANIMATION_TYPE)||!sawFirstUpdate)){currentPIR.pushEvent(event);sawFirstUpdate=true;}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,SCROLL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,SCROLL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
-break;case INPUT_TYPE.SCROLL_END:if(!currentPIR){console.error('ScrollEnd without ScrollUpdate? '+'File a bug with this trace!');var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);break;}
-currentPIR.pushEvent(event);break;}});return protoIRs;},handleCSSAnimations:function(sortedInputEvents){var animationEvents=this.modelHelper.browserHelper.getAllAsyncSlicesMatching(function(event){return((event.title===CSS_ANIMATION_TITLE)&&(event.duration>0));});var animationRanges=[];animationEvents.forEach(function(event){animationRanges.push({min:event.start,max:event.end,event:event});});function merge(ranges){var protoIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,CSS_IR_NAME);ranges.forEach(function(range){protoIR.pushEvent(range.event);});return protoIR;}
-return tr.b.mergeRanges(animationRanges,ANIMATION_MERGE_THRESHOLD_MS,merge);},postProcessProtoIRs:function(protoIRs){protoIRs=this.mergeIntersectingResponses(protoIRs);protoIRs=this.mergeIntersectingAnimations(protoIRs);protoIRs=this.fixResponseAnimationStarts(protoIRs);protoIRs=this.fixTapResponseTouchAnimations(protoIRs);return protoIRs;},mergeIntersectingResponses:function(protoIRs){var newPIRs=[];while(protoIRs.length){var pir=protoIRs.shift();newPIRs.push(pir);if(pir.irType!==ProtoIR.RESPONSE_TYPE)
-continue;for(var i=0;i<protoIRs.length;++i){var otherPIR=protoIRs[i];if(otherPIR.irType!==pir.irType)
-continue;if(!otherPIR.intersects(pir))
-continue;var typeNames=pir.associatedEvents.map(function(event){return event.typeName;});if(otherPIR.containsTypeNames(typeNames))
-continue;pir.merge(otherPIR);protoIRs.splice(i,1);--i;}}
-return newPIRs;},mergeIntersectingAnimations:function(protoIRs){var newPIRs=[];while(protoIRs.length){var pir=protoIRs.shift();newPIRs.push(pir);if(pir.irType!==ProtoIR.ANIMATION_TYPE)
-continue;var isCSS=pir.containsSliceTitle(CSS_ANIMATION_TITLE);var isFling=pir.containsTypeNames([INPUT_TYPE.FLING_START]);for(var i=0;i<protoIRs.length;++i){var otherPIR=protoIRs[i];if(otherPIR.irType!==pir.irType)
-continue;if(isCSS!=otherPIR.containsSliceTitle(CSS_ANIMATION_TITLE))
-continue;if(!otherPIR.intersects(pir))
-continue;if(isFling!=otherPIR.containsTypeNames([INPUT_TYPE.FLING_START]))
-continue;pir.merge(otherPIR);protoIRs.splice(i,1);--i;}}
-return newPIRs;},fixResponseAnimationStarts:function(protoIRs){protoIRs.forEach(function(apir){if(apir.irType!==ProtoIR.ANIMATION_TYPE)
-return;protoIRs.forEach(function(rpir){if(rpir.irType!==ProtoIR.RESPONSE_TYPE)
-return;if(!apir.containsTimestampInclusive(rpir.end))
-return;if(apir.containsTimestampInclusive(rpir.start))
-return;apir.start=rpir.end;});});return protoIRs;},fixTapResponseTouchAnimations:function(protoIRs){function isTapResponse(pir){return(pir.irType===ProtoIR.RESPONSE_TYPE)&&pir.containsTypeNames([INPUT_TYPE.TAP]);}
-function isTouchAnimation(pir){return(pir.irType===ProtoIR.ANIMATION_TYPE)&&pir.containsTypeNames([INPUT_TYPE.TOUCH_MOVE])&&!pir.containsTypeNames([INPUT_TYPE.SCROLL_UPDATE,INPUT_TYPE.PINCH_UPDATE]);}
-var newPIRs=[];while(protoIRs.length){var pir=protoIRs.shift();newPIRs.push(pir);var pirIsTapResponse=isTapResponse(pir);var pirIsTouchAnimation=isTouchAnimation(pir);if(!pirIsTapResponse&&!pirIsTouchAnimation)
-continue;for(var i=0;i<protoIRs.length;++i){var otherPIR=protoIRs[i];if(!otherPIR.intersects(pir))
-continue;if(pirIsTapResponse&&!isTouchAnimation(otherPIR))
-continue;if(pirIsTouchAnimation&&!isTapResponse(otherPIR))
-continue;pir.irType=ProtoIR.RESPONSE_TYPE;pir.merge(otherPIR);protoIRs.splice(i,1);--i;}}
-return newPIRs;},checkAllInputEventsHandled:function(sortedInputEvents,protoIRs){var handledEvents=[];protoIRs.forEach(function(protoIR){protoIR.associatedEvents.forEach(function(event){if(handledEvents.indexOf(event)>=0){console.error('double-handled event',event.typeName,parseInt(event.start),parseInt(event.end),protoIR);return;}
-handledEvents.push(event);});});sortedInputEvents.forEach(function(event){if(handledEvents.indexOf(event)<0){console.error('UNHANDLED INPUT EVENT!',event.typeName,parseInt(event.start),parseInt(event.end));}});}};function createCustomizeModelLinesFromModel(model){var modelLines=[];modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {title: \'model start\', start: 0, end: 1});');var typeNames={};for(var typeName in tr.e.cc.INPUT_EVENT_TYPE_NAMES){typeNames[tr.e.cc.INPUT_EVENT_TYPE_NAMES[typeName]]=typeName;}
-var modelEvents=new tr.model.EventSet();model.interactionRecords.forEach(function(ir,index){modelEvents.addEventSet(ir.sourceEvents);});modelEvents=modelEvents.toArray();modelEvents.sort(compareEvents);modelEvents.forEach(function(event){var startAndEnd='start: '+parseInt(event.start)+', '+'end: '+parseInt(event.end)+'});';if(event instanceof tr.e.cc.InputLatencyAsyncSlice){modelLines.push('      audits.addInputEvent(model, INPUT_TYPE.'+
-typeNames[event.typeName]+',');}else if(event.title==='RenderFrameImpl::didCommitProvisionalLoad'){modelLines.push('      audits.addCommitLoadEvent(model,');}else if(event.title==='InputHandlerProxy::HandleGestureFling::started'){modelLines.push('      audits.addFlingAnimationEvent(model,');}else if(event.title===tr.e.audits.IMPL_RENDERING_STATS){modelLines.push('      audits.addFrameEvent(model,');}else if(event.title===CSS_ANIMATION_TITLE){modelLines.push('      audits.addEvent(model.rendererMain, {');modelLines.push('        title: \'Animation\', '+startAndEnd);return;}else{throw('You must extend createCustomizeModelLinesFromModel()'+'to support this event:\n'+event.title+'\n');}
+return;irs.push(new tr.model.um.IdleExpectation(model,range.min,range.max-range.min));});return irs;}};function createCustomizeModelLinesFromModel(model){var modelLines=[];modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {title: \'model start\', start: 0, end: 1});');var typeNames={};for(var typeName in tr.e.cc.INPUT_EVENT_TYPE_NAMES){typeNames[tr.e.cc.INPUT_EVENT_TYPE_NAMES[typeName]]=typeName;}
+var modelEvents=new tr.model.EventSet();model.userModel.expectations.forEach(function(ir,index){modelEvents.addEventSet(ir.sourceEvents);});modelEvents=modelEvents.toArray();modelEvents.sort(tr.importer.compareEvents);modelEvents.forEach(function(event){var startAndEnd='start: '+parseInt(event.start)+', '+'end: '+parseInt(event.end)+'});';if(event instanceof tr.e.cc.InputLatencyAsyncSlice){modelLines.push('      audits.addInputEvent(model, INPUT_TYPE.'+
+typeNames[event.typeName]+',');}else if(event.title==='RenderFrameImpl::didCommitProvisionalLoad'){modelLines.push('      audits.addCommitLoadEvent(model,');}else if(event.title==='InputHandlerProxy::HandleGestureFling::started'){modelLines.push('      audits.addFlingAnimationEvent(model,');}else if(event.title===tr.model.helpers.IMPL_RENDERING_STATS){modelLines.push('      audits.addFrameEvent(model,');}else if(event.title===tr.importer.CSS_ANIMATION_TITLE){modelLines.push('      audits.addEvent(model.rendererMain, {');modelLines.push('        title: \'Animation\', '+startAndEnd);return;}else{throw('You must extend createCustomizeModelLinesFromModel()'+'to support this event:\n'+event.title+'\n');}
 modelLines.push('          {'+startAndEnd);});modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {'+'title: \'model end\', '+'start: '+(parseInt(model.bounds.max)-1)+', '+'end: '+parseInt(model.bounds.max)+'});');return modelLines;}
-function createExpectedIRLinesFromModel(model){var expectedLines=[];var irCount=model.interactionRecords.length;model.interactionRecords.forEach(function(ir,index){var irString='      {';irString+='title: \''+ir.title+'\', ';irString+='start: '+parseInt(ir.start)+', ';irString+='end: '+parseInt(ir.end)+', ';irString+='eventCount: '+ir.sourceEvents.length;irString+='}';if(index<(irCount-1))
+function createExpectedIRLinesFromModel(model){var expectedLines=[];var irCount=model.userModel.expectations.length;model.userModel.expectations.forEach(function(ir,index){var irString='      {';irString+='title: \''+ir.title+'\', ';irString+='start: '+parseInt(ir.start)+', ';irString+='end: '+parseInt(ir.end)+', ';irString+='eventCount: '+ir.sourceEvents.length;irString+='}';if(index<(irCount-1))
 irString+=',';expectedLines.push(irString);});return expectedLines;}
-function createIRFinderTestCaseStringFromModel(model){var filename=window.location.hash.substr(1);var testName=filename.substr(filename.lastIndexOf('/')+1);testName=testName.substr(0,testName.indexOf('.'));try{var testLines=[];testLines.push('  /*');testLines.push('    This test was generated from');testLines.push('    '+filename+'');testLines.push('   */');testLines.push('  test(\''+testName+'\', function() {');testLines.push('    var verifier = new IRVerifier();');testLines.push('    verifier.customizeModelCallback = function(model) {');testLines.push.apply(testLines,createCustomizeModelLinesFromModel(model));testLines.push('    };');testLines.push('    verifier.expectedIRs = [');testLines.push.apply(testLines,createExpectedIRLinesFromModel(model));testLines.push('    ];');testLines.push('    verifier.verify();');testLines.push('  });');return testLines.join('\n');}catch(error){return error;}}
-return{RAILIRFinder:RAILIRFinder,createIRFinderTestCaseStringFromModel:createIRFinderTestCaseStringFromModel};});'use strict';tr.exportTo('tr.e.audits',function(){var Auditor=tr.c.Auditor;function ChromeAuditor(model){Auditor.call(this,model);if(tr.e.audits.ChromeModelHelper.supportsModel(this.model)){var modelHelper=new tr.e.audits.ChromeModelHelper(this.model);if(modelHelper.browserHelper===undefined)
-this.modelHelper=undefined;else
-this.modelHelper=modelHelper;}else{this.modelHelper=undefined;}};ChromeAuditor.prototype={__proto__:Auditor.prototype,runAnnotate:function(){if(!this.modelHelper)
-return;this.model.getAllProcesses().forEach(function(process){if(process.labels!==undefined&&process.labels.length==1&&process.labels[0]=='chrome://tracing')
-process.important=false;});},runAudit:function(){if(!this.modelHelper)
-return;if(!tr.e.rail.RAILIRFinder.supportsModelHelper(this.modelHelper))
-return;var rirf=new tr.e.rail.RAILIRFinder(this.model,this.modelHelper);var rirs=undefined;try{rirs=rirf.findAllInteractionRecords();}catch(error){this.model.importWarning({type:'RAILIRFinder',message:error,showToUser:true});return;}
-rirs.forEach(function(ir){this.model.addInteractionRecord(ir);},this);}};Auditor.register(ChromeAuditor);return{ChromeAuditor:ChromeAuditor};});'use strict';tr.exportTo('tr.b',function(){function Settings(){return Settings;};if(tr.b.unittest&&tr.b.unittest.TestRunner){tr.b.unittest.TestRunner.addEventListener('tr-unittest-will-run',function(){if(tr.isHeadless)
-Settings.setAlternativeStorageInstance(new HeadlessStorage());else
-Settings.setAlternativeStorageInstance(global.sessionStorage);});}
-function SessionSettings(){return SessionSettings;}
-function AddStaticStorageFunctionsToClass_(input_class,storage){input_class.storage_=storage;input_class.get=function(key,opt_default,opt_namespace){key=input_class.namespace_(key,opt_namespace);var rawVal=input_class.storage_.getItem(key);if(rawVal===null||rawVal===undefined)
-return opt_default;try{return JSON.parse(rawVal).value;}catch(e){input_class.storage_.removeItem(key);return opt_default;}};input_class.set=function(key,value,opt_namespace){if(value===undefined)
-throw new Error('Settings.set: value must not be undefined');var v=JSON.stringify({value:value});input_class.storage_.setItem(input_class.namespace_(key,opt_namespace),v);};input_class.keys=function(opt_namespace){var result=[];opt_namespace=opt_namespace||'';for(var i=0;i<input_class.storage_.length;i++){var key=input_class.storage_.key(i);if(input_class.isnamespaced_(key,opt_namespace))
-result.push(input_class.unnamespace_(key,opt_namespace));}
-return result;};input_class.isnamespaced_=function(key,opt_namespace){return key.indexOf(input_class.normalize_(opt_namespace))==0;};input_class.namespace_=function(key,opt_namespace){return input_class.normalize_(opt_namespace)+key;};input_class.unnamespace_=function(key,opt_namespace){return key.replace(input_class.normalize_(opt_namespace),'');};input_class.normalize_=function(opt_namespace){return input_class.NAMESPACE+(opt_namespace?opt_namespace+'.':'');};input_class.setAlternativeStorageInstance=function(instance){input_class.storage_=instance;};input_class.getAlternativeStorageInstance=function(){if(!tr.isHeadless&&input_class.storage_===localStorage)
-return undefined;return input_class.storage_;};input_class.NAMESPACE='trace-viewer';};function HeadlessStorage(){this.length=0;this.hasItem_={};this.items_={};this.itemsAsArray_=undefined;}
-HeadlessStorage.prototype={key:function(index){return this.itemsAsArray[index];},get itemsAsArray(){if(this.itemsAsArray_!==undefined)
-return this.itemsAsArray_;var itemsAsArray=[];for(var k in this.items_)
-itemsAsArray.push(k);this.itemsAsArray_=itemsAsArray;return this.itemsAsArray_;},getItem:function(key){if(!this.hasItem_[key])
-return null;return this.items_[key];},removeItem:function(key){if(!this.hasItem_[key])
-return;var value=this.items_[key];delete this.hasItem_[key];delete this.items_[key];this.length--;this.itemsAsArray_=undefined;return value;},setItem:function(key,value){if(this.hasItem_[key]){this.items_[key]=value;return;}
-this.items_[key]=value;this.hasItem_[key]=true;this.length++;this.itemsAsArray_=undefined;return value;}};if(tr.isHeadless){AddStaticStorageFunctionsToClass_(Settings,new HeadlessStorage());AddStaticStorageFunctionsToClass_(SessionSettings,new HeadlessStorage());}else{AddStaticStorageFunctionsToClass_(Settings,localStorage);AddStaticStorageFunctionsToClass_(SessionSettings,sessionStorage);}
-return{Settings:Settings,SessionSettings:SessionSettings};});'use strict';tr.exportTo('tr.c',function(){function ScriptingObject(){}
-ScriptingObject.prototype={onModelChanged:function(model){}};return{ScriptingObject:ScriptingObject};});'use strict';tr.exportTo('tr.c',function(){function ScriptingController(brushingStateController){this.brushingStateController_=brushingStateController;this.scriptObjectNames_=[];this.scriptObjectValues_=[];this.brushingStateController.addEventListener('model-changed',this.onModelChanged_.bind(this));var typeInfos=ScriptingObjectRegistry.getAllRegisteredTypeInfos();typeInfos.forEach(function(typeInfo){this.addScriptObject(typeInfo.metadata.name,typeInfo.constructor);global[typeInfo.metadata.name]=typeInfo.constructor;},this);}
-function ScriptingObjectRegistry(){}
-var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ScriptingObjectRegistry,options);ScriptingController.prototype={get brushingStateController(){return this.brushingStateController_;},onModelChanged_:function(){this.scriptObjectValues_.forEach(function(v){if(v.onModelChanged)
-v.onModelChanged(this.brushingStateController.model);},this);},addScriptObject:function(name,value){this.scriptObjectNames_.push(name);this.scriptObjectValues_.push(value);},executeCommand:function(command){var f=new Function(this.scriptObjectNames_,'return eval('+command+')');return f.apply(null,this.scriptObjectValues_);}};return{ScriptingController:ScriptingController,ScriptingObjectRegistry:ScriptingObjectRegistry};});'use strict';Polymer('tr-ui-a-tab-view',{ready:function(){this.$.tshh.style.display='none';this.tabs_=[];this.selectedTab_=undefined;for(var i=0;i<this.children.length;i++)
-this.processAddedChild_(this.children[i]);this.childrenObserver_=new MutationObserver(this.childrenUpdated_.bind(this));this.childrenObserver_.observe(this,{childList:'true'});},get tabStripHeadingText(){return this.$.tsh.textContent;},set tabStripHeadingText(tabStripHeadingText){this.$.tsh.textContent=tabStripHeadingText;if(!!tabStripHeadingText)
-this.$.tshh.style.display='';else
-this.$.tshh.style.display='none';},get selectedTab(){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(this.selectedTab_)
-return this.selectedTab_.content;return undefined;},set selectedTab(content){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(content===undefined||content===null){this.changeSelectedTabById_(undefined);return;}
-var contentTabId=undefined;for(var i=0;i<this.tabs_.length;i++)
-if(this.tabs_[i].content===content){contentTabId=this.tabs_[i].id;break;}
-if(contentTabId===undefined)
-return;this.changeSelectedTabById_(contentTabId);},get tabsHidden(){var ts=this.shadowRoot.querySelector('tab-strip');return ts.hasAttribute('tabs-hidden');},set tabsHidden(tabsHidden){tabsHidden=!!tabsHidden;var ts=this.shadowRoot.querySelector('tab-strip');if(tabsHidden)
-ts.setAttribute('tabs-hidden',true);else
-ts.removeAttribute('tabs-hidden');},get tabs(){return this.tabs_.map(function(tabObject){return tabObject.content;});},processAddedChild_:function(child){var observerAttributeSelected=new MutationObserver(this.childAttributesChanged_.bind(this));var observerAttributeTabLabel=new MutationObserver(this.childAttributesChanged_.bind(this));var tabObject={id:this.tabs_.length,content:child,label:child.getAttribute('tab-label'),observers:{forAttributeSelected:observerAttributeSelected,forAttributeTabLabel:observerAttributeTabLabel}};this.tabs_.push(tabObject);if(child.hasAttribute('selected')){if(this.selectedTab_)
-child.removeAttribute('selected');else
-this.setSelectedTabById_(tabObject.id);}
-var previousSelected=child.selected;var tabView=this;Object.defineProperty(child,'selected',{configurable:true,set:function(value){if(value){tabView.changeSelectedTabById_(tabObject.id);return;}
-var wasSelected=tabView.selectedTab_===tabObject;if(wasSelected)
-tabView.changeSelectedTabById_(undefined);},get:function(){return this.hasAttribute('selected');}});if(previousSelected)
-child.selected=previousSelected;observerAttributeSelected.observe(child,{attributeFilter:['selected']});observerAttributeTabLabel.observe(child,{attributeFilter:['tab-label']});},processRemovedChild_:function(child){for(var i=0;i<this.tabs_.length;i++){this.tabs_[i].id=i;if(this.tabs_[i].content===child){this.tabs_[i].observers.forAttributeSelected.disconnect();this.tabs_[i].observers.forAttributeTabLabel.disconnect();if(this.tabs_[i]===this.selectedTab_){this.clearSelectedTab_();this.fire('selected-tab-change');}
-child.removeAttribute('selected');delete child.selected;this.tabs_.splice(i,1);i--;}}},childAttributesChanged_:function(mutations,observer){var tabObject=undefined;for(var i=0;i<this.tabs_.length;i++){var observers=this.tabs_[i].observers;if(observers.forAttributeSelected===observer||observers.forAttributeTabLabel===observer){tabObject=this.tabs_[i];break;}}
-if(!tabObject)
-return;for(var i=0;i<mutations.length;i++){var node=tabObject.content;if(mutations[i].attributeName==='tab-label')
-tabObject.label=node.getAttribute('tab-label');if(mutations[i].attributeName==='selected'){var nodeIsSelected=node.hasAttribute('selected');if(nodeIsSelected)
-this.changeSelectedTabById_(tabObject.id);else
-this.changeSelectedTabById_(undefined);}}},childrenUpdated_:function(mutations,observer){mutations.forEach(function(mutation){for(var i=0;i<mutation.removedNodes.length;i++)
-this.processRemovedChild_(mutation.removedNodes[i]);for(var i=0;i<mutation.addedNodes.length;i++)
-this.processAddedChild_(mutation.addedNodes[i]);},this);},tabButtonSelectHandler_:function(event,detail,sender){this.changeSelectedTabById_(sender.getAttribute('button-id'));},changeSelectedTabById_:function(id){var newTab=id!==undefined?this.tabs_[id]:undefined;var changed=this.selectedTab_!==newTab;this.saveCurrentTabScrollPosition_();this.clearSelectedTab_();if(id!==undefined){this.setSelectedTabById_(id);this.restoreCurrentTabScrollPosition_();}
-if(changed)
-this.fire('selected-tab-change');},setSelectedTabById_:function(id){this.selectedTab_=this.tabs_[id];this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.setAttribute('selected','selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});},saveTabStates:function(){this.saveCurrentTabScrollPosition_();},saveCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.selectedTab_.content._savedScrollTop=this.$['content-container'].scrollTop;this.selectedTab_.content._savedScrollLeft=this.$['content-container'].scrollLeft;}},restoreCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.$['content-container'].scrollTop=this.selectedTab_.content._savedScrollTop||0;this.$['content-container'].scrollLeft=this.selectedTab_.content._savedScrollLeft||0;}},clearSelectedTab_:function(){if(this.selectedTab_){this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.removeAttribute('selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});this.selectedTab_=undefined;}}});'use strict';Polymer('tr-ui-a-sub-view',{set tabLabel(label){return this.setAttribute('tab-label',label);},get tabLabel(){return this.getAttribute('tab-label');},get requiresTallView(){return false;},get relatedEventsToHighlight(){return undefined;},set selection(selection){throw new Error('Not implemented!');},get selection(){throw new Error('Not implemented!');}});'use strict';tr.exportTo('tr.ui.b',function(){var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;function BrushingState(){this.guid_=tr.b.GUID.allocate();this.selection_=new EventSet();this.findMatches_=new EventSet();this.analysisViewRelatedEvents_=new EventSet();this.analysisLinkHoveredEvents_=new EventSet();this.appliedToModel_=undefined;this.viewSpecificBrushingStates_={};}
+function createIRFinderTestCaseStringFromModel(model){var filename=window.location.hash.substr(1);var testName=filename.substr(filename.lastIndexOf('/')+1);testName=testName.substr(0,testName.indexOf('.'));try{var testLines=[];testLines.push('  /*');testLines.push('    This test was generated from');testLines.push('    '+filename+'');testLines.push('   */');testLines.push('  test(\''+testName+'\', function() {');testLines.push('    var verifier = new UserExpectationVerifier();');testLines.push('    verifier.customizeModelCallback = function(model) {');testLines.push.apply(testLines,createCustomizeModelLinesFromModel(model));testLines.push('    };');testLines.push('    verifier.expectedIRs = [');testLines.push.apply(testLines,createExpectedIRLinesFromModel(model));testLines.push('    ];');testLines.push('    verifier.verify();');testLines.push('  });');return testLines.join('\n');}catch(error){return error;}}
+return{UserModelBuilder:UserModelBuilder,createIRFinderTestCaseStringFromModel:createIRFinderTestCaseStringFromModel};});'use strict';tr.exportTo('tr.importer',function(){var Timing=tr.b.Timing;function ImportOptions(){this.shiftWorldToZero=true;this.pruneEmptyContainers=true;this.showImportWarnings=true;this.trackDetailedModelStats=false;this.customizeModelCallback=undefined;var auditorTypes=tr.c.Auditor.getAllRegisteredTypeInfos();this.auditorConstructors=auditorTypes.map(function(typeInfo){return typeInfo.constructor;});}
+function Import(model,opt_options){if(model===undefined)
+throw new Error('Must provide model to import into.');this.importing_=false;this.importOptions_=opt_options||new ImportOptions();this.model_=model;this.model_.importOptions=this.importOptions_;}
+Import.prototype={__proto__:Object.prototype,importTraces:function(traces){var progressMeter={update:function(msg){}};tr.b.Task.RunSynchronously(this.createImportTracesTask(progressMeter,traces));},importTracesWithProgressDialog:function(traces){if(tr.isHeadless)
+throw new Error('Cannot use this method in headless mode.');var overlay=tr.ui.b.Overlay();overlay.title='Importing...';overlay.userCanClose=false;overlay.msgEl=document.createElement('div');overlay.appendChild(overlay.msgEl);overlay.msgEl.style.margin='20px';overlay.update=function(msg){this.msgEl.textContent=msg;};overlay.visible=true;var promise=tr.b.Task.RunWhenIdle(this.createImportTracesTask(overlay,traces));promise.then(function(){overlay.visible=false;},function(err){overlay.visible=false;});return promise;},createImportTracesTask:function(progressMeter,traces){if(this.importing_)
+throw new Error('Already importing.');this.importing_=true;var importTask=new tr.b.Task(function prepareImport(){progressMeter.update('I will now import your traces for you...');},this);var lastTask=importTask;var importers=[];lastTask=lastTask.timedAfter('TraceImport',function createImports(){traces=traces.slice(0);progressMeter.update('Creating importers...');for(var i=0;i<traces.length;++i)
+importers.push(this.createImporter_(traces[i]));for(var i=0;i<importers.length;i++){var subtraces=importers[i].extractSubtraces();for(var j=0;j<subtraces.length;j++){try{traces.push(subtraces[j]);importers.push(this.createImporter_(subtraces[j]));}catch(error){console.warn(error.name+': '+error.message);continue;}}}
+if(traces.length&&!this.hasEventDataDecoder_(importers)){throw new Error('Could not find an importer for the provided eventData.');}
+importers.sort(function(x,y){return x.importPriority-y.importPriority;});},this);lastTask=lastTask.timedAfter('TraceImport',function importClockSyncMarkers(task){importers.forEach(function(importer,index){task.subTask(Timing.wrapNamedFunction('TraceImport',importer.importerName,function runImportClockSyncMarkersOnOneImporter(){progressMeter.update('Importing clock sync markers '+(index+1)+' of '+
+importers.length);importer.importClockSyncMarkers();}),this);},this);},this);lastTask=lastTask.timedAfter('TraceImport',function runImport(task){importers.forEach(function(importer,index){task.subTask(Timing.wrapNamedFunction('TraceImport',importer.importerName,function runImportEventsOnOneImporter(){progressMeter.update('Importing '+(index+1)+' of '+importers.length);importer.importEvents();}),this);},this);},this);if(this.importOptions_.customizeModelCallback){lastTask=lastTask.timedAfter('TraceImport',function runCustomizeCallbacks(task){this.importOptions_.customizeModelCallback(this.model_);},this);}
+lastTask=lastTask.timedAfter('TraceImport',function importSampleData(task){importers.forEach(function(importer,index){progressMeter.update('Importing sample data '+(index+1)+'/'+importers.length);importer.importSampleData();},this);},this);lastTask=lastTask.timedAfter('TraceImport',function runAutoclosers(){progressMeter.update('Autoclosing open slices...');this.model_.autoCloseOpenSlices();this.model_.createSubSlices();},this);lastTask=lastTask.timedAfter('TraceImport',function finalizeImport(task){importers.forEach(function(importer,index){progressMeter.update('Finalizing import '+(index+1)+'/'+importers.length);importer.finalizeImport();},this);},this);lastTask=lastTask.timedAfter('TraceImport',function runPreinits(){progressMeter.update('Initializing objects (step 1/2)...');this.model_.preInitializeObjects();},this);if(this.importOptions_.pruneEmptyContainers){lastTask=lastTask.timedAfter('TraceImport',function runPruneEmptyContainers(){progressMeter.update('Pruning empty containers...');this.model_.pruneEmptyContainers();},this);}
+lastTask=lastTask.timedAfter('TraceImport',function runMergeKernelWithuserland(){progressMeter.update('Merging kernel with userland...');this.model_.mergeKernelWithUserland();},this);var auditors=[];lastTask=lastTask.timedAfter('TraceImport',function createAuditorsAndRunAnnotate(){progressMeter.update('Adding arbitrary data to model...');auditors=this.importOptions_.auditorConstructors.map(function(auditorConstructor){return new auditorConstructor(this.model_);},this);auditors.forEach(function(auditor){auditor.runAnnotate();auditor.installUserFriendlyCategoryDriverIfNeeded();});},this);lastTask=lastTask.timedAfter('TraceImport',function computeWorldBounds(){progressMeter.update('Computing final world bounds...');this.model_.computeWorldBounds(this.importOptions_.shiftWorldToZero);},this);lastTask=lastTask.timedAfter('TraceImport',function buildFlowEventIntervalTree(){progressMeter.update('Building flow event map...');this.model_.buildFlowEventIntervalTree();},this);lastTask=lastTask.timedAfter('TraceImport',function joinRefs(){progressMeter.update('Joining object refs...');this.model_.joinRefs();},this);lastTask=lastTask.timedAfter('TraceImport',function cleanupUndeletedObjects(){progressMeter.update('Cleaning up undeleted objects...');this.model_.cleanupUndeletedObjects();},this);lastTask=lastTask.timedAfter('TraceImport',function sortMemoryDumps(){progressMeter.update('Sorting memory dumps...');this.model_.sortMemoryDumps();},this);lastTask=lastTask.timedAfter('TraceImport',function finalizeMemoryGraphs(){progressMeter.update('Finalizing memory dump graphs...');this.model_.finalizeMemoryGraphs();},this);lastTask=lastTask.timedAfter('TraceImport',function initializeObjects(){progressMeter.update('Initializing objects (step 2/2)...');this.model_.initializeObjects();},this);lastTask=lastTask.timedAfter('TraceImport',function buildEventIndices(){progressMeter.update('Building event indices...');this.model_.buildEventIndices();},this);lastTask=lastTask.timedAfter('TraceImport',function buildUserModel(){progressMeter.update('Building UserModel...');var userModelBuilder=new tr.importer.UserModelBuilder(this.model_);userModelBuilder.buildUserModel();},this);lastTask=lastTask.timedAfter('TraceImport',function sortExpectations(){progressMeter.update('Sorting user expectations...');this.model_.userModel.sortExpectations();},this);lastTask=lastTask.timedAfter('TraceImport',function runAudits(){progressMeter.update('Running auditors...');auditors.forEach(function(auditor){auditor.runAudit();});},this);lastTask=lastTask.timedAfter('TraceImport',function sortAlerts(){progressMeter.update('Updating alerts...');this.model_.sortAlerts();},this);lastTask=lastTask.timedAfter('TraceImport',function lastUpdateBounds(){progressMeter.update('Update bounds...');this.model_.updateBounds();},this);lastTask=lastTask.timedAfter('TraceImport',function addModelWarnings(){progressMeter.update('Looking for warnings...');if(!this.model_.isTimeHighResolution){this.model_.importWarning({type:'low_resolution_timer',message:'Trace time is low resolution, trace may be unusable.',showToUser:true});}},this);lastTask.after(function(){this.importing_=false;},this);return importTask;},createImporter_:function(eventData){var importerConstructor=tr.importer.Importer.findImporterFor(eventData);if(!importerConstructor){throw new Error('Couldn\'t create an importer for the provided '+'eventData.');}
+return new importerConstructor(this.model_,eventData);},hasEventDataDecoder_:function(importers){for(var i=0;i<importers.length;++i){if(!importers[i].isTraceDataContainer())
+return true;}
+return false;}};return{ImportOptions:ImportOptions,Import:Import};});'use strict';tr.exportTo('tr.e.cc',function(){function PictureAsImageData(picture,errorOrImageData){this.picture_=picture;if(errorOrImageData instanceof ImageData){this.error_=undefined;this.imageData_=errorOrImageData;}else{this.error_=errorOrImageData;this.imageData_=undefined;}};PictureAsImageData.Pending=function(picture){return new PictureAsImageData(picture,undefined);};PictureAsImageData.prototype={get picture(){return this.picture_;},get error(){return this.error_;},get imageData(){return this.imageData_;},isPending:function(){return this.error_===undefined&&this.imageData_===undefined;},asCanvas:function(){if(!this.imageData_)
+return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.imageData_.width;canvas.height=this.imageData_.height;ctx.putImageData(this.imageData_,0,0);return canvas;}};return{PictureAsImageData:PictureAsImageData};});'use strict';tr.exportTo('tr.e.cc',function(){var convertedNameCache={};function convertNameToJSConvention(name){if(name in convertedNameCache)
+return convertedNameCache[name];if(name[0]=='_'||name[name.length-1]=='_'){convertedNameCache[name]=name;return name;}
+var words=name.split('_');if(words.length==1){convertedNameCache[name]=words[0];return words[0];}
+for(var i=1;i<words.length;i++)
+words[i]=words[i][0].toUpperCase()+words[i].substring(1);convertedNameCache[name]=words.join('');return convertedNameCache[name];}
+function convertObjectFieldNamesToJSConventions(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){delete object[fieldName];object[newFieldName]=fieldValue;return newFieldName;});}
+function convertQuadSuffixedTypesToQuads(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){});}
+function convertObject(object){convertObjectFieldNamesToJSConventions(object);convertQuadSuffixedTypesToQuads(object);}
+function moveRequiredFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
+throw Error('Expected field '+key+' not found in args');if(object[key]!==undefined)
+throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
+function moveOptionalFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
+continue;if(object[key]!==undefined)
+throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
+function preInitializeObject(object){preInitializeObjectInner(object.args,false);}
+function preInitializeObjectInner(object,hasRecursed){if(!(object instanceof Object))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++)
+preInitializeObjectInner(object[i],true);return;}
+if(hasRecursed&&(object instanceof tr.model.ObjectSnapshot||object instanceof tr.model.ObjectInstance))
+return;for(var key in object){var newKey=convertNameToJSConvention(key);if(newKey!=key){var value=object[key];delete object[key];object[newKey]=value;key=newKey;}
+if(/Quad$/.test(key)&&!(object[key]instanceof tr.b.Quad)){var q;try{q=tr.b.Quad.from8Array(object[key]);}catch(e){console.log(e);}
+object[key]=q;continue;}
+if(/Rect$/.test(key)&&!(object[key]instanceof tr.b.Rect)){var r;try{r=tr.b.Rect.fromArray(object[key]);}catch(e){console.log(e);}
+object[key]=r;}
+preInitializeObjectInner(object[key],true);}}
+function bytesToRoundedMegabytes(bytes){return Math.round(bytes/100000.0)/10.0;}
+return{preInitializeObject:preInitializeObject,convertNameToJSConvention:convertNameToJSConvention,moveRequiredFieldsFromArgsToToplevel:moveRequiredFieldsFromArgsToToplevel,moveOptionalFieldsFromArgsToToplevel:moveOptionalFieldsFromArgsToToplevel,bytesToRoundedMegabytes:bytesToRoundedMegabytes};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var PictureCount=0;var OPS_TIMING_ITERATIONS=3;function Picture(skp64,layerRect){this.skp64_=skp64;this.layerRect_=layerRect;this.guid_=tr.b.GUID.allocate();}
+Picture.prototype={get canSave(){return true;},get layerRect(){return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){return this.skp64_;},getOps:function(){if(!PictureSnapshot.CanGetOps()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+var ops=window.chrome.skiaBenchmarking.getOps({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!ops)
+console.error('Failed to get picture ops.');return ops;},getOpTimings:function(){if(!PictureSnapshot.CanGetOpTimings()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+var opTimings=window.chrome.skiaBenchmarking.getOpTimings({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!opTimings)
+console.error('Failed to get picture op timings.');return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
+return ops;if(opTimings[iteration].cmd_times.length!=ops.length)
+return ops;}
+for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
+min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
+return ops;},rasterize:function(params,rasterCompleteCallback){if(!PictureSnapshot.CanRasterize()||!PictureSnapshot.CanGetOps()){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,tr.e.cc.PictureSnapshot.HowToEnablePictureDebugging()));return;}
+var raster=window.chrome.skiaBenchmarking.rasterize({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}},{stop:params.stopIndex===undefined?-1:params.stopIndex,overdraw:!!params.showOverdraw,params:{}});if(raster){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=raster.width;canvas.height=raster.height;var imageData=ctx.createImageData(raster.width,raster.height);imageData.data.set(new Uint8ClampedArray(raster.data));rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,imageData));}else{var error='Failed to rasterize picture. '+'Your recording may be from an old Chrome version. '+'The SkPicture format is not backward compatible.';rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,error));}}};function LayeredPicture(pictures){this.guid_=tr.b.GUID.allocate();this.pictures_=pictures;this.layerRect_=undefined;}
+LayeredPicture.prototype={__proto__:Picture.prototype,get canSave(){return false;},get typeName(){return'cc::LayeredPicture';},get layerRect(){if(this.layerRect_!==undefined)
+return this.layerRect_;this.layerRect_={x:0,y:0,width:0,height:0};for(var i=0;i<this.pictures_.length;++i){var rect=this.pictures_[i].layerRect;this.layerRect_.x=Math.min(this.layerRect_.x,rect.x);this.layerRect_.y=Math.min(this.layerRect_.y,rect.y);this.layerRect_.width=Math.max(this.layerRect_.width,rect.x+rect.width);this.layerRect_.height=Math.max(this.layerRect_.height,rect.y+rect.height);}
+return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){throw new Error('Not available with a LayeredPicture.');},getOps:function(){var ops=[];for(var i=0;i<this.pictures_.length;++i)
+ops=ops.concat(this.pictures_[i].getOps());return ops;},getOpTimings:function(){var opTimings=this.pictures_[0].getOpTimings();for(var i=1;i<this.pictures_.length;++i){var timings=this.pictures_[i].getOpTimings();opTimings.cmd_times=opTimings.cmd_times.concat(timings.cmd_times);opTimings.total_time+=timings.total_time;}
+return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
+return ops;}
+for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
+min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
+return ops;},rasterize:function(params,rasterCompleteCallback){this.picturesAsImageData_=[];var rasterCallback=function(pictureAsImageData){this.picturesAsImageData_.push(pictureAsImageData);if(this.picturesAsImageData_.length!==this.pictures_.length)
+return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.layerRect.width;canvas.height=this.layerRect.height;for(var i=0;i<this.picturesAsImageData_.length;++i){ctx.putImageData(this.picturesAsImageData_[i].imageData,this.pictures_[i].layerRect.x,this.pictures_[i].layerRect.y);}
+this.picturesAsImageData_=[];rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,ctx.getImageData(this.layerRect.x,this.layerRect.y,this.layerRect.width,this.layerRect.height)));}.bind(this);for(var i=0;i<this.pictures_.length;++i)
+this.pictures_[i].rasterize(params,rasterCallback);}};function PictureSnapshot(){ObjectSnapshot.apply(this,arguments);}
+PictureSnapshot.HasSkiaBenchmarking=function(){return tr.isExported('chrome.skiaBenchmarking');}
+PictureSnapshot.CanRasterize=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.rasterize)
+return false;return true;}
+PictureSnapshot.CanGetOps=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.getOps)
+return false;return true;}
+PictureSnapshot.CanGetOpTimings=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.getOpTimings)
+return false;return true;}
+PictureSnapshot.CanGetInfo=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.getInfo)
+return false;return true;}
+PictureSnapshot.HowToEnablePictureDebugging=function(){if(tr.isHeadless)
+return'Pictures only work in chrome';var usualReason=['For pictures to show up, you need to have Chrome running with ','--enable-skia-benchmarking. Please restart chrome with this flag ','and try again.'].join('');if(!tr.isExported('global.chrome.skiaBenchmarking'))
+return usualReason;if(!global.chrome.skiaBenchmarking.rasterize)
+return'Your chrome is old';if(!global.chrome.skiaBenchmarking.getOps)
+return'Your chrome is old: skiaBenchmarking.getOps not found';if(!global.chrome.skiaBenchmarking.getOpTimings)
+return'Your chrome is old: skiaBenchmarking.getOpTimings not found';if(!global.chrome.skiaBenchmarking.getInfo)
+return'Your chrome is old: skiaBenchmarking.getInfo not found';return'Rasterizing is on';}
+PictureSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.rasterResult_=undefined;},initialize:function(){if(this.args.alias)
+this.args=this.args.alias.args;if(!this.args.params.layerRect)
+throw new Error('Missing layer rect');this.layerRect_=this.args.params.layerRect;this.picture_=new Picture(this.args.skp64,this.args.params.layerRect);},set picture(picture){this.picture_=picture;},get canSave(){return this.picture_.canSave;},get layerRect(){return this.layerRect_?this.layerRect_:this.picture_.layerRect;},get guid(){return this.picture_.guid;},getBase64SkpData:function(){return this.picture_.getBase64SkpData();},getOps:function(){return this.picture_.getOps();},getOpTimings:function(){return this.picture_.getOpTimings();},tagOpsWithTimings:function(ops){return this.picture_.tagOpsWithTimings(ops);},rasterize:function(params,rasterCompleteCallback){this.picture_.rasterize(params,rasterCompleteCallback);}};ObjectSnapshot.register(PictureSnapshot,{typeNames:['cc::Picture']});return{PictureSnapshot:PictureSnapshot,Picture:Picture,LayeredPicture:LayeredPicture};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function DisplayItemList(skp64,layerRect){tr.e.cc.Picture.apply(this,arguments);}
+DisplayItemList.prototype={__proto__:tr.e.cc.Picture.prototype};function DisplayItemListSnapshot(){tr.e.cc.PictureSnapshot.apply(this,arguments);}
+DisplayItemListSnapshot.prototype={__proto__:tr.e.cc.PictureSnapshot.prototype,initialize:function(){tr.e.cc.PictureSnapshot.prototype.initialize.call(this);this.displayItems_=this.args.params.items;},get items(){return this.displayItems_;}};ObjectSnapshot.register(DisplayItemListSnapshot,{typeNames:['cc::DisplayItemList']});return{DisplayItemListSnapshot:DisplayItemListSnapshot,DisplayItemList:DisplayItemList};});'use strict';tr.exportTo('tr.e.cc',function(){var constants={};constants.ACTIVE_TREE=0;constants.PENDING_TREE=1;constants.HIGH_PRIORITY_BIN=0;constants.LOW_PRIORITY_BIN=1;constants.SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';constants.BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';return{constants:constants};});'use strict';tr.exportTo('tr.e.cc',function(){function Region(){this.rects=[];}
+Region.fromArray=function(array){if(array.length%4!=0)
+throw new Error('Array must consist be a multiple of 4 in length');var r=new Region();for(var i=0;i<array.length;i+=4){r.rects.push(tr.b.Rect.fromXYWH(array[i],array[i+1],array[i+2],array[i+3]));}
+return r;}
+Region.fromArrayOrUndefined=function(array){if(array===undefined)
+return new Region();return Region.fromArray(array);};Region.prototype={__proto__:Region.prototype,rectIntersects:function(r){for(var i=0;i<this.rects.length;i++){if(this.rects[i].intersects(r))
+return true;}
+return false;},addRect:function(r){this.rects.push(r);}};return{Region:Region};});'use strict';tr.exportTo('tr.e.cc',function(){function TileCoverageRect(rect,tile){this.geometryRect=rect;this.tile=tile;}
+return{TileCoverageRect:TileCoverageRect};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeImpl_=undefined;this.parentLayer=undefined;},initialize:function(){this.invalidation=new tr.e.cc.Region();this.annotatedInvalidation=new tr.e.cc.Region();this.unrecordedRegion=new tr.e.cc.Region();this.pictures=[];tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['layerId','children','layerQuad']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['maskLayer','replicaLayer','idealContentsScale','geometryContentsScale','layoutRects','usingGpuRasterization']);this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;this.bounds=tr.b.Rect.fromXYWH(0,0,this.args.bounds.width,this.args.bounds.height);if(this.args.animationBounds){this.animationBoundsRect=tr.b.Rect.fromXYWH(this.args.animationBounds[0],this.args.animationBounds[1],this.args.animationBounds[3],this.args.animationBounds[4]);}
+for(var i=0;i<this.children.length;i++)
+this.children[i].parentLayer=this;if(this.maskLayer)
+this.maskLayer.parentLayer=this;if(this.replicaLayer)
+this.replicaLayer.parentLayer=this;if(!this.geometryContentsScale)
+this.geometryContentsScale=1.0;if(!this.idealContentsScale)
+this.idealContentsScale=1.0;this.touchEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.touchEventHandlerRegion);this.wheelEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.wheelEventHandlerRegion);this.nonFastScrollableRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.nonFastScrollableRegion);},get layerTreeImpl(){if(this.layerTreeImpl_)
+return this.layerTreeImpl_;if(this.parentLayer)
+return this.parentLayer.layerTreeImpl;return undefined;},set layerTreeImpl(layerTreeImpl){this.layerTreeImpl_=layerTreeImpl;},get activeLayer(){if(this.layerTreeImpl.whichTree==constants.ACTIVE_TREE)
+return this;var activeTree=this.layerTreeImpl.layerTreeHostImpl.activeTree;return activeTree.findLayerWithId(this.layerId);},get pendingLayer(){if(this.layerTreeImpl.whichTree==constants.PENDING_TREE)
+return this;var pendingTree=this.layerTreeImpl.layerTreeHostImpl.pendingTree;return pendingTree.findLayerWithId(this.layerId);}};function PictureLayerImplSnapshot(){LayerImplSnapshot.apply(this,arguments);}
+PictureLayerImplSnapshot.prototype={__proto__:LayerImplSnapshot.prototype,initialize:function(){LayerImplSnapshot.prototype.initialize.call(this);if(this.args.invalidation){this.invalidation=tr.e.cc.Region.fromArray(this.args.invalidation);delete this.args.invalidation;}
+if(this.args.annotatedInvalidationRects){this.annotatedInvalidation=new tr.e.cc.Region();for(var i=0;i<this.args.annotatedInvalidationRects.length;++i){var annotatedRect=this.args.annotatedInvalidationRects[i];var rect=annotatedRect.geometryRect;rect.reason=annotatedRect.reason;this.annotatedInvalidation.addRect(rect);}
+delete this.args.annotatedInvalidationRects;}
+if(this.args.unrecordedRegion){this.unrecordedRegion=tr.e.cc.Region.fromArray(this.args.unrecordedRegion);delete this.args.unrecordedRegion;}
+if(this.args.pictures){this.pictures=this.args.pictures;this.pictures.sort(function(a,b){return a.ts-b.ts;});}
+this.tileCoverageRects=[];if(this.args.coverageTiles){for(var i=0;i<this.args.coverageTiles.length;++i){var rect=this.args.coverageTiles[i].geometryRect.scale(this.idealContentsScale);var tile=this.args.coverageTiles[i].tile;this.tileCoverageRects.push(new tr.e.cc.TileCoverageRect(rect,tile));}
+delete this.args.coverageTiles;}}};ObjectSnapshot.register(PictureLayerImplSnapshot,{typeName:'cc::PictureLayerImpl'});ObjectSnapshot.register(LayerImplSnapshot,{typeNames:['cc::LayerImpl','cc::DelegatedRendererLayerImpl','cc::HeadsUpDisplayLayerImpl','cc::IOSurfaceLayerImpl','cc::NinePatchLayerImpl','cc::PictureImageLayerImpl','cc::ScrollbarLayerImpl','cc::SolidColorLayerImpl','cc::SurfaceLayerImpl','cc::TextureLayerImpl','cc::TiledLayerImpl','cc::VideoLayerImpl','cc::PaintedScrollbarLayerImpl','ClankPatchLayer','TabBorderLayer','CounterLayer']});return{LayerImplSnapshot:LayerImplSnapshot,PictureLayerImplSnapshot:PictureLayerImplSnapshot};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerTreeImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeHostImpl=undefined;this.whichTree=undefined;this.sourceFrameNumber=undefined;},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['rootLayer','renderSurfaceLayerList']);if(this.args.sourceFrameNumber)
+this.sourceFrameNumber=this.args.sourceFrameNumber;this.rootLayer.layerTreeImpl=this;if(this.args.swapPromiseTraceIds&&this.args.swapPromiseTraceIds.length){this.tracedInputLatencies=[];var ownProcess=this.objectInstance.parent;var modelHelper=ownProcess.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper)
+this._initializeTracedInputLatencies(modelHelper);}},_initializeTracedInputLatencies:function(modelHelper){var latencyEvents=modelHelper.browserHelper.getLatencyEventsInRange(modelHelper.model.bounds);latencyEvents.forEach(function(event){for(var i=0;i<this.args.swapPromiseTraceIds.length;i++){if(!event.args.data||!event.args.data.trace_id)
+continue;if(parseInt(event.args.data.trace_id)===this.args.swapPromiseTraceIds[i])
+this.tracedInputLatencies.push(event);}},this);},get hasSourceFrameBeenDrawnBefore(){if(this.whichTree==tr.e.cc.constants.PENDING_TREE)
+return false;if(this.sourceFrameNumber===undefined)
+return;var thisLTHI=this.layerTreeHostImpl;var thisLTHIIndex=thisLTHI.objectInstance.snapshots.indexOf(thisLTHI);var prevLTHIIndex=thisLTHIIndex-1;if(prevLTHIIndex<0||prevLTHIIndex>=thisLTHI.objectInstance.snapshots.length)
+return false;var prevLTHI=thisLTHI.objectInstance.snapshots[prevLTHIIndex];if(!prevLTHI.activeTree)
+return false;if(prevLTHI.activeTree.sourceFrameNumber===undefined)
+return;return prevLTHI.activeTree.sourceFrameNumber==this.sourceFrameNumber;},get otherTree(){var other=this.whichTree==constants.ACTIVE_TREE?constants.PENDING_TREE:constants.ACTIVE_TREE;return this.layerTreeHostImpl.getTree(other);},get gpuMemoryUsageInBytes(){var totalBytes=0;this.iterLayers(function(layer){if(layer.gpuMemoryUsageInBytes!==undefined)
+totalBytes+=layer.gpuMemoryUsageInBytes;});return totalBytes;},iterLayers:function(func,thisArg){var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])
+return;visitedLayers[layer.layerId]=true;func.call(thisArg,layer,depth,isMask,isReplica);if(layer.children){for(var i=0;i<layer.children.length;i++)
+visitLayer(layer.children[i],depth+1);}
+if(layer.maskLayer)
+visitLayer(layer.maskLayer,depth+1,true,false);if(layer.replicaLayer)
+visitLayer(layer.replicaLayer,depth+1,false,true);}
+visitLayer(this.rootLayer,0,false,false);},findLayerWithId:function(id){var foundLayer=undefined;function visitLayer(layer){if(layer.layerId==id)
+foundLayer=layer;}
+this.iterLayers(visitLayer);return foundLayer;}};ObjectSnapshot.register(LayerTreeImplSnapshot,{typeName:'cc::LayerTreeImpl'});return{LayerTreeImplSnapshot:LayerTreeImplSnapshot};});'use strict';tr.exportTo('tr.b',function(){function BBox2(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};BBox2.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addBBox2:function(bbox2){if(bbox2.isEmpty)
+return;this.addVec2(bbox2.min_);this.addVec2(bbox2.max_);},clone:function(){var bbox=new BBox2();bbox.addBBox2(this);return bbox;},addXY:function(x,y){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,x,y);vec2.set(this.min_,x,y);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],x);this.max_[1]=Math.max(this.max_[1],y);this.min_[0]=Math.min(this.min_[0],x);this.min_[1]=Math.min(this.min_[1],y);},addVec2:function(value){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,value[0],value[1]);vec2.set(this.min_,value[0],value[1]);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],value[0]);this.max_[1]=Math.max(this.max_[1],value[1]);this.min_[0]=Math.min(this.min_[0],value[0]);this.min_[1]=Math.min(this.min_[1],value[1]);},addQuad:function(quad){this.addVec2(quad.p1);this.addVec2(quad.p2);this.addVec2(quad.p3);this.addVec2(quad.p4);},get minVec2(){if(this.isEmpty_)
+return undefined;return this.min_;},get maxVec2(){if(this.isEmpty_)
+return undefined;return this.max_;},get sizeAsVec2(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no size');var size=vec2.create();vec2.subtract(size,this.max_,this.min_);return size;},get size(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no size');return{width:this.max_[0]-this.min_[0],height:this.max_[1]-this.min_[1]};},get width(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no width');return this.max_[0]-this.min_[0];},get height(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no width');return this.max_[1]-this.min_[1];},toString:function(){if(this.isEmpty_)
+return'empty';return'min=('+this.min_[0]+','+this.min_[1]+') '+'max=('+this.max_[0]+','+this.max_[1]+')';},asRect:function(){return tr.b.Rect.fromXYWH(this.min_[0],this.min_[1],this.max_[0]-this.min_[0],this.max_[1]-this.min_[1]);}};return{BBox2:BBox2};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayerTreeHostImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeHostImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['deviceViewportSize','activeTree']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['pendingTree']);if(this.args.activeTiles!==undefined){this.activeTiles=this.args.activeTiles;delete this.args.activeTiles;}else if(this.args.tiles!==undefined){this.activeTiles=this.args.tiles;delete this.args.tiles;}
+if(!this.activeTiles)
+this.activeTiles=[];this.activeTree.layerTreeHostImpl=this;this.activeTree.whichTree=constants.ACTIVE_TREE;if(this.pendingTree){this.pendingTree.layerTreeHostImpl=this;this.pendingTree.whichTree=constants.PENDING_TREE;}},getContentsScaleNames:function(){var scales={};for(var i=0;i<this.activeTiles.length;++i){var tile=this.activeTiles[i];scales[tile.contentsScale]=tile.resolution;}
+return scales;},getTree:function(whichTree){if(whichTree==constants.ACTIVE_TREE)
+return this.activeTree;if(whichTree==constants.PENDING_TREE)
+return this.pendingTree;throw new Exception('Unknown tree type + '+whichTree);},get tilesHaveGpuMemoryUsageInfo(){if(this.tilesHaveGpuMemoryUsageInfo_!==undefined)
+return this.tilesHaveGpuMemoryUsageInfo_;for(var i=0;i<this.activeTiles.length;i++){if(this.activeTiles[i].gpuMemoryUsageInBytes===undefined)
+continue;this.tilesHaveGpuMemoryUsageInfo_=true;return true;}
+this.tilesHaveGpuMemoryUsageInfo_=false;return false;},get gpuMemoryUsageInBytes(){if(!this.tilesHaveGpuMemoryUsageInfo)
+return;var usage=0;for(var i=0;i<this.activeTiles.length;i++){var u=this.activeTiles[i].gpuMemoryUsageInBytes;if(u!==undefined)
+usage+=u;}
+return usage;},get userFriendlyName(){var frameNumber;if(!this.activeTree){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{if(this.activeTree.sourceFrameNumber===undefined)
+frameNumber=this.objectInstance.snapshots.indexOf(this);else
+frameNumber=this.activeTree.sourceFrameNumber;}
+return'cc::LayerTreeHostImpl frame '+frameNumber;}};ObjectSnapshot.register(LayerTreeHostImplSnapshot,{typeName:'cc::LayerTreeHostImpl'});function LayerTreeHostImplInstance(){ObjectInstance.apply(this,arguments);this.allLayersBBox_=undefined;}
+LayerTreeHostImplInstance.prototype={__proto__:ObjectInstance.prototype,get allContentsScales(){if(this.allContentsScales_)
+return this.allContentsScales_;var scales={};for(var tileID in this.allTileHistories_){var tileHistory=this.allTileHistories_[tileID];scales[tileHistory.contentsScale]=true;}
+this.allContentsScales_=tr.b.dictionaryKeys(scales);return this.allContentsScales_;},get allLayersBBox(){if(this.allLayersBBox_)
+return this.allLayersBBox_;var bbox=new tr.b.BBox2();function handleTree(tree){tree.renderSurfaceLayerList.forEach(function(layer){bbox.addQuad(layer.layerQuad);});}
+this.snapshots.forEach(function(lthi){handleTree(lthi.activeTree);if(lthi.pendingTree)
+handleTree(lthi.pendingTree);});this.allLayersBBox_=bbox;return this.allLayersBBox_;}};ObjectInstance.register(LayerTreeHostImplInstance,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshot:LayerTreeHostImplSnapshot,LayerTreeHostImplInstance:LayerTreeHostImplInstance};});'use strict';tr.exportTo('tr.e.cc',function(){var tileTypes={highRes:'highRes',lowRes:'lowRes',extraHighRes:'extraHighRes',extraLowRes:'extraLowRes',missing:'missing',culled:'culled',solidColor:'solidColor',picture:'picture',directPicture:'directPicture',unknown:'unknown'};var tileBorder={highRes:{color:'rgba(80, 200, 200, 0.7)',width:1},lowRes:{color:'rgba(212, 83, 192, 0.7)',width:2},extraHighRes:{color:'rgba(239, 231, 20, 0.7)',width:2},extraLowRes:{color:'rgba(93, 186, 18, 0.7)',width:2},missing:{color:'rgba(255, 0, 0, 0.7)',width:1},culled:{color:'rgba(160, 100, 0, 0.8)',width:1},solidColor:{color:'rgba(128, 128, 128, 0.7)',width:1},picture:{color:'rgba(64, 64, 64, 0.7)',width:1},directPicture:{color:'rgba(127, 255, 0, 1.0)',width:1},unknown:{color:'rgba(0, 0, 0, 1.0)',width:2}};return{tileTypes:tileTypes,tileBorder:tileBorder};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function TileSnapshot(){ObjectSnapshot.apply(this,arguments);}
+TileSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['layerId','contentsScale','contentRect']);if(this.args.managedState){this.resolution=this.args.managedState.resolution;this.isSolidColor=this.args.managedState.isSolidColor;this.isUsingGpuMemory=this.args.managedState.isUsingGpuMemory;this.hasResource=this.args.managedState.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}else{this.resolution=this.args.resolution;this.isSolidColor=this.args.drawInfo.isSolidColor;this.isUsingGpuMemory=this.args.isUsingGpuMemory;this.hasResource=this.args.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}
+if(this.contentRect)
+this.layerRect=this.contentRect.scale(1.0/this.contentsScale);if(this.isSolidColor)
+this.type_=tr.e.cc.tileTypes.solidColor;else if(!this.hasResource)
+this.type_=tr.e.cc.tileTypes.missing;else if(this.resolution==='HIGH_RESOLUTION')
+this.type_=tr.e.cc.tileTypes.highRes;else if(this.resolution==='LOW_RESOLUTION')
+this.type_=tr.e.cc.tileTypes.lowRes;else
+this.type_=tr.e.cc.tileTypes.unknown;},getTypeForLayer:function(layer){var type=this.type_;if(type==tr.e.cc.tileTypes.unknown){if(this.contentsScale<layer.idealContentsScale)
+type=tr.e.cc.tileTypes.extraLowRes;else if(this.contentsScale>layer.idealContentsScale)
+type=tr.e.cc.tileTypes.extraHighRes;}
+return type;}};ObjectSnapshot.register(TileSnapshot,{typeName:'cc::Tile'});return{TileSnapshot:TileSnapshot};});'use strict';tr.exportTo('tr.ui.b',function(){var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;function BrushingState(){this.guid_=tr.b.GUID.allocate();this.selection_=new EventSet();this.findMatches_=new EventSet();this.analysisViewRelatedEvents_=new EventSet();this.analysisLinkHoveredEvents_=new EventSet();this.appliedToModel_=undefined;this.viewSpecificBrushingStates_={};}
 BrushingState.prototype={get guid(){return this.guid_;},clone:function(){var that=new BrushingState();that.selection_=this.selection_;that.findMatches_=this.findMatches_;that.analysisViewRelatedEvents_=this.analysisViewRelatedEvents_;that.analysisLinkHoveredEvents_=this.analysisLinkHoveredEvents_;that.viewSpecificBrushingStates_=this.viewSpecificBrushingStates_;return that;},equals:function(that){if(!this.selection_.equals(that.selection_))
 return false;if(!this.findMatches_.equals(that.findMatches_))
 return false;if(!this.analysisViewRelatedEvents_.equals(that.analysisViewRelatedEvents_)){return false;}
@@ -4965,7 +5427,23 @@
 return;if(this.target_===undefined){this.activeAnimation_.didStopEarly(frameBeginTime,this.target_,false);return;}
 var oldTargetState=this.target_.cloneAnimationState();var done=this.activeAnimation_.tick(frameBeginTime,this.target_);if(done)
 this.activeAnimation_=undefined;if(this.activeAnimation_){this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);}
-if(oldTargetState){var e=new tr.b.Event('didtick');e.oldTargetState=oldTargetState;this.dispatchEvent(e,false,false);}}};return{AnimationController:AnimationController};});'use strict';tr.exportTo('tr.ui.b',function(){function createSpan(opt_dictionary){var ownerDocument=document;if(opt_dictionary&&opt_dictionary.ownerDocument)
+if(oldTargetState){var e=new tr.b.Event('didtick');e.oldTargetState=oldTargetState;this.dispatchEvent(e,false,false);}}};return{AnimationController:AnimationController};});'use strict';tr.exportTo('tr.b',function(){function Settings(){return Settings;};if(tr.b.unittest&&tr.b.unittest.TestRunner){tr.b.unittest.TestRunner.addEventListener('tr-unittest-will-run',function(){if(tr.isHeadless)
+Settings.setAlternativeStorageInstance(new HeadlessStorage());else
+Settings.setAlternativeStorageInstance(global.sessionStorage);});}
+function SessionSettings(){return SessionSettings;}
+function AddStaticStorageFunctionsToClass_(input_class,storage){input_class.storage_=storage;input_class.get=function(key,opt_default,opt_namespace){key=input_class.namespace_(key,opt_namespace);var rawVal=input_class.storage_.getItem(key);if(rawVal===null||rawVal===undefined)
+return opt_default;try{return JSON.parse(rawVal).value;}catch(e){input_class.storage_.removeItem(key);return opt_default;}};input_class.set=function(key,value,opt_namespace){if(value===undefined)
+throw new Error('Settings.set: value must not be undefined');var v=JSON.stringify({value:value});input_class.storage_.setItem(input_class.namespace_(key,opt_namespace),v);};input_class.keys=function(opt_namespace){var result=[];opt_namespace=opt_namespace||'';for(var i=0;i<input_class.storage_.length;i++){var key=input_class.storage_.key(i);if(input_class.isnamespaced_(key,opt_namespace))
+result.push(input_class.unnamespace_(key,opt_namespace));}
+return result;};input_class.isnamespaced_=function(key,opt_namespace){return key.indexOf(input_class.normalize_(opt_namespace))==0;};input_class.namespace_=function(key,opt_namespace){return input_class.normalize_(opt_namespace)+key;};input_class.unnamespace_=function(key,opt_namespace){return key.replace(input_class.normalize_(opt_namespace),'');};input_class.normalize_=function(opt_namespace){return input_class.NAMESPACE+(opt_namespace?opt_namespace+'.':'');};input_class.setAlternativeStorageInstance=function(instance){input_class.storage_=instance;};input_class.getAlternativeStorageInstance=function(){if(!tr.isHeadless&&input_class.storage_===localStorage)
+return undefined;return input_class.storage_;};input_class.NAMESPACE='trace-viewer';};function HeadlessStorage(){this.length=0;this.hasItem_={};this.items_={};this.itemsAsArray_=undefined;}
+HeadlessStorage.prototype={key:function(index){return this.itemsAsArray[index];},get itemsAsArray(){if(this.itemsAsArray_!==undefined)
+return this.itemsAsArray_;var itemsAsArray=[];for(var k in this.items_)
+itemsAsArray.push(k);this.itemsAsArray_=itemsAsArray;return this.itemsAsArray_;},getItem:function(key){if(!this.hasItem_[key])
+return null;return this.items_[key];},removeItem:function(key){if(!this.hasItem_[key])
+return;var value=this.items_[key];delete this.hasItem_[key];delete this.items_[key];this.length--;this.itemsAsArray_=undefined;return value;},setItem:function(key,value){if(this.hasItem_[key]){this.items_[key]=value;return;}
+this.items_[key]=value;this.hasItem_[key]=true;this.length++;this.itemsAsArray_=undefined;return value;}};if(tr.isHeadless){AddStaticStorageFunctionsToClass_(Settings,new HeadlessStorage());AddStaticStorageFunctionsToClass_(SessionSettings,new HeadlessStorage());}else{AddStaticStorageFunctionsToClass_(Settings,localStorage);AddStaticStorageFunctionsToClass_(SessionSettings,sessionStorage);}
+return{Settings:Settings,SessionSettings:SessionSettings};});'use strict';tr.exportTo('tr.ui.b',function(){function createSpan(opt_dictionary){var ownerDocument=document;if(opt_dictionary&&opt_dictionary.ownerDocument)
 ownerDocument=opt_dictionary.ownerDocument;var spanEl=ownerDocument.createElement('span');if(opt_dictionary){if(opt_dictionary.className)
 spanEl.className=opt_dictionary.className;if(opt_dictionary.textContent)
 spanEl.textContent=opt_dictionary.textContent;if(opt_dictionary.tooltip)
@@ -5008,11 +5486,16 @@
 opt_changeCb.call();}
 buttonEl.addEventListener('change',onChange);var id='#checkbox-'+nextCheckboxId++;var spanEl=createSpan({className:'labeled-checkbox'});buttonEl.setAttribute('id',id);var labelEl=document.createElement('label');labelEl.textContent=label;labelEl.setAttribute('for',id);spanEl.appendChild(buttonEl);spanEl.appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=buttonEl.checked!==(!!opt_bool);if(!changed)
 return;buttonEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return buttonEl.checked;});return spanEl;}
+function createButton(targetEl,targetElProperty,label,opt_changeCb){var buttonEl=document.createElement('input');buttonEl.type='button';function onClick(){if(opt_changeCb)
+opt_changeCb.call();}
+buttonEl.addEventListener('click',onClick);buttonEl.value=label;return buttonEl;}
+function createTextInput(targetEl,targetElProperty,settingsKey,defaultValue){var initialValue=tr.b.Settings.get(settingsKey,defaultValue);var el=document.createElement('input');el.type='text';function onChange(e){tr.b.Settings.set(settingsKey,el.value);targetEl[targetElProperty]=el.value;}
+el.addEventListener('input',onChange);el.value=initialValue;targetEl[targetElProperty]=initialValue;return el;}
 function isElementAttachedToDocument(el){var cur=el;while(cur.parentNode)
 cur=cur.parentNode;return(cur===el.ownerDocument||cur.nodeName==='#document-fragment');}
 function asHTMLOrTextNode(value,opt_ownerDocument){if(value instanceof Node)
 return value;var ownerDocument=opt_ownerDocument||document;return ownerDocument.createTextNode(value);}
-return{createSpan:createSpan,createDiv:createDiv,createScopedStyle:createScopedStyle,createSelector:createSelector,createOptionGroup:createOptionGroup,createCheckBox:createCheckBox,isElementAttachedToDocument:isElementAttachedToDocument,asHTMLOrTextNode:asHTMLOrTextNode};});'use strict';tr.exportTo('tr.ui.b',function(){var ColorScheme=tr.b.ColorScheme;var colors=ColorScheme.colors;var colorsAsStrings=ColorScheme.colorsAsStrings;var numColorsPerVariant=ColorScheme.properties.numColorsPerVariant;var SelectionState=tr.model.SelectionState;var EventPresenter={getSelectableItemColorAsString:function(item){var colorId=item.colorId+this.getColorIdOffset_(item);return colorsAsStrings[colorId];},getColorIdOffset_:function(event){return event.selectionState;},getTextColor:function(event){if(event.selectionState===SelectionState.DIMMED)
+return{createSpan:createSpan,createDiv:createDiv,createScopedStyle:createScopedStyle,createSelector:createSelector,createOptionGroup:createOptionGroup,createCheckBox:createCheckBox,createButton:createButton,createTextInput:createTextInput,isElementAttachedToDocument:isElementAttachedToDocument,asHTMLOrTextNode:asHTMLOrTextNode};});'use strict';tr.exportTo('tr.ui.b',function(){var ColorScheme=tr.b.ColorScheme;var colors=ColorScheme.colors;var colorsAsStrings=ColorScheme.colorsAsStrings;var numColorsPerVariant=ColorScheme.properties.numColorsPerVariant;var SelectionState=tr.model.SelectionState;var EventPresenter={getSelectableItemColorAsString:function(item){var colorId=item.colorId+this.getColorIdOffset_(item);return colorsAsStrings[colorId];},getColorIdOffset_:function(event){return event.selectionState;},getTextColor:function(event){if(event.selectionState===SelectionState.DIMMED)
 return'rgb(60,60,60)';return'rgb(0,0,0)';},getSliceColorId:function(slice){return slice.colorId+this.getColorIdOffset_(slice);},getSliceAlpha:function(slice,async){var alpha=1;if(async)
 alpha*=0.3;return alpha;},getInstantSliceColor:function(instant){var colorId=instant.colorId+this.getColorIdOffset_(instant);return colors[colorId].toStringWithAlphaOverride(1.0);},getObjectInstanceColor:function(instance){var colorId=instance.colorId+this.getColorIdOffset_(instance);return colors[colorId].toStringWithAlphaOverride(0.25);},getObjectSnapshotColor:function(snapshot){var colorId=snapshot.objectInstance.colorId+this.getColorIdOffset_(snapshot);return colors[colorId];},getCounterSeriesColor:function(colorId,selectionState,opt_alphaMultiplier){var event={selectionState:selectionState};var c=colors[colorId+this.getColorIdOffset_(event)];return c.toStringWithAlphaOverride(opt_alphaMultiplier!==undefined?opt_alphaMultiplier:1.0);},getBarSnapshotColor:function(snapshot,offset){var colorId=(snapshot.objectInstance.colorId+offset)%numColorsPerVariant;colorId+=this.getColorIdOffset_(snapshot);return colors[colorId].toStringWithAlphaOverride(1.0);}};return{EventPresenter:EventPresenter};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCacheDict={};var elidedTitleCache=new ElidedTitleCache();function ElidedTitleCache(){this.textWidthMap={};}
 ElidedTitleCache.prototype={get:function(ctx,pixWidth,title,width,sliceDuration){var elidedDict=elidedTitleCacheDict[title];if(!elidedDict){elidedDict={};elidedTitleCacheDict[title]=elidedDict;}
@@ -5137,7 +5620,7 @@
 this.textContent=opt_textContent;},getCurrentSelection_:function(){if(typeof this.selection_==='function')
 return this.selection_();return this.selection_;},setHighlight_:function(opt_eventSet){if(this.controller_)
 this.controller_.changeAnalysisLinkHoveredEvents(opt_eventSet);},clearHighlight_:function(opt_eventSet){this.setHighlight_();},onClicked_:function(){if(!this.selection_)
-return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=this.getCurrentSelection_();this.dispatchEvent(event);},onMouseEnter_:function(){this.setHighlight_(this.getCurrentSelection_());},onMouseLeave_:function(){this.clearHighlight_();}});'use strict';tr.exportTo('tr.ui.b',function(){var TableFormat={};TableFormat.SelectionMode={NONE:0,ROW:1,CELL:2};TableFormat.HighlightStyle={DEFAULT:0,NONE:1,LIGHT:2,DARK:3};return{TableFormat:TableFormat};});'use strict';(function(){var RIGHT_ARROW=String.fromCharCode(0x25b6);var UNSORTED_ARROW=String.fromCharCode(0x25BF);var ASCENDING_ARROW=String.fromCharCode(0x25B4);var DESCENDING_ARROW=String.fromCharCode(0x25BE);var BASIC_INDENTATION=8;var SelectionMode=tr.ui.b.TableFormat.SelectionMode;var HighlightStyle=tr.ui.b.TableFormat.HighlightStyle;Polymer('tr-ui-b-table',{created:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.customizeTableRowCallback_=undefined;},ready:function(){this.$.body.addEventListener('keydown',this.onKeyDown_.bind(this),true);},clear:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.textContent='';this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.subRowsPropertyName_='subRows';},get showHeader(){return this.showHeader_;},set showHeader(showHeader){this.showHeader_=showHeader;this.scheduleRebuildHeaders_();},set subRowsPropertyName(name){this.subRowsPropertyName_=name;},set customizeTableRowCallback(cb){this.customizeTableRowCallback_=cb;this.scheduleRebuildBody_();},get emptyValue(){return this.emptyValue_;},set emptyValue(emptyValue){var previousEmptyValue=this.emptyValue_;this.emptyValue_=emptyValue;if(this.tableRows_.length===0&&emptyValue!==previousEmptyValue)
+return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=this.getCurrentSelection_();this.dispatchEvent(event);},onMouseEnter_:function(){this.setHighlight_(this.getCurrentSelection_());},onMouseLeave_:function(){this.clearHighlight_();}});'use strict';tr.exportTo('tr.ui.b',function(){var TableFormat={};TableFormat.SelectionMode={NONE:0,ROW:1,CELL:2};TableFormat.HighlightStyle={DEFAULT:0,NONE:1,LIGHT:2,DARK:3};return{TableFormat:TableFormat};});'use strict';(function(){var RIGHT_ARROW=String.fromCharCode(0x25b6);var UNSORTED_ARROW=String.fromCharCode(0x25BF);var ASCENDING_ARROW=String.fromCharCode(0x25B4);var DESCENDING_ARROW=String.fromCharCode(0x25BE);var BASIC_INDENTATION=8;var SelectionMode=tr.ui.b.TableFormat.SelectionMode;var HighlightStyle=tr.ui.b.TableFormat.HighlightStyle;Polymer('tr-ui-b-table',{created:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.customizeTableRowCallback_=undefined;},ready:function(){this.$.body.addEventListener('keydown',this.onKeyDown_.bind(this),true);},clear:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.textContent='';this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.subRowsPropertyName_='subRows';this.defaultExpansionStateCallback_=undefined;},get showHeader(){return this.showHeader_;},set showHeader(showHeader){this.showHeader_=showHeader;this.scheduleRebuildHeaders_();},set subRowsPropertyName(name){this.subRowsPropertyName_=name;},set defaultExpansionStateCallback(cb){this.defaultExpansionStateCallback_=cb;this.scheduleRebuildBody_();},set customizeTableRowCallback(cb){this.customizeTableRowCallback_=cb;this.scheduleRebuildBody_();},get emptyValue(){return this.emptyValue_;},set emptyValue(emptyValue){var previousEmptyValue=this.emptyValue_;this.emptyValue_=emptyValue;if(this.tableRows_.length===0&&emptyValue!==previousEmptyValue)
 this.scheduleRebuildBody_();},set tableColumns(columns){var columnsWithExpandButtons=[];for(var i=0;i<columns.length;i++){if(columns[i].showExpandButtons)
 columnsWithExpandButtons.push(i);}
 if(columnsWithExpandButtons.length===0){columnsWithExpandButtons=[0];}
@@ -5150,7 +5633,7 @@
 throw new Error('Column '+number+' does not have a comparator.');this.sortColumnIndex_=number;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();},get sortColumnIndex(){return this.sortColumnIndex_;},set sortDescending(value){var newValue=!!value;if(newValue!==this.sortDescending_){this.sortDescending_=newValue;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();}},get sortDescending(){return this.sortDescending_;},updateHeaderArrows_:function(){for(var i=0;i<this.headerCells_.length;i++){if(!this.tableColumns_[i].cmp){this.headerCells_[i].sideContent='';continue;}
 if(i!==this.sortColumnIndex_){this.headerCells_[i].sideContent=UNSORTED_ARROW;continue;}
 this.headerCells_[i].sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;}},sortRows_:function(rows){rows.sort(function(rowA,rowB){if(this.sortDescending_)
-return this.tableColumns_[this.sortColumnIndex_].cmp(rowB.userRow,rowA.userRow);return this.tableColumns_[this.sortColumnIndex_].cmp(rowA.userRow,rowB.userRow);}.bind(this));for(var i=0;i<rows.length;i++){if(rows[i].isExpanded)
+return this.tableColumns_[this.sortColumnIndex_].cmp(rowB.userRow,rowA.userRow);return this.tableColumns_[this.sortColumnIndex_].cmp(rowA.userRow,rowB.userRow);}.bind(this));for(var i=0;i<rows.length;i++){if(this.getExpandedForUserRow_(rows[i]))
 this.sortRows_(rows[i][this.subRowsPropertyName_]);}},generateHeaderColumns_:function(){this.headerCells_=[];this.$.head.textContent='';if(!this.showHeader_)
 return;var tr=this.appendNewElement_(this.$.head,'tr');for(var i=0;i<this.tableColumns_.length;i++){var td=this.appendNewElement_(tr,'td');var headerCell=document.createElement('tr-ui-b-table-header-cell');if(this.showHeader)
 headerCell.cellTitle=this.tableColumns_[i].title;else
@@ -5171,8 +5654,8 @@
 for(var i=0;i<userRows.length;i++){var userRow=userRows[i];var rowInfo=this.getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo);var htmlNode=this.getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation);if(lastAddedRow===undefined){tableSection.insertBefore(htmlNode,tableSection.firstChild);}else{var nextSiblingOfLastAdded=lastAddedRow.nextSibling;tableSection.insertBefore(htmlNode,nextSiblingOfLastAdded);}
 this.updateTabIndexForTableRowNode_(htmlNode);lastAddedRow=htmlNode;if(!rowInfo.isExpanded)
 continue;lastAddedRow=this.generateTableRowNodes_(tableSection,userRow[this.subRowsPropertyName_],rowInfoMap,indentation+1,lastAddedRow,rowInfo);}
-return lastAddedRow;},getOrCreateRowInfoFor_:function(rowInfoMap,userRow,parentRowInfo){if(rowInfoMap.has(userRow))
-return rowInfoMap.get(userRow);var rowInfo={userRow:userRow,htmlNode:undefined,isExpanded:userRow.isExpanded||false,parentRowInfo:parentRowInfo};rowInfoMap.set(userRow,rowInfo);return rowInfo;},customizeTableRow_:function(userRow,trElement){if(!this.customizeTableRowCallback_)
+return lastAddedRow;},getOrCreateRowInfoFor_:function(rowInfoMap,userRow,parentRowInfo){var rowInfo=undefined;if(rowInfoMap.has(userRow)){rowInfo=rowInfoMap.get(userRow);}else{rowInfo={userRow:userRow,htmlNode:undefined,parentRowInfo:parentRowInfo};rowInfoMap.set(userRow,rowInfo);}
+rowInfo.isExpanded=this.getExpandedForUserRow_(userRow);return rowInfo;},customizeTableRow_:function(userRow,trElement){if(!this.customizeTableRowCallback_)
 return;this.customizeTableRowCallback_(userRow,trElement);},getHTMLNodeForRowInfo_:function(tableSection,rowInfo,rowInfoMap,indentation){if(rowInfo.htmlNode){this.customizeTableRow_(rowInfo.userRow,rowInfo.htmlNode);return rowInfo.htmlNode;}
 var INDENT_SPACE=indentation*16;var INDENT_SPACE_NO_BUTTON=indentation*16+BASIC_INDENTATION;var trElement=this.ownerDocument.createElement('tr');rowInfo.htmlNode=trElement;rowInfo.indentation=indentation;trElement.rowInfo=rowInfo;this.customizeTableRow_(rowInfo.userRow,trElement);for(var i=0;i<this.tableColumns_.length;){var td=this.appendNewElement_(trElement,'td');td.columnIndex=i;var column=this.tableColumns_[i];var value=column.value(rowInfo.userRow);var colSpan=column.colSpan?column.colSpan:1;td.style.colSpan=colSpan;if(column.textAlign){td.style.textAlign=column.textAlign;}
 if(this.doesColumnIndexSupportSelection(i))
@@ -5180,15 +5663,15 @@
 expandButton.classList.add('button-expanded');}else{td.style.paddingLeft=INDENT_SPACE_NO_BUTTON+'px';}}
 if(value!==undefined)
 td.appendChild(tr.ui.b.asHTMLOrTextNode(value,this.ownerDocument));i+=colSpan;}
-var needsClickListener=false;if(this.columnsWithExpandButtons_.length)
-needsClickListener=true;else if(tableSection==this.$.body)
-needsClickListener=true;if(needsClickListener){trElement.addEventListener('click',function(e){e.stopPropagation();if(e.target.tagName=='EXPAND-BUTTON'){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);return;}
+var isSelectable=tableSection===this.$.body;var isExpandable=rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length;if(isSelectable||isExpandable){trElement.addEventListener('click',function(e){e.stopPropagation();if(e.target.tagName=='EXPAND-BUTTON'){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);return;}
 function getTD(cur){if(cur===trElement)
 throw new Error('woah');if(cur.parentElement===trElement)
 return cur;return getTD(cur.parentElement);}
-if(this.selectionMode_!==SelectionMode.NONE){var isAlreadySelected=false;var tdThatWasClicked=getTD(e.target);switch(this.selectionMode_){case SelectionMode.ROW:isAlreadySelected=this.selectedTableRowInfo_===rowInfo;break;case SelectionMode.CELL:isAlreadySelected=this.selectedTableRowInfo_===rowInfo;isAlreadySelected&=(this.selectedColumnIndex_===tdThatWasClicked.columnIndex);break;default:throw new Error('Invalid selection mode '+
+if(isSelectable&&this.selectionMode_!==SelectionMode.NONE){var shouldSelect=false;var columnIndex=getTD(e.target).columnIndex;switch(this.selectionMode_){case SelectionMode.ROW:shouldSelect=this.selectedTableRowInfo_!==rowInfo;break;case SelectionMode.CELL:if(this.doesColumnIndexSupportSelection(columnIndex)){shouldSelect=this.selectedTableRowInfo_!==rowInfo||this.selectedColumnIndex_!==columnIndex;}
+break;default:throw new Error('Invalid selection mode '+
 this.selectionMode_);}
-if(isAlreadySelected){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}else{this.didTableRowInfoGetClicked_(rowInfo,tdThatWasClicked.columnIndex);}}else{if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}}.bind(this));}
+if(shouldSelect){this.didTableRowInfoGetClicked_(rowInfo,columnIndex);return;}}
+if(isExpandable){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}.bind(this));}
 return rowInfo.htmlNode;},removeSubNodes_:function(tableSection,rowInfo,rowInfoMap){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
 return;for(var i=0;i<rowInfo.userRow[this.subRowsPropertyName_].length;i++){var subRow=rowInfo.userRow[this.subRowsPropertyName_][i];var subRowInfo=rowInfoMap.get(subRow);if(!subRowInfo)
 continue;var subNode=subRowInfo.htmlNode;if(subNode&&subNode.parentNode===tableSection){tableSection.removeChild(subNode);this.removeSubNodes_(tableSection,subRowInfo,rowInfoMap);}}},scheduleRebuildHeaders_:function(){this.headerDirty_=true;this.scheduleRebuild_();},scheduleRebuildBody_:function(){this.bodyDirty_=true;this.scheduleRebuild_();},scheduleRebuildFooter_:function(){this.footerDirty_=true;this.scheduleRebuild_();},scheduleRebuild_:function(){if(this.rebuildPending_)
@@ -5198,7 +5681,13 @@
 if(wasBodyOrHeaderDirty)
 this.applySizes_();if(this.footerDirty_){this.$.foot.textContent='';this.generateTableRowNodes_(this.$.foot,this.tableFooterRows_,this.tableFooterRowsInfo_,0,undefined,undefined);if(this.tableFooterRowsInfo_.length){this.$.body.classList.add('has-footer');}else{this.$.body.classList.remove('has-footer');}
 this.footerDirty_=false;}},appendNewElement_:function(parent,tagName){var element=parent.ownerDocument.createElement(tagName);parent.appendChild(element);return element;},getExpandedForTableRow:function(userRow){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
-throw new Error('Row has not been seen, must expand its parents');return rowInfo.isExpanded;},setExpandedForTableRow:function(userRow,expanded){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
+throw new Error('Row has not been seen, must expand its parents');return rowInfo.isExpanded;},getExpandedForUserRow_:function(userRow){if(userRow[this.subRowsPropertyName_]===undefined)
+return false;if(userRow[this.subRowsPropertyName_].length===0)
+return false;if(userRow.isExpanded)
+return true;if(userRow.isExpanded===false)
+return false;if(this.defaultExpansionStateCallback_===undefined)
+return false;var parentUserRow=undefined;var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo&&rowInfo.parentRowInfo)
+parentUserRow=rowInfo.parentRowInfo.userRow;return this.defaultExpansionStateCallback_(userRow,parentUserRow);},setExpandedForTableRow:function(userRow,expanded){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
 throw new Error('Row has not been seen, must expand its parents');return this.setExpandedForUserRow_(this.$.body,this.tableRowsInfo_,userRow,expanded);},setExpandedForUserRow_:function(tableSection,rowInfoMap,userRow,expanded){this.rebuildIfNeeded_();var rowInfo=rowInfoMap.get(userRow);if(rowInfo===undefined)
 throw new Error('Row has not been seen, must expand its parents');rowInfo.isExpanded=!!expanded;if(rowInfo.htmlNode===undefined)
 return;if(rowInfo.htmlNode.parentElement!==tableSection)
@@ -5218,9 +5707,9 @@
 this.removeSelectedState_();var curRowInfo=this.selectedTableRowInfo_;while(curRowInfo&&!isVisible(curRowInfo))
 curRowInfo=curRowInfo.parentRowInfo;this.selectedTableRowInfo_=curRowInfo;if(this.selectedTableRowInfo_)
 this.updateSelectedState_();},didTableRowInfoGetClicked_:function(rowInfo,columnIndex){switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.CELL:if(!this.doesColumnIndexSupportSelection(columnIndex))
-return;case SelectionMode.ROW:if(this.selectedTableRowInfo_!==rowInfo)
-this.selectedTableRow=rowInfo.userRow;if(this.selectedColumnIndex!==columnIndex)
-this.selectedColumnIndex=columnIndex;}},get selectedTableRow(){if(!this.selectedTableRowInfo_)
+return;if(this.selectedColumnIndex!==columnIndex)
+this.selectedColumnIndex=columnIndex;case SelectionMode.ROW:if(this.selectedTableRowInfo_!==rowInfo)
+this.selectedTableRow=rowInfo.userRow;}},get selectedTableRow(){if(!this.selectedTableRowInfo_)
 return undefined;return this.selectedTableRowInfo_.userRow;},set selectedTableRow(userRow){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE)
 throw new Error('Selection is off.');var rowInfo;if(userRow===undefined){rowInfo=undefined;}else{rowInfo=this.tableRowsInfo_.get(userRow);if(!rowInfo)
 throw new Error('Row has not been seen, must expand its parents.');}
@@ -5250,7 +5739,7 @@
 throw new Error('Selection is not supported on this column');var e=this.prepareToChangeSelection_();this.selectedColumnIndex_=selectedColumnIndex;if(this.selectedColumnIndex_===undefined)
 this.selectedTableRowInfo_=undefined;this.updateSelectedState_();this.dispatchEvent(e);},onKeyDown_:function(e){if(this.selectionMode_===SelectionMode.NONE)
 return;if(this.selectedTableRowInfo_===undefined)
-return;var code_to_command_names={37:'ARROW_LEFT',38:'ARROW_UP',39:'ARROW_RIGHT',40:'ARROW_DOWN'};var cmdName=code_to_command_names[e.keyCode];if(cmdName===undefined)
+return;var code_to_command_names={13:'ENTER',37:'ARROW_LEFT',38:'ARROW_UP',39:'ARROW_RIGHT',40:'ARROW_DOWN'};var cmdName=code_to_command_names[e.keyCode];if(cmdName===undefined)
 return;e.stopPropagation();e.preventDefault();this.performKeyCommand_(cmdName);},performKeyCommand_:function(cmdName){this.rebuildIfNeeded_();var rowInfo=this.selectedTableRowInfo_;var htmlNode=rowInfo.htmlNode;if(cmdName==='ARROW_UP'){var prev=htmlNode.previousElementSibling;if(prev){tr.ui.b.scrollIntoViewIfNeeded(prev);this.selectedTableRow=prev.rowInfo.userRow;this.focusSelected_();return;}
 return;}
 if(cmdName==='ARROW_DOWN'){var next=htmlNode.nextElementSibling;if(next){tr.ui.b.scrollIntoViewIfNeeded(next);this.selectedTableRow=next.rowInfo.userRow;this.focusSelected_();return;}
@@ -5266,36 +5755,48 @@
 return;case SelectionMode.CELL:var newIndex=this.selectedColumnIndex_-1;if(newIndex<0)
 return;if(!this.doesColumnIndexSupportSelection(newIndex))
 return;this.selectedColumnIndex=newIndex;this.focusSelected_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
+if(cmdName==='ENTER'){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
+return;if(rowInfo.userRow[this.subRowsPropertyName_].length===0)
+return;this.setExpandedForTableRow(rowInfo.userRow,!rowInfo.isExpanded);this.focusSelected_();return;}
 throw new Error('Unrecognized command '+cmdName);},focusSelected_:function(){if(!this.selectedTableRowInfo_)
 return;var node=this.getSelectableNodeGivenTableRowNode_(this.selectedTableRowInfo_.htmlNode);node.focus();},dispatchSortingChangedEvent_:function(){var e=new tr.b.Event('sort-column-changed');e.sortColumnIndex=this.sortColumnIndex_;e.sortDescending=this.sortDescending_;this.dispatchEvent(e);}});})();'use strict';Polymer('tr-ui-b-table-header-cell',{created:function(){this.tapCallback_=undefined;this.cellTitle_='';},set cellTitle(value){this.cellTitle_=value;var titleNode=tr.ui.b.asHTMLOrTextNode(this.cellTitle_,this.ownerDocument);this.$.title.innerText='';this.$.title.appendChild(titleNode);},get cellTitle(){return this.cellTitle_;},clearSideContent:function(){this.$.side.textContent='';},set sideContent(content){this.$.side.textContent=content;},get sideContent(){return this.$.side.textContent;},set tapCallback(callback){this.style.cursor='pointer';this.tapCallback_=callback;},get tapCallback(){return this.tapCallback_;},onTap_:function(){if(this.tapCallback_)
-this.tapCallback_();}});'use strict';tr.exportTo('tr.ui.b',function(){Object.observe(Polymer.elements,clearPolymerElementCaches);var elementsByName=undefined;var elementsThatExtend=undefined;var elementSubclasses=undefined;function clearPolymerElementCaches(){elementsByName={};elementsThatExtend=undefined;elementSubclasses={};}
-function buildElementMapsIfNeeded(){if(elementsThatExtend!==undefined&&elementsByName!==undefined)
-return;elementsByName={};elementsThatExtend={};Polymer.elements.forEach(function(element){if(elementsByName[element.name])
-throw new Error('Something is strange: dupe polymer element names');elementsByName[element.name]=element;if(element.extends){if(elementsThatExtend[element.extends]===undefined)
-elementsThatExtend[element.extends]=[];elementsThatExtend[element.extends].push(element.name);}});}
-function getPolymerElementNamed(tagName){buildElementMapsIfNeeded();return elementsByName[tagName];}
+this.tapCallback_();}});'use strict';tr.exportTo('tr.b',function(){function _iterateElementDeeplyImpl(element,cb,thisArg,includeElement){if(includeElement){if(cb.call(thisArg,element))
+return true;}
+if(element.shadowRoot){if(_iterateElementDeeplyImpl(element.shadowRoot,cb,thisArg,false))
+return true;}
+for(var i=0;i<element.children.length;i++){if(_iterateElementDeeplyImpl(element.children[i],cb,thisArg,true))
+return true;}}
+function iterateElementDeeply(element,cb,thisArg){_iterateElementDeeplyImpl(element,cb,thisArg,false);}
+function findDeepElementMatchingPredicate(element,predicate){var foundElement=undefined;function matches(element){var match=predicate(element);if(!match)
+return false;foundElement=element;return true;}
+iterateElementDeeply(element,matches);return foundElement;}
+function findDeepElementsMatchingPredicate(element,predicate){var foundElements=[];function matches(element){var match=predicate(element);if(match){foundElements.push(element);}
+return false;}
+iterateElementDeeply(element,matches);return foundElements;}
+function findDeepElementMatching(element,selector){return findDeepElementMatchingPredicate(element,function(element){return element.matches(selector);});}
+function findDeepElementsMatching(element,selector){return findDeepElementsMatchingPredicate(element,function(element){return element.matches(selector);});}
+function findDeepElementWithTextContent(element,re){return findDeepElementMatchingPredicate(element,function(element){if(element.children.length!==0)
+return false;return re.test(element.textContent);});}
+return{iterateElementDeeply:iterateElementDeeply,findDeepElementMatching:findDeepElementMatching,findDeepElementsMatching:findDeepElementsMatching,findDeepElementMatchingPredicate:findDeepElementMatchingPredicate,findDeepElementsMatchingPredicate:findDeepElementsMatchingPredicate,findDeepElementWithTextContent:findDeepElementWithTextContent};});'use strict';tr.exportTo('tr.ui.b',function(){function getPolymerElementNamed(tagName){for(var i=0;i<Polymer.elements.length;i++){if(Polymer.elements[i].name===tagName)
+return Polymer.elements[i];}}
 function getPolymerElementsThatSubclass(tagName){if(Polymer.waitingFor().length){throw new Error('There are unresolved polymer elements. '+'Wait until Polymer.whenReady');}
-buildElementMapsIfNeeded();var element=getPolymerElementNamed(tagName);if(!element)
-throw new Error(tagName+' is not a polymer element');if(elementSubclasses===undefined)
-elementSubclasses={};if(elementSubclasses[tagName]===undefined){var immediateSubElements=elementsThatExtend[element.name];var allSubElements=[];if(immediateSubElements!==undefined&&immediateSubElements.length){immediateSubElements.forEach(function(subElement){allSubElements.push(subElement);allSubElements.push.apply(allSubElements,getPolymerElementsThatSubclass(subElement));});}
-elementSubclasses[tagName]=allSubElements;}
-return elementSubclasses[tagName];}
-return{getPolymerElementNamed:getPolymerElementNamed,getPolymerElementsThatSubclass:getPolymerElementsThatSubclass};});'use strict';tr.exportTo('tr.ui.units',function(){function createScalarSpan(value,opt_config){if(value===undefined)
-return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-ui-u-scalar-span');span.value=value;return span;}
-tr.b.u.Units.addEventListener('display-mode-changed',function(e){var subclassNames=tr.ui.b.getPolymerElementsThatSubclass('tr-ui-u-scalar-span');var isSubclass={};subclassNames.forEach(function(n){isSubclass[n.toUpperCase()]=true;});var m=tr.b.findDeepElementsMatchingPredicate(document.body,function(el){return isSubclass[el.tagName];});m.forEach(function(el){el.updateContent_();});});return{createScalarSpan:createScalarSpan};});'use strict';Polymer('tr-ui-u-scalar-span',{ready:function(){this.value_=undefined;this.unit_=undefined;this.warning_=undefined;this.percentage_=undefined;this.isDelta_=false;},set contentTextDecoration(deco){this.$.content.style.textDecoration=deco;},get value(){return this.value_;},set value(value){if(value instanceof tr.b.u.Scalar){this.value_=value.value;this.unit_=value.unit;}else{this.value_=value;}
+var baseElement;var elementNamesThatExtend={};Polymer.elements.forEach(function(element){if(element.name===tagName)
+baseElement=element;if(element.extends){if(elementNamesThatExtend[element.extends]===undefined)
+elementNamesThatExtend[element.extends]=[];elementNamesThatExtend[element.extends].push(element.name);}});if(!baseElement)
+throw new Error(tagName+' is not a polymer element');var allFoundSubElementNames=[baseElement.name];for(var i=0;i<allFoundSubElementNames.length;i++){var elementName=allFoundSubElementNames[i];allFoundSubElementNames.push.apply(allFoundSubElementNames,elementNamesThatExtend[elementName]);}
+allFoundSubElementNames.shift();return allFoundSubElementNames;}
+return{getPolymerElementNamed:getPolymerElementNamed,getPolymerElementsThatSubclass:getPolymerElementsThatSubclass};});'use strict';tr.exportTo('tr.v.ui',function(){function createScalarSpan(value,opt_config){if(value===undefined)
+return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-v-ui-scalar-span');var numericValue;if(value instanceof tr.v.ScalarNumeric){span.value=value;numericValue=value.value;}else{var unit=config.unit;if(unit===undefined){throw new Error('Unit must be provided in config when value is a number');}
+span.setValueAndUnit(value,unit);numericValue=value;}
+if(config.total)
+span.percentage=numericValue/config.total;if(config.rightAlign)
+span.rightAlign=true;return span;}
+tr.v.Unit.addEventListener('display-mode-changed',function(e){var scalarSpanTagName='tr-v-ui-scalar-span';var subclassNames=tr.ui.b.getPolymerElementsThatSubclass(scalarSpanTagName);subclassNames.push(scalarSpanTagName);var isSubclass={};subclassNames.forEach(function(n){isSubclass[n.toUpperCase()]=true;});var m=tr.b.findDeepElementsMatchingPredicate(document.body,function(el){return isSubclass[el.tagName];});m.forEach(function(el){el.updateContent_();});});return{createScalarSpan:createScalarSpan};});'use strict';Polymer('tr-v-ui-scalar-span',{ready:function(){this.value_=undefined;this.unit_=undefined;this.warning_=undefined;this.percentage_=undefined;},set contentTextDecoration(deco){this.$.content.style.textDecoration=deco;},get value(){return this.value_;},set value(value){if(value instanceof tr.v.ScalarNumeric){this.value_=value.value;this.unit_=value.unit;}else{this.value_=value;}
 this.updateContent_();},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContent_();},setValueAndUnit:function(value,unit){this.value_=value;this.unit_=unit;this.updateContent_();},get percentage(){return this.percentage_;},set percentage(percentage){this.percentage_=percentage;this.updateSparkline_();},get rightAlign(){return this.$.content.classList.contains('right-align');},set rightAlign(rightAlign){if(rightAlign)
 this.$.content.classList.add('right-align');else
-this.$.content.classList.remove('right-align');},get isDelta(){return this.isDelta_;},set isDelta(isDelta){this.isDelta_=isDelta;this.updateContent_();},updateSparkline_:function(){if(this.percentage_===undefined){this.$.sparkline.style.display='none';this.$.sparkline.style.width='0';}else{this.$.sparkline.style.display='block';this.$.sparkline.style.width=(this.percentage_*100)+'%';}},updateContent_:function(){if(this.unit_===undefined){this.$.content.textContent='';return;}
-var content=this.unit_.format(this.value);if(this.isDelta_){if(this.value>0){content='+'+content;}else if(this.value===0){var PLUS_MINUS_SIGN=String.fromCharCode(177);content=PLUS_MINUS_SIGN+content;}}
-this.$.content.textContent=content;},get warning(){return this.warning_;},set warning(warning){this.warning_=warning;var warningEl=this.$.warning;if(this.warning_){warningEl.title=warning;warningEl.style.display='';}else{warningEl.title='';warningEl.style.display='none';}}});'use strict';tr.exportTo('tr.ui.units',function(){function createTimeDurationSpan(duration,opt_config){if(duration===undefined)
-return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-ui-u-time-duration-span');span.setValueAndUnit(duration,tr.b.u.Units.timeDurationInMs);if(config.total)
-span.percentage=duration/config.total;span.duration=duration;if(config.rightAlign)
-span.rightAlign=true;return span;}
-return{createTimeDurationSpan:createTimeDurationSpan};});'use strict';Polymer('tr-ui-u-time-duration-span',{get duration(){return this.value;},set duration(duration){if(duration instanceof tr.b.u.TimeDuration){this.value=duration;return;}
-this.setValueAndUnit(duration,tr.b.u.Units.timeDurationInMs);}});'use strict';tr.exportTo('tr.ui.units',function(){function createTimeStampSpan(timestamp,opt_config){if(timestamp===undefined)
-return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-ui-u-time-stamp-span');span.timestamp=timestamp;return span;}
-return{createTimeStampSpan:createTimeStampSpan};});'use strict';Polymer('tr-ui-u-time-stamp-span',{get timestamp(){return this.value;},set timestamp(timestamp){if(timestamp instanceof tr.b.u.TimeStamp){this.value=timestamp;return;}
-this.setValueAndUnit(timestamp,tr.b.u.Units.timeStampInMs);}});'use strict';function isTable(object){if(!(object instanceof Array)||(object.length<2))return false;for(var colName in object[0]){if(typeof colName!=='string')return false;}
+this.$.content.classList.remove('right-align');},updateSparkline_:function(){if(this.percentage_===undefined){this.$.sparkline.style.display='none';this.$.sparkline.style.width='0';}else{this.$.sparkline.style.display='block';this.$.sparkline.style.width=(this.percentage_*100)+'%';}},updateContent_:function(){if(this.unit_===undefined){this.$.content.textContent='';this.$.content.style.color='';return;}
+this.$.content.textContent=this.unit_.format(this.value);var BIGGER_IS_BETTER=tr.v.ImprovementDirection.BIGGER_IS_BETTER;var SMALLER_IS_BETTER=tr.v.ImprovementDirection.SMALLER_IS_BETTER;var color='';if(this.unit_.isDelta){var improvementDirection=this.unit_.improvementDirection;if(this.value>0){switch(improvementDirection){case BIGGER_IS_BETTER:color='green';break;case SMALLER_IS_BETTER:color='red';break;}}else if(this.value<0){switch(improvementDirection){case BIGGER_IS_BETTER:color='red';break;case SMALLER_IS_BETTER:color='green';break;}}}
+this.$.content.style.color=color;},get warning(){return this.warning_;},set warning(warning){this.warning_=warning;var warningEl=this.$.warning;if(this.warning_){warningEl.title=warning;warningEl.style.display='';}else{warningEl.title='';warningEl.style.display='none';}}});'use strict';function isTable(object){if(!(object instanceof Array)||(object.length<2))return false;for(var colName in object[0]){if(typeof colName!=='string')return false;}
 for(var i=0;i<object.length;++i){if(!(object[i]instanceof Object))return false;for(var colName in object[i]){if(i&&(object[0][colName]===undefined))return false;var cellType=typeof object[i][colName];if(cellType!=='string'&&cellType!='number')return false;}
 if(i){for(var colName in object[0]){if(object[i][colName]===undefined)return false;}}}
 return true;}
@@ -5309,448 +5810,14 @@
 if(object instanceof tr.model.ObjectSnapshot){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
 if(object instanceof tr.model.ObjectInstance){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
 if(object instanceof tr.b.Rect){this.appendSimpleText_(label,indent,object.toString(),suffix);return;}
-if(object instanceof tr.b.u.Scalar){var el=this.ownerDocument.createElement('tr-ui-u-scalar-span');el.value=object;this.appendElementWithLabel_(label,indent,el,suffix);return;}
+if(object instanceof tr.v.ScalarNumeric){var el=this.ownerDocument.createElement('tr-v-ui-scalar-span');el.value=object;this.appendElementWithLabel_(label,indent,el,suffix);return;}
 if(object instanceof Array){this.appendElementsForArray_(label,object,indent,depth,maxDepth,suffix);return;}
 this.appendElementsForObject_(label,object,indent,depth,maxDepth,suffix);},appendElementsForArray_:function(label,object,indent,depth,maxDepth,suffix){if(object.length==0){this.appendSimpleText_(label,indent,'[]',suffix);return;}
 if(isTable(object)){var table=document.createElement('tr-ui-b-table');var columns=[];tr.b.iterItems(object[0],function(colName){columns.push({title:colName,value:function(row){return row[colName];}});});table.tableColumns=columns;table.tableRows=object;this.appendElementWithLabel_(label,indent,table,suffix);table.rebuild();return;}
 this.appendElementsForType_(label+'[',object[0],indent,depth+1,maxDepth,object.length>1?',':']'+suffix);for(var i=1;i<object.length;i++){this.appendElementsForType_('',object[i],indent+label.length+1,depth+1,maxDepth,i<object.length-1?',':']'+suffix);}
 return;},appendElementsForObject_:function(label,object,indent,depth,maxDepth,suffix){var keys=tr.b.dictionaryKeys(object);if(keys.length==0){this.appendSimpleText_(label,indent,'{}',suffix);return;}
 this.appendElementsForType_(label+'{'+keys[0]+': ',object[keys[0]],indent,depth,maxDepth,keys.length>1?',':'}'+suffix);for(var i=1;i<keys.length;i++){this.appendElementsForType_(keys[i]+': ',object[keys[i]],indent+label.length+1,depth+1,maxDepth,i<keys.length-1?',':'}'+suffix);}},appendElementWithLabel_:function(label,indent,dataElement,suffix){var row=document.createElement('div');var indentSpan=document.createElement('span');indentSpan.style.whiteSpace='pre';for(var i=0;i<indent;i++)
-indentSpan.textContent+=' ';row.appendChild(indentSpan);var labelSpan=document.createElement('span');labelSpan.textContent=label;row.appendChild(labelSpan);row.appendChild(dataElement);var suffixSpan=document.createElement('span');suffixSpan.textContent=suffix;row.appendChild(suffixSpan);row.dataElement=dataElement;this.$.content.appendChild(row);},appendSimpleText_:function(label,indent,text,suffix){var el=this.ownerDocument.createElement('span');el.textContent=text;this.appendElementWithLabel_(label,indent,el,suffix);return el;}});'use strict';Polymer('tr-ui-a-generic-object-view-with-label',{ready:function(){this.labelEl_=document.createElement('div');this.genericObjectView_=document.createElement('tr-ui-a-generic-object-view');this.shadowRoot.appendChild(this.labelEl_);this.shadowRoot.appendChild(this.genericObjectView_);},get label(){return this.labelEl_.textContent;},set label(label){this.labelEl_.textContent=label;},get object(){return this.genericObjectView_.object;},set object(object){this.genericObjectView_.object=object;}});'use strict';Polymer('tr-ui-a-stack-frame',{ready:function(){this.stackFrame_=undefined;this.$.table.tableColumns=[];this.$.table.showHeader=true;},get stackFrame(){return this.stackFrame_;},set stackFrame(stackFrame){var table=this.$.table;this.stackFrame_=stackFrame;if(stackFrame===undefined){table.tableColumns=[];table.tableRows=[];table.rebuild();return;}
-var hasName=false;var hasTitle=false;table.tableRows=stackFrame.stackTrace;table.tableRows.forEach(function(row){hasName|=row.name!==undefined;hasTitle|=row.title!==undefined;});var cols=[];if(hasName){cols.push({title:'Name',value:function(row){return row.name;}});}
-if(hasTitle){cols.push({title:'Title',value:function(row){return row.title;}});}
-table.tableColumns=cols;table.rebuild();},tableForTesting:function(){return this.$.table;}});'use strict';Polymer('tr-ui-a-single-event-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');this.setSelectionWithoutErrorChecks(selection);},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},getEventRows_:function(event){var rows=[];if(event.error)
-rows.push({name:'Error',value:event.error});if(event.title)
-rows.push({name:'Title',value:event.title});if(event.category)
-rows.push({name:'Category',value:event.category});if(event.name)
-rows.push({name:'Name',value:event.name});var startEl=document.createElement('tr-ui-u-time-stamp-span');startEl.timestamp=event.start;rows.push({name:'Start',value:startEl});if(event.duration){var wallDurationEl=document.createElement('tr-ui-u-time-duration-span');wallDurationEl.duration=event.duration;rows.push({name:'Wall Duration',value:wallDurationEl});}
-if(event.cpuDuration){var cpuDurationEl=document.createElement('tr-ui-u-time-duration-span');cpuDurationEl.duration=event.cpuDuration;rows.push({name:'CPU Duration',value:cpuDurationEl});}
-if(event.subSlices!==undefined&&event.subSlices.length!==0){if(event.selfTime){var selfTimeEl=document.createElement('tr-ui-u-time-duration-span');selfTimeEl.duration=event.selfTime;rows.push({name:'Self Time',value:selfTimeEl});}
-if(event.cpuSelfTime){var cpuSelfTimeEl=document.createElement('tr-ui-u-time-duration-span');cpuSelfTimeEl.duration=event.cpuSelfTime;if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
-rows.push({name:'CPU Self Time',value:cpuSelfTimeEl});}}
-if(event.durationInUserTime){var durationInUserTimeEl=document.createElement('tr-ui-u-time-duration-span');durationInUserTimeEl.duration=event.durationInUserTime;rows.push({name:'Duration (U)',value:durationInUserTimeEl});}
-function createStackFrameEl(sf){var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sf;return sfEl;}
-if(event.startStackFrame&&event.endStackFrame){if(event.startStackFrame===event.endStackFrame){rows.push({name:'Start+End Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else{rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}}else if(event.startStackFrame){rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else if(event.endStackFrame){rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}
-if(event.info){var descriptionEl=tr.ui.b.createDiv({textContent:event.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(event.info.docLinks){event.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}}
-if(event.associatedAlerts.length){var alertSubRows=[];event.associatedAlerts.forEach(function(alert){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(alert);},alert.info.description);alertSubRows.push({name:alert.title,value:linkEl});});rows.push({name:'Alerts',value:'',isExpanded:true,subRows:alertSubRows});}
-return rows;},addArgsToRows_:function(rows,args){var n=0;for(var argName in args){n+=1;}
-if(n>0){var subRows=[];for(var argName in args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=args[argName];subRows.push({name:argName,value:argView});}
-rows.push({name:'Args',value:'',isExpanded:true,subRows:subRows});}
-return rows;},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
-var event=this.currentSelection_[0];var rows=this.getEventRows_(event);if(event.argsStripped)
-rows.push({name:'Args',value:'Stripped'});else
-this.addArgsToRows_(rows,event.args);this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){var FLOW_IN=0x1;var FLOW_OUT=0x2;var FLOW_IN_OUT=FLOW_IN|FLOW_OUT;function FlowClassifier(){this.numEvents_=0;this.eventsByGUID_={};}
-FlowClassifier.prototype={getFS_:function(event){var fs=this.eventsByGUID_[event.guid];if(fs===undefined){this.numEvents_++;fs={state:0,event:event};this.eventsByGUID_[event.guid]=fs;}
-return fs;},addInFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_IN;return event;},addOutFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_OUT;return event;},hasEvents:function(){return this.numEvents_>0;},get inFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN)
-selection.push(fs.event);}
-return selection;},get outFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_OUT)
-selection.push(fs.event);}
-return selection;},get internalFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN_OUT)
-selection.push(fs.event);}
-return selection;}};return{FlowClassifier:FlowClassifier};});'use strict';Polymer('tr-ui-a-related-events',{ready:function(){this.eventGroups_=[];this.cancelFunctions_=[];this.$.table.tableColumns=[{title:'Event(s)',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip)
-typeEl.title=row.tooltip;return typeEl;},width:'150px'},{title:'Link',width:'100%',value:function(row){var linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name)
-linkEl.setSelectionAndContent(row.selection,row.name);else
-linkEl.selection=row.selection;return linkEl;}}];},hasRelatedEvents:function(){return(this.eventGroups_&&this.eventGroups_.length>0);},setRelatedEvents:function(eventSet){this.cancelAllTasks_();this.eventGroups_=[];this.addConnectedFlows_(eventSet);this.addConnectedEvents_(eventSet);this.addOverlappingSamples_(eventSet);this.updateContents_();},addConnectedFlows_:function(eventSet){var classifier=new tr.ui.analysis.FlowClassifier();eventSet.forEach(function(slice){if(slice.inFlowEvents){slice.inFlowEvents.forEach(function(flow){classifier.addInFlow(flow);});}
-if(slice.outFlowEvents){slice.outFlowEvents.forEach(function(flow){classifier.addOutFlow(flow);});}});if(!classifier.hasEvents())
-return;var addToEventGroups=function(type,flowEvent){this.eventGroups_.push({type:type,selection:new tr.model.EventSet(flowEvent),name:flowEvent.title});};classifier.inFlowEvents.forEach(addToEventGroups.bind(this,'Incoming flow'));classifier.outFlowEvents.forEach(addToEventGroups.bind(this,'Outgoing flow'));classifier.internalFlowEvents.forEach(addToEventGroups.bind(this,'Internal flow'));},cancelAllTasks_:function(){this.cancelFunctions_.forEach(function(cancelFunction){cancelFunction();});this.cancelFunctions_=[];},addConnectedEvents_:function(eventSet){this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Preceding events','Add all events that have led to the selected one(s), connected by '+'flow arrows or by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addAncestors_(event,events);if(event.startSlice)
-events.push(event.startSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Following events','Add all events that have been caused by the selected one(s), '+'connected by flow arrows or by call stack.',eventSet,function(event,events){this.addOutFlowEvents_(event,events);this.addDescendents_(event,events);if(event.endSlice)
-events.push(event.endSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('All connected events','Add all events connected to the selected one(s) by flow arrows or '+'by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addOutFlowEvents_(event,events);this.addAncestors_(event,events);this.addDescendents_(event,events);if(event.startSlice)
-events.push(event.startSlice);if(event.endSlice)
-events.push(event.endSlice);}.bind(this)));},createEventsLinkIfNeeded_:function(title,tooltip,events,addFunction){events=new tr.model.EventSet(events);var lengthBefore=events.length;var task;var isCanceled=false;function addEventsUntilTimeout(startingIndex){if(isCanceled)
-return;var startingTime=window.performance.now();while(startingIndex<events.length){addFunction(events[startingIndex],events);startingIndex++;if(window.performance.now()-startingTime>8){var newTask=new tr.b.Task(addEventsUntilTimeout.bind(this,startingIndex),this);task.after(newTask);task=newTask;return;}}
-if(lengthBefore===events.length)
-return;this.eventGroups_.push({type:title,tooltip:tooltip,selection:events});this.updateContents_();};function cancelTask(){isCanceled=true;}
-task=new tr.b.Task(addEventsUntilTimeout.bind(this,0),this);tr.b.Task.RunWhenIdle(task);return cancelTask;},addInFlowEvents_:function(event,eventSet){if(!event.inFlowEvents)
-return;event.inFlowEvents.forEach(function(e){eventSet.push(e);});},addOutFlowEvents_:function(event,eventSet){if(!event.outFlowEvents)
-return;event.outFlowEvents.forEach(function(e){eventSet.push(e);});},addAncestors_:function(event,eventSet){if(!event.iterateAllAncestors)
-return;event.iterateAllAncestors(function(e){eventSet.push(e);});},addDescendents_:function(event,eventSet){if(!event.iterateAllDescendents)
-return;event.iterateAllDescendents(function(e){eventSet.push(e);});},addOverlappingSamples_:function(eventSet){var samples=new tr.model.EventSet;eventSet.forEach(function(slice){if(!slice.parentContainer||!slice.parentContainer.samples)
-return;var candidates=slice.parentContainer.samples;var range=tr.b.Range.fromExplicitRange(slice.start,slice.start+slice.duration);var filteredSamples=range.filterArray(candidates,function(value){return value.start;});filteredSamples.forEach(function(sample){samples.push(sample);});}.bind(this));if(samples.length>0){this.eventGroups_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected slice(s).',selection:samples});}},updateContents_:function(){var table=this.$.table;if(this.eventGroups_===undefined)
-table.tableRows=[];else
-table.tableRows=this.eventGroups_.slice();table.rebuild();}});'use strict';Polymer('tr-ui-a-single-thread-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents())
-this.$.relatedEvents.style.display='';else
-this.$.relatedEvents.style.display='none';}});'use strict';Polymer('tr-ui-a-selection-summary-table',{created:function(){this.selection_=new tr.b.Range();},ready:function(){this.$.table.showHeader=false;this.$.table.tableColumns=[{title:'Name',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;var rows=[];var hasRange;if(this.selection_&&(!selection.bounds.isEmpty))
-hasRange=true;else
-hasRange=false;var timeSpanConfig={ownerDocument:this.ownerDocument};rows.push({title:'Selection start',value:hasRange?tr.ui.units.createTimeStampSpan(selection.bounds.min,timeSpanConfig):'<empty>'});rows.push({title:'Selection extent',value:hasRange?tr.ui.units.createTimeDurationSpan(selection.bounds.range,timeSpanConfig):'<empty>'});this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){function MultiEventSummary(title,events){this.title=title;this.duration_=undefined;this.selfTime_=undefined;this.events_=events;this.cpuTimesComputed_=false;this.cpuSelfTime_=undefined;this.cpuDuration_=undefined;this.maxDuration_=undefined;this.maxCpuDuration_=undefined;this.maxSelfTime_=undefined;this.maxCpuSelfTime_=undefined;this.untotallableArgs_=[];this.totalledArgs_=undefined;};MultiEventSummary.prototype={set title(title){if(title=='Totals')
-this.totalsRow=true;this.title_=title;},get title(){return this.title_;},get duration(){if(this.duration_===undefined){this.duration_=tr.b.Statistics.sum(this.events_,function(event){return event.duration;});}
-return this.duration_;},get cpuSelfTime(){this.computeCpuTimesIfNeeded_();return this.cpuSelfTime_;},get cpuDuration(){this.computeCpuTimesIfNeeded_();return this.cpuDuration_;},computeCpuTimesIfNeeded_:function(){if(this.cpuTimesComputed_)
-return;this.cpuTimesComputed_=true;var cpuSelfTime=0;var cpuDuration=0;var hasCpuData=false;for(var i=0;i<this.events_.length;i++){var event=this.events_[i];if(event.cpuDuration!==undefined){cpuDuration+=event.cpuDuration;hasCpuData=true;}
-if(event.cpuSelfTime!==undefined){cpuSelfTime+=event.cpuSelfTime;hasCpuData=true;}}
-if(hasCpuData){this.cpuDuration_=cpuDuration;this.cpuSelfTime_=cpuSelfTime;}},get selfTime(){if(this.selfTime_===undefined){this.selfTime_=0;for(var i=0;i<this.events_.length;i++){if(this.events_[i].selfTime!==undefined)
-this.selfTime_+=this.events[i].selfTime;}}
-return this.selfTime_;},get events(){return this.events_;},get numEvents(){return this.events_.length;},get numAlerts(){if(this.numAlerts_===undefined){this.numAlerts_=tr.b.Statistics.sum(this.events_,function(event){return event.associatedAlerts.length;});}
-return this.numAlerts_;},get untotallableArgs(){this.updateArgsIfNeeded_();return this.untotallableArgs_;},get totalledArgs(){this.updateArgsIfNeeded_();return this.totalledArgs_;},get maxDuration(){if(this.maxDuration_===undefined){this.maxDuration_=tr.b.Statistics.max(this.events_,function(event){return event.duration;});}
-return this.maxDuration_;},get maxCpuDuration(){if(this.maxCpuDuration_===undefined){this.maxCpuDuration_=tr.b.Statistics.max(this.events_,function(event){return event.cpuDuration;});}
-return this.maxCpuDuration_;},get maxSelfTime(){if(this.maxSelfTime_===undefined){this.maxSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.selfTime;});}
-return this.maxSelfTime_;},get maxCpuSelfTime(){if(this.maxCpuSelfTime_===undefined){this.maxCpuSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.cpuSelfTime;});}
-return this.maxCpuSelfTime_;},updateArgsIfNeeded_:function(){if(this.totalledArgs_!==undefined)
-return;var untotallableArgs={};var totalledArgs={};for(var i=0;i<this.events_.length;i++){var event=this.events_[i];for(var argName in event.args){var argVal=event.args[argName];var type=typeof argVal;if(type!=='number'){untotallableArgs[argName]=true;delete totalledArgs[argName];continue;}
-if(untotallableArgs[argName]){continue;}
-if(totalledArgs[argName]===undefined)
-totalledArgs[argName]=0;totalledArgs[argName]+=argVal;}}
-this.untotallableArgs_=tr.b.dictionaryKeys(untotallableArgs);this.totalledArgs_=totalledArgs;}};return{MultiEventSummary:MultiEventSummary};});'use strict';Polymer('tr-ui-a-multi-event-summary-table',{ready:function(){this.showTotals_=false;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;this.eventsByTitle_=undefined;},updateTableColumns_:function(rows,maxValues){var hasCpuData=false;var hasAlerts=false;rows.forEach(function(row){if(row.cpuDuration!==undefined)
-hasCpuData=true;if(row.cpuSelfTime!==undefined)
-hasCpuData=true;if(row.numAlerts)
-hasAlerts=true;});var ownerDocument=this.ownerDocument;var columns=[];columns.push({title:'Name',value:function(row){if(row.title==='Totals')
-return'Totals';var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.events);},row.title);return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.title.localeCompare(rowB.title);}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,{total:row.totalsRow?undefined:maxValues.duration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
-if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuDuration,{total:row.totalsRow?undefined:maxValues.cpuDuration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time',value:function(row){return tr.ui.units.createTimeDurationSpan(row.selfTime,{total:row.totalsRow?undefined:maxValues.selfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuSelfTime,{total:row.totalsRow?undefined:maxValues.cpuSelfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
-columns.push({title:'Occurrences',value:function(row){return row.numEvents;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numEvents-rowB.numEvents;}});var alertsColumnIndex;if(hasAlerts){columns.push({title:'Num Alerts',value:function(row){return row.numAlerts;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numAlerts-rowB.numAlerts;}});alertsColumnIndex=columns.length-1;}
-var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;if(hasAlerts){this.$.table.sortColumnIndex=alertsColumnIndex;this.$.table.sortDescending=true;}},configure:function(config){if(config.eventsByTitle===undefined)
-throw new Error('Required: eventsByTitle');if(config.showTotals!==undefined)
-this.showTotals_=config.showTotals;else
-this.showTotals_=true;if(config.eventsHaveDuration!==undefined)
-this.eventsHaveDuration_=config.eventsHaveDuration;else
-this.eventsHaveDuration_=true;if(config.eventsHaveSubRows!==undefined)
-this.eventsHaveSubRows_=config.eventsHaveSubRows;else
-this.eventsHaveSubRows_=true;this.eventsByTitle_=config.eventsByTitle;this.updateContents_();},get showTotals(){return this.showTotals_;},set showTotals(showTotals){this.showTotals_=showTotals;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get eventsByTitle(){return this.eventsByTitle_;},set eventsByTitle(eventsByTitle){this.eventsByTitle_=eventsByTitle;this.updateContents_();},get selectionBounds(){return this.selectionBounds_;},set selectionBounds(selectionBounds){this.selectionBounds_=selectionBounds;this.updateContents_();},updateContents_:function(){var eventsByTitle;if(this.eventsByTitle_!==undefined)
-eventsByTitle=this.eventsByTitle_;else
-eventsByTitle=[];var allEvents=[];var rows=[];tr.b.iterItems(eventsByTitle,function(title,eventsOfSingleTitle){allEvents.push.apply(allEvents,eventsOfSingleTitle);var row=new tr.ui.analysis.MultiEventSummary(title,eventsOfSingleTitle);rows.push(row);});this.updateTableColumns_(rows);this.$.table.tableRows=rows;var maxValues={duration:undefined,selfTime:undefined,cpuSelfTime:undefined,cpuDuration:undefined};if(this.eventsHaveDuration){for(var column in maxValues){maxValues[column]=tr.b.Statistics.max(rows,function(event){return event[column];});}}
-var footerRows=[];if(this.showTotals_){var multiEventSummary=new tr.ui.analysis.MultiEventSummary('Totals',allEvents);footerRows.push(multiEventSummary);}
-this.updateTableColumns_(rows,maxValues);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-event-details-table',{created:function(){this.selection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},ready:function(){this.initTitleTable_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;this.updateTitleTable_();if(this.selection_===undefined){this.$.table.tableRows=[];this.$.table.tableFooterRows=[];this.$.table.rebuild();return;}
-var summary=new tr.ui.analysis.MultiEventSummary('Totals',this.selection_);this.updateColumns_(summary);this.updateRows_(summary);this.$.table.rebuild();},initTitleTable_:function(){var table=this.$.titletable;table.showHeader=false;table.tableColumns=[{title:'Title',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},updateTitleTable_:function(){var title;if(this.selection_&&this.selection_.length)
-title=this.selection_[0].title;else
-title='<No selection>';var table=this.$.titletable;table.tableRows=[{title:'Title',value:title}];},updateColumns_:function(summary){var hasCpuData;if(summary.cpuDuration!==undefined)
-hasCpuData=true;if(summary.cpuSelfTime!==undefined)
-hasCpuData=true;var colWidthPercentage;if(hasCpuData)
-colWidthPercentage='20%';else
-colWidthPercentage='33.3333%';var timeSpanConfig={ownerDocument:this.ownerDocument};var columns=[];columns.push({title:'Start',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype){return row.title;}
-var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.event);});linkEl.appendChild(tr.ui.units.createTimeStampSpan(row.start,timeSpanConfig));return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.start-rowB.start;}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
-if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuDuration,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.selfTime,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuSelfTime,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
-var argKeys=tr.b.dictionaryKeys(summary.totalledArgs);argKeys.sort();var otherKeys=summary.untotallableArgs.slice(0);otherKeys.sort();argKeys.push.apply(argKeys,otherKeys);var keysWithColumns=argKeys.slice(0,4);var keysInOtherColumn=argKeys.slice(4);keysWithColumns.forEach(function(argKey){var hasTotal=summary.totalledArgs[argKey];var colDesc={title:'Arg: '+argKey,value:function(row){if(row.__proto__!==tr.ui.analysis.MultiEventSummary.prototype){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=row.args[argKey];return argView;}
-if(hasTotal)
-return row.totalledArgs[argKey];return'';},width:'<upated further down>'};if(hasTotal){colDesc.cmp=function(rowA,rowB){return rowA.args[argKey]-rowB.args[argKey];}}
-columns.push(colDesc);});if(keysInOtherColumn.length){columns.push({title:'Other Args',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype)
-return'';var argView=document.createElement('tr-ui-a-generic-object-view');var obj={};for(var i=0;i<keysInOtherColumn.length;i++)
-obj[keysInOtherColumn[i]]=row.args[keysInOtherColumn[i]];argView.object=obj;return argView;},width:'<upated further down>'});}
-var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;},updateRows_:function(summary){this.$.table.sortColumnIndex=0;function Row(event){this.event=event;}
-Row.prototype={get start(){return this.event.start;},get duration(){return this.event.duration;},get cpuDuration(){return this.event.cpuDuration;},get selfTime(){return this.event.selfTime;},get cpuSelfTime(){return this.event.cpuSelfTime;},get args(){return this.event.args;}};this.$.table.tableRows=this.selection_.map(function(event){return new Row(event);});this.$.table.footerRows=[summary];}});'use strict';Polymer('tr-ui-a-multi-event-sub-view',{created:function(){this.currentSelection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},set selection(selection){if(selection.length<=1)
-throw new Error('Only supports multiple items');this.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},updateContents_:function(){var selection=this.currentSelection_;this.$.content.textContent='';if(!selection)
-return;var eventsByTitle=selection.getEventsOrganizedByTitle();var numTitles=tr.b.dictionaryLength(eventsByTitle);var summaryTableEl=document.createElement('tr-ui-a-multi-event-summary-table');summaryTableEl.configure({showTotals:numTitles>1,eventsByTitle:eventsByTitle,eventsHaveDuration:this.eventsHaveDuration_,eventsHaveSubRows:this.eventsHaveSubRows_});this.$.content.appendChild(summaryTableEl);var selectionSummaryTableEl=document.createElement('tr-ui-a-selection-summary-table');selectionSummaryTableEl.selection=this.currentSelection_;this.$.content.appendChild(selectionSummaryTableEl);if(numTitles===1){var detailsTableEl=document.createElement('tr-ui-a-multi-event-details-table');detailsTableEl.eventsHaveDuration=this.eventsHaveDuration_;detailsTableEl.eventsHaveSubRows=this.eventsHaveSubRows_;detailsTableEl.selection=selection;this.$.content.appendChild(detailsTableEl);}}});'use strict';Polymer('tr-ui-a-multi-thread-slice-sub-view',{created:function(){this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;if(tr.isExported('tr.ui.e.chrome.cc.RasterTaskSelection')){if(tr.ui.e.chrome.cc.RasterTaskSelection.supports(selection)){var ltvSelection=new tr.ui.e.chrome.cc.RasterTaskSelection(selection);var ltv=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();ltv.objectSnapshot=ltvSelection.containingSnapshot;ltv.selection=ltvSelection;ltv.extraHighlightsByLayerId=ltvSelection.extraHighlightsByLayerId;this.$.content.textContent='';this.$.content.appendChild(ltv);this.requiresTallView_=true;return;}}
-this.$.content.textContent='';var mesv=document.createElement('tr-ui-a-multi-event-sub-view');mesv.selection=selection;this.$.content.appendChild(mesv);var relatedEvents=document.createElement('tr-ui-a-related-events');relatedEvents.setRelatedEvents(selection);if(relatedEvents.hasRelatedEvents()){this.$.content.appendChild(relatedEvents);}},get requiresTallView(){if(this.$.content.children.length===0)
-return false;var childTagName=this.$.content.children[0].tagName;if(childTagName==='TR-UI-A-MULTI-EVENT-SUB-VIEW')
-return false;return true;}});'use strict';Polymer('tr-ui-a-single-async-slice-sub-view',{getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});return rows;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-multi-async-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;},get relatedEventsToHighlight(){if(!this.$.content.selection)
-return undefined;var selection=new tr.model.EventSet();this.$.content.selection.forEach(function(asyncEvent){if(!asyncEvent.associatedEvents)
-return;asyncEvent.associatedEvents.forEach(function(event){selection.push(event);});});if(selection.length)
-return selection;return undefined;}});'use strict';Polymer('tr-ui-a-single-cpu-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.CpuSlice))
-throw new Error('Only supports thread time slices');this.currentSelection_=selection;var cpuSlice=selection[0];var thread=cpuSlice.threadThatWasRunning;var shadowRoot=this.shadowRoot;if(thread){shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;}else{shadowRoot.querySelector('#process-name').parentElement.style.display='none';shadowRoot.querySelector('#thread-name').textContent=cpuSlice.title;}
-shadowRoot.querySelector('#start').timestamp=cpuSlice.start;shadowRoot.querySelector('#duration').duration=cpuSlice.duration;var runningThreadEl=shadowRoot.querySelector('#running-thread');var timeSlice=cpuSlice.getAssociatedTimeslice();if(!timeSlice){runningThreadEl.parentElement.style.display='none';}else{var threadLink=document.createElement('tr-ui-a-analysis-link');threadLink.selection=new tr.model.EventSet(timeSlice);threadLink.textContent='Click to select';runningThreadEl.parentElement.style.display='';runningThreadEl.textContent='';runningThreadEl.appendChild(threadLink);}
-shadowRoot.querySelector('#args').object=cpuSlice.args;}});'use strict';Polymer('tr-ui-a-multi-cpu-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-single-thread-time-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.ThreadTimeSlice))
-throw new Error('Only supports thread time slices');this.currentSelection_=selection;var timeSlice=selection[0];var thread=timeSlice.thread;var shadowRoot=this.shadowRoot;shadowRoot.querySelector('#state').textContent=timeSlice.title;var stateColor=tr.b.ColorScheme.colorsAsStrings[timeSlice.colorId];shadowRoot.querySelector('#state').style.backgroundColor=stateColor;shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;shadowRoot.querySelector('#start').timestamp=timeSlice.start;shadowRoot.querySelector('#duration').duration=timeSlice.duration;var onCpuEl=shadowRoot.querySelector('#on-cpu');onCpuEl.textContent='';var runningInsteadEl=shadowRoot.querySelector('#running-instead');if(timeSlice.cpuOnWhichThreadWasRunning){runningInsteadEl.parentElement.removeChild(runningInsteadEl);var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(timeSlice.getAssociatedCpuSlice());cpuLink.textContent=timeSlice.cpuOnWhichThreadWasRunning.userFriendlyName;onCpuEl.appendChild(cpuLink);}else{onCpuEl.parentElement.removeChild(onCpuEl);var cpuSliceThatTookCpu=timeSlice.getCpuSliceThatTookCpu();if(cpuSliceThatTookCpu){var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(cpuSliceThatTookCpu);if(cpuSliceThatTookCpu.thread)
-cpuLink.textContent=cpuSliceThatTookCpu.thread.userFriendlyName;else
-cpuLink.textContent=cpuSliceThatTookCpu.title;runningInsteadEl.appendChild(cpuLink);}else{runningInsteadEl.parentElement.removeChild(runningInsteadEl);}}
-var argsEl=shadowRoot.querySelector('#args');if(tr.b.dictionaryKeys(timeSlice.args).length>0){var argsView=document.createElement('tr-ui-a-generic-object-view');argsView.object=timeSlice.args;argsEl.parentElement.style.display='';argsEl.textContent='';argsEl.appendChild(argsView);}else{argsEl.parentElement.style.display='none';}}});'use strict';Polymer('tr-ui-a-multi-thread-time-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-single-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-single-event-sub-view');realView.setSelectionWithoutErrorChecks(selection);this.$.content.appendChild(realView);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';Polymer('tr-ui-a-multi-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.$.content.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';(function(){var COUNTER_SAMPLE_TABLE_COLUMNS=[{title:'Counter',width:'150px',value:function(row){return row.counter;}},{title:'Series',width:'150px',value:function(row){return row.series;}},{title:'Time',width:'150px',value:function(row){return row.start;}},{title:'Value',width:'100%',value:function(row){return row.value;}}];Polymer('tr-ui-a-counter-sample-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=COUNTER_SAMPLE_TABLE_COLUMNS;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.selection?this.getRows_(this.selection.toArray()):[];this.$.table.rebuild();},getRows_:function(samples){var samplesByCounter=tr.b.group(samples,function(sample){return sample.series.counter.guid;});var rows=[];tr.b.iterItems(samplesByCounter,function(unused,counterSamples){var samplesBySeries=tr.b.group(counterSamples,function(sample){return sample.series.guid;});tr.b.iterItems(samplesBySeries,function(unused,seriesSamples){var seriesRows=this.getRowsForSamples_(seriesSamples);seriesRows[0].counter=seriesSamples[0].series.counter.name;seriesRows[0].series=seriesSamples[0].series.name;if(seriesRows.length>1){seriesRows[0].subRows=seriesRows.slice(1);seriesRows[0].isExpanded=true;}
-rows.push(seriesRows[0]);},this);},this);return rows;},getRowsForSamples_:function(samples){return samples.map(function(sample){return{start:sample.timestamp,value:sample.value};});}});})();'use strict';Polymer('tr-ui-a-single-flow-event-sub-view',{getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});function createLinkTo(slice){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(slice);});linkEl.textContent=slice.userFriendlyName;return linkEl;}
-rows.push({name:'From',value:createLinkTo(event.startSlice)});rows.push({name:'To',value:createLinkTo(event.endSlice)});return rows;}});'use strict';Polymer('tr-ui-a-multi-flow-event-sub-view',{ready:function(){this.$.content.eventsHaveDuration=false;this.$.content.eventsHaveSubRows=false;},set selection(selection){this.$.content.selection=selection;},get selection(){return this.$.content.selection;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectInstanceView=tr.ui.b.define('object-instance-view');ObjectInstanceView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectInstance_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectInstance=obj;},get modelEvent(){return this.objectInstance;},get objectInstance(){return this.objectInstance_;},set objectInstance(i){this.objectInstance_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstanceView;options.defaultMetadata={showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectInstanceView,options);return{ObjectInstanceView:ObjectInstanceView};});'use strict';Polymer('tr-ui-a-single-object-instance-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.$.content.children.length===0)
-return false;if(this.$.content.children[0]instanceof
-tr.ui.analysis.ObjectInstanceView)
-return this.$.content.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectInstance))
-throw new Error('Only supports object instances');this.$.content.textContent='';this.currentSelection_=selection;var instance=selection[0];var typeInfo=tr.ui.analysis.ObjectInstanceView.getTypeInfo(instance.category,instance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.$.content.appendChild(customView);customView.modelEvent=instance;}else{this.appendGenericAnalysis_(instance);}},appendGenericAnalysis_:function(instance){var html='';html+='<div class="title">'+
-instance.typeName+' '+
-instance.id+'</div>\n';html+='<table>';html+='<tr>';html+='<tr><td>creationTs:</td><td>'+
-instance.creationTs+'</td></tr>\n';if(instance.deletionTs!=Number.MAX_VALUE){html+='<tr><td>deletionTs:</td><td>'+
-instance.deletionTs+'</td></tr>\n';}else{html+='<tr><td>deletionTs:</td><td>not deleted</td></tr>\n';}
-html+='<tr><td>snapshots:</td><td id="snapshots"></td></tr>\n';html+='</table>';this.$.content.innerHTML=html;var snapshotsEl=this.$.content.querySelector('#snapshots');instance.snapshots.forEach(function(snapshot){var snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);snapshotsEl.appendChild(snapshotLink);});}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectSnapshotView=tr.ui.b.define('object-snapshot-view');ObjectSnapshotView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectSnapshot_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectSnapshot=obj;},get modelEvent(){return this.objectSnapshot;},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(i){this.objectSnapshot_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshotView;options.defaultMetadata={showInstances:true,showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectSnapshotView,options);return{ObjectSnapshotView:ObjectSnapshotView};});'use strict';Polymer('tr-ui-a-single-object-snapshot-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.children.length===0)
-return false;if(this.children[0]instanceof tr.ui.analysis.ObjectSnapshotView)
-return this.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectSnapshot))
-throw new Error('Only supports object instances');this.textContent='';this.currentSelection_=selection;var snapshot=selection[0];var typeInfo=tr.ui.analysis.ObjectSnapshotView.getTypeInfo(snapshot.objectInstance.category,snapshot.objectInstance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.appendChild(customView);customView.modelEvent=snapshot;}else{this.appendGenericAnalysis_(snapshot);}},appendGenericAnalysis_:function(snapshot){var instance=snapshot.objectInstance;this.textContent='';var titleEl=document.createElement('div');titleEl.classList.add('title');titleEl.appendChild(document.createTextNode('Snapshot of '));this.appendChild(titleEl);var instanceLinkEl=document.createElement('tr-ui-a-analysis-link');instanceLinkEl.selection=new tr.model.EventSet(instance);titleEl.appendChild(instanceLinkEl);titleEl.appendChild(document.createTextNode(' @ '));titleEl.appendChild(tr.ui.units.createTimeStampSpan(snapshot.ts,{ownerDocument:this.ownerDocument}));var tableEl=document.createElement('table');this.appendChild(tableEl);var rowEl=document.createElement('tr');tableEl.appendChild(rowEl);var labelEl=document.createElement('td');labelEl.textContent='args:';rowEl.appendChild(labelEl);var argsEl=document.createElement('td');argsEl.id='args';rowEl.appendChild(argsEl);var objectViewEl=document.createElement('tr-ui-a-generic-object-view');objectViewEl.object=snapshot.args;argsEl.appendChild(objectViewEl);}});'use strict';Polymer('tr-ui-a-multi-object-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;var objectEvents=tr.b.asArray(selection).sort(tr.b.Range.compareByMinTimes);var timeSpanConfig={ownerDocument:this.ownerDocument};var table=this.$.content;table.tableColumns=[{title:'First',value:function(event){if(event instanceof tr.model.ObjectSnapshot)
-return tr.ui.units.createTimeStampSpan(event.ts,timeSpanConfig);var spanEl=document.createElement('span');spanEl.appendChild(tr.ui.units.createTimeStampSpan(event.creationTs,timeSpanConfig));spanEl.appendChild(tr.ui.b.createSpan({textContent:'-',marginLeft:'4px',marginRight:'4px'}));if(event.deletionTs!=Number.MAX_VALUE){spanEl.appendChild(tr.ui.units.createTimeStampSpan(event.deletionTs,timeSpanConfig));}
-return spanEl;},width:'200px'},{title:'Second',value:function(event){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(event);},event.userFriendlyName);return linkEl;},width:'100%'}];table.tableRows=objectEvents;table.rebuild();}});'use strict';Polymer('tr-ui-a-single-sample-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.tableColumns=[{title:'FirstColumn',value:function(row){return row.title;},width:'250px'},{title:'SecondColumn',value:function(row){return row.value;},width:'100%'}];this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;if(this.currentSelection_===undefined){this.$.content.tableRows=[];return;}
-var sample=this.currentSelection_[0];var table=this.$.content;var rows=[];rows.push({title:'Title',value:sample.title});rows.push({title:'Sample time',value:tr.ui.units.createTimeStampSpan(sample.start,{ownerDocument:this.ownerDocument})});var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sample.leafStackFrame;rows.push({title:'Stack trace',value:sfEl});table.tableRows=rows;table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){function zFunction(list){var n=list.length;if(n===0)
-return[];var z=new Array(n);z[0]=0;for(var i=1,left=0,right=0;i<n;++i){var maxLength;if(i<=right)
-maxLength=Math.min(right-i+1,z[i-left]);else
-maxLength=0;while(i+maxLength<n&&list[maxLength]===list[i+maxLength])
-++maxLength;if(i+maxLength-1>right){left=i;right=i+maxLength-1;}
-z[i]=maxLength;}
-return z;}
-function StackFrameTreeNode(title,opt_frame){this.title=title;this.frame=opt_frame;this.parent=undefined;this.children=[];this.childMap={};this.total=0;this.self=0;}
-StackFrameTreeNode.prototype={get subRows(){return this.children;},get stackTraceTitles(){var titles=[];for(var currentNode=this;currentNode!==undefined;currentNode=currentNode.parent){titles.push(currentNode.title);}
-return titles;},getOrCreateChild:function(title,opt_frame){var childNode=this.childMap[title];if(childNode!==undefined)
-return childNode;childNode=new StackFrameTreeNode(title,opt_frame);childNode.parent=this;this.children.push(childNode);this.childMap[title]=childNode;return childNode;},addStackTrace:function(trace,value,opt_traceContainsRootFrame){var currentNode=this;var startIndex=trace.length-(opt_traceContainsRootFrame?2:1);for(var i=startIndex;i>=0;i--){currentNode.total+=value;var stackFrame=trace[i];currentNode=currentNode.getOrCreateChild(stackFrame.title,stackFrame);}
-currentNode.total+=value;currentNode.self+=value;},convertToBottomUpView:function(){var bottomUpViewRoot=new StackFrameTreeNode(this.title,this.frame);bottomUpViewRoot.total=this.total;bottomUpViewRoot.self=this.self;this.addChildrenToBottomUpViewRecursively_(bottomUpViewRoot);return bottomUpViewRoot;},addChildrenToBottomUpViewRecursively_:function(bottomUpViewRoot){this.children.forEach(function(child){child.addToBottomUpViewRecursively_(bottomUpViewRoot);});},addToBottomUpViewRecursively_:function(bottomUpViewRoot){var remainingRecursiveSuffixLength=this.calculateRecursiveSuffixLength_();var bottomUpParentNode=bottomUpViewRoot;for(var topDownNode=this;topDownNode.parent!==undefined;topDownNode=topDownNode.parent){var bottomUpChildNode=bottomUpParentNode.getOrCreateChild(topDownNode.title,topDownNode.frame);bottomUpChildNode.self+=this.self;if(remainingRecursiveSuffixLength>0)
-remainingRecursiveSuffixLength--;else
-bottomUpChildNode.total+=this.total;bottomUpParentNode=bottomUpChildNode;}
-this.addChildrenToBottomUpViewRecursively_(bottomUpViewRoot);},calculateRecursiveSuffixLength_:function(){var maxLengths=zFunction(this.stackTraceTitles);var recursiveSuffixLength=0;for(var i=0;i<maxLengths.length;i++)
-recursiveSuffixLength=Math.max(recursiveSuffixLength,maxLengths[i]);return recursiveSuffixLength;}};return{StackFrameTreeNode:StackFrameTreeNode,zFunction:zFunction};});'use strict';(function(){Polymer('tr-ui-a-multi-sample-sub-view',{ready:function(){this.viewSelector_=this.$.view_selector;this.selection_=undefined;this.viewSelector_.addEventListener('change',this.viewSelectorChanged_.bind(this));},viewSelectorChanged_:function(){this.samplingData_=this.createSamplingSummary_(this.selection_,this.viewSelector_.value);this.updateContents_();},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.samplingData_=this.createSamplingSummary_(selection,this.viewSelector_.value);this.updateContents_();},createSamplingSummary_:function(selection,viewOption){var root=new tr.ui.analysis.StackFrameTreeNode('(root)',undefined);var samples=selection.getEventsOrganizedByBaseType().sample;samples.forEach(function(sample){root.addStackTrace(sample.stackTrace,1);});switch(viewOption){case'TOPDOWNVIEW':return root;case'BOTTOMUPVIEW':return root.convertToBottomUpView();default:throw new Error('Unknown sampling summary view option: \''+viewOption+'\'');}},updateContents_:function(){var columns=[this.createPercentColumn_('Total'),this.createSamplesColumn_('Total'),this.createPercentColumn_('Self'),this.createSamplesColumn_('Self'),{title:'Symbol',value:function(row){return row.title;},width:'250px',cmp:function(a,b){return a.title.localeCompare(b.title);},showExpandButtons:true}];this.$.table.tableColumns=columns;this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;this.$.table.tableRows=this.samplingData_.subRows;this.$.table.rebuild();},createPercentColumn_:function(title){var field=title.toLowerCase();return{title:title+' percent',value:function(row){var percent=row[field]/this.samplingData_.total;var span=document.createElement('tr-ui-u-scalar-span');span.value=(percent*100).toFixed(2);span.percentage=percent;span.unit=tr.b.u.Units.unitlessNumber;return span;}.bind(this),width:'60px',cmp:function(a,b){return a[field]-b[field];}};},createSamplesColumn_:function(title){var field=title.toLowerCase();return{title:title+' samples',value:function(row){return row[field];},width:'60px',cmp:function(a,b){return a[field]-b[field];}};}});})();'use strict';Polymer('tr-ui-a-single-interaction-record-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.textContent='';var realView=document.createElement('tr-ui-a-single-event-sub-view');this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-multi-interaction-record-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.currentSelection_=selection;this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(ir){ir.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';Polymer('tr-ui-a-alert-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},getRowsForSingleAlert_:function(alert){var rows=[];for(var argName in alert.args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=alert.args[argName];rows.push({name:argName,value:argView});}
-if(alert.associatedEvents.length){alert.associatedEvents.forEach(function(event,i){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return event;},event.title);var valueString='';if(event instanceof tr.model.TimedEvent)
-valueString='took '+event.duration.toFixed(2)+'ms';rows.push({name:linkEl,value:valueString});});}
-var descriptionEl=tr.ui.b.createDiv({textContent:alert.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(alert.info.docLinks){alert.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}
-return rows;},getRowsForAlerts_:function(alerts){if(alerts.length==1){var rows=[{name:'Alert',value:alerts[0].title}];var detailRows=this.getRowsForSingleAlert_(alerts[0]);rows.push.apply(rows,detailRows);return rows;}else{return alerts.map(function(alert){return{name:'Alert',value:alert.title,isExpanded:alerts.size<10,subRows:this.getRowsForSingleAlert_(alert)};},this);}},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
-var alerts=this.currentSelection_;this.$.table.tableRows=this.getRowsForAlerts_(alerts);this.$.table.rebuild();},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-single-frame-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!=1)
-throw new Error('Only supports single frame!');this.currentSelection_=selection;this.$.asv.selection=selection[0].associatedAlerts;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-multi-frame-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(frameEvent){frameEvent.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var NO_BREAK_SPACE=String.fromCharCode(160);var COLLATOR=new Intl.Collator(undefined,{numeric:true});function TitleColumn(title){this.title=title;}
-TitleColumn.prototype={supportsCellSelection:false,value:function(row){var formattedTitle=this.formatTitle(row);var defined=row.defined;if(defined===undefined||defined.length===0)
-return formattedTitle;var firstDefined=defined[0];var lastDefined=defined[defined.length-1];var changeDefinedCount=0;for(var i=1;i<defined.length;i++){if(defined[i]!==defined[i-1])
-changeDefinedCount++;}
-var color=undefined;var prefix=undefined;if(!firstDefined&&lastDefined){color='red';prefix='+++';}else if(firstDefined&&!lastDefined){color='green';prefix='---';}
-if(changeDefinedCount>1){color='purple';}
-if(color===undefined&&prefix===undefined)
-return formattedTitle;var titleEl=document.createElement('span');if(prefix!==undefined){var prefixEl=tr.ui.b.createSpan({textContent:prefix});prefixEl.style.fontFamily='monospace';titleEl.appendChild(prefixEl);titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));}
-if(color!==undefined)
-titleEl.style.color=color;titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedTitle));return titleEl;},formatTitle:function(row){return row.title;},cmp:function(rowA,rowB){return COLLATOR.compare(rowA.title,rowB.title);}};function MemoryColumn(name,title,units,cellGetter,aggregationMode){this.name=name;this.title=title;this.units=units;this.cell=cellGetter;this.aggregationMode=aggregationMode;this.color=undefined;}
-MemoryColumn.fromRows=function(rows,cellKey,aggregationMode,opt_titleBuilder){var columnTraits={};function gatherTraits(row){if(row===undefined)
-return;var attrCells=row[cellKey];if(attrCells===undefined)
-return;tr.b.iterItems(attrCells,function(attrName,attrCell){if(attrCell===undefined)
-return;var attrValues=attrCell.attrs;if(attrValues===undefined)
-return;var existingTraits=columnTraits[attrName];attrValues.forEach(function(attrValue){if(attrValue===undefined)
-return;if(existingTraits===undefined){columnTraits[attrName]=existingTraits={constructor:attrValue.constructor,units:attrValue.units};return;}
-if(existingTraits.constructor!==attrValue.constructor||existingTraits.units!==attrValue.units){existingTraits.constructor=tr.model.UnknownAttribute;existingTraits.units=undefined;}});});if(row.subRows!==undefined)
-row.subRows.forEach(gatherTraits);};rows.forEach(gatherTraits);var titleBuilder=opt_titleBuilder||tr.b.identity;var columns=[];tr.b.iterItems(columnTraits,function(columnName,columnTraits){var cellGetter=fieldGetter(cellKey,columnName);var title=titleBuilder(columnName);columns.push(MemoryColumn.fromAttributeTraits(columnName,title,columnTraits,cellGetter,aggregationMode));});return columns;};MemoryColumn.fromAttributeTraits=function(name,title,traits,cellGetter,aggregationMode){var constructor;if(traits.constructor===tr.model.ScalarAttribute)
-constructor=ScalarMemoryColumn;else
-constructor=MemoryColumn;return new constructor(name,title,traits.units,cellGetter,aggregationMode);};MemoryColumn.spaceEqually=function(columns){var columnWidth=(100/columns.length).toFixed(3)+'%';columns.forEach(function(column){column.width=columnWidth;});};MemoryColumn.sortByImportance=function(columns,importanceRules){var positions=columns.map(function(column,srcIndex){return{importance:column.getImportance(importanceRules),column:column};});positions.sort(function(a,b){if(a.importance===b.importance)
-return COLLATOR.compare(a.column.name,b.column.name);return b.importance-a.importance;});positions.forEach(function(position,dstIndex){columns[dstIndex]=position.column;});};MemoryColumn.columnNamesToImportanceRules=function(columnNames){return columnNames.map(function(columnName,columnIndex){return{condition:columnName,importance:columnNames.length-columnIndex};});};MemoryColumn.iconFromAttributeInfoType=function(type){switch(type){case tr.model.AttributeInfoType.WARNING:return{symbol:String.fromCharCode(9888),color:'red'};case tr.model.AttributeInfoType.LINK:return{symbol:String.fromCharCode(9903)};case tr.model.AttributeInfoType.MEMORY_OWNER:return{symbol:String.fromCharCode(8702),color:'green'};case tr.model.AttributeInfoType.MEMORY_OWNED:return{symbol:String.fromCharCode(8701),color:'green'};case tr.model.AttributeInfoType.OVERALL_VALUE:return{symbol:String.fromCharCode(8614)};case tr.model.AttributeInfoType.RECENT_VALUE:return{symbol:String.fromCharCode(8618)};case tr.model.AttributeInfoType.HAS_HEAP_DUMP:return{symbol:String.fromCharCode(9283)};default:return{symbol:String.fromCharCode(9432),color:'blue'};}
-throw new Error('Unreachable');};MemoryColumn.AggregationMode={DIFF:0,MAX:1};MemoryColumn.prototype={attrs:function(row){var cell=this.cell(row);if(cell===undefined)
-return undefined;return cell.attrs;},value:function(row){var attrs=this.attrs(row);if(this.hasAllAttrsUndefined(attrs))
-return'';return this.formatAttributes(attrs);},hasAllAttrsUndefined:function(attrs){if(attrs===undefined)
-return true;return attrs.every(function(attr){return attr===undefined;});},formatAttributes:function(attrs){var formattedValue=this.formatAttributeValues(attrs);var color;if(typeof this.color==='function')
-color=this.color(attrs);else
-color=this.color;var infos=this.getInfos(attrs);if((color===undefined||formattedValue==='')&&infos.length===0)
-return formattedValue;var attrEl=document.createElement('span');attrEl.style.display='flex';attrEl.style.alignItems='center';attrEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedValue));infos.forEach(function(info){var infoEl=document.createElement('span');infoEl.style.paddingLeft='4px';infoEl.style.cursor='help';infoEl.style.fontWeight='bold';var icon=MemoryColumn.iconFromAttributeInfoType(info.type);infoEl.textContent=icon.symbol;if(icon.color!==undefined)
-infoEl.style.color=icon.color;infoEl.title=info.message;attrEl.appendChild(infoEl);},this);if(color!==undefined)
-attrEl.style.color=color;return attrEl;},formatAttributeValues:function(attrs){if(attrs.length===1)
-return this.formatSingleAttributeValue(attrs[0]);else
-return this.formatMultipleAttributeValues(attrs);},formatSingleAttributeValue:function(attr){return String(attr.value);},formatMultipleAttributeValues:function(attrs){var commonAttr=this.getCommonAttributeOrUndefined(attrs);if(commonAttr===undefined){return tr.ui.b.createSpan({textContent:'(multiple values)',italic:true});}
-return this.formatSingleAttributeValue(commonAttr);},cmp:function(rowA,rowB){var attrsA=this.attrs(rowA);var attrsB=this.attrs(rowB);if(attrsA!==undefined&&attrsB!==undefined&&attrsA.length!==attrsB.length)
-throw new Error('Different number of attributes');var undefinedA=this.hasAllAttrsUndefined(attrsA);var undefinedB=this.hasAllAttrsUndefined(attrsB);if(undefinedA&&undefinedB)
-return 0;if(undefinedA)
-return-1;if(undefinedB)
-return 1;return this.compareAttributes(attrsA,attrsB);},compareAttributes:function(attrsA,attrsB){if(attrsA.length===1)
-return this.compareSingleAttributes(attrsA[0],attrsB[0]);else
-return this.compareMultipleAttributes(attrsA,attrsB);},compareSingleAttributes:function(attrA,attrB){var strA=String(attrA.value);var strB=String(attrB.value);return COLLATOR.compare(strA,strB);},compareMultipleAttributes:function(attrsA,attrsB){var commonAttrA=this.getCommonAttributeOrUndefined(attrsA);var commonAttrB=this.getCommonAttributeOrUndefined(attrsB);var hasMultipleValuesA=commonAttrA===undefined;var hasMultipleValuesB=commonAttrB===undefined;if(hasMultipleValuesA&&hasMultipleValuesB)
-return 0;if(hasMultipleValuesA)
-return 1;if(hasMultipleValuesB)
-return-1;return this.compareSingleAttributes(commonAttrA,commonAttrB);},getCommonAttributeOrUndefined:function(attrs){var firstDefinedAttribute=undefined;for(var i=0;i<attrs.length;i++){var attr=attrs[i];if(attr===undefined)
-continue;if(firstDefinedAttribute===undefined){firstDefinedAttribute=attr;continue;}
-if(firstDefinedAttribute.value!==attr.value||firstDefinedAttribute.units!==attr.units){return undefined;}}
-return firstDefinedAttribute;},getInfos:function(attrs){if(attrs.length!==1){var hasDumpInfo=undefined;attrs.some(function(attr){if(attr===undefined)
-return false;return attr.infos.some(function(info){if(info.type!==tr.model.AttributeInfoType.HAS_HEAP_DUMP)
-return false;hasDumpInfo=info;return true;});});if(hasDumpInfo)
-return[hasDumpInfo];else
-return[];}
-return attrs[0].infos;},getImportance:function(importanceRules){if(importanceRules.length===0)
-return 0;for(var i=0;i<importanceRules.length;i++){var importanceRule=importanceRules[i];if(this.matchesNameCondition(importanceRule.condition))
-return importanceRule.importance;}
-var minImportance=importanceRules[0].importance;for(var i=1;i<importanceRules.length;i++){minImportance=Math.min(minImportance,importanceRules[i].importance);}
-return minImportance-1;},matchesNameCondition:function(condition){if(condition===undefined)
-return true;if(typeof(condition)==='string')
-return this.name===condition;return condition.test(this.name);}};function ScalarMemoryColumn(name,title,units,cellGetter,aggregationMode){MemoryColumn.call(this,name,title,units,cellGetter,aggregationMode);}
-ScalarMemoryColumn.prototype={__proto__:MemoryColumn.prototype,formatSingleAttributeValue:function(attr){return this.formatUnits(attr.value,false);},formatMultipleAttributeValues:function(attrs){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.formatUnits(this.getDiffAttrValue(attrs),true);case MemoryColumn.AggregationMode.MAX:return this.formatUnits(this.getMaxAttrValue(attrs),false);default:return tr.ui.b.createSpan({textContent:'(unsupported aggregation mode)',italic:true});}},formatUnits:function(value,isDelta){if(value===undefined)
-return'';var sizeEl=document.createElement('tr-ui-u-scalar-span');sizeEl.value=value;if(this.units==='bytes')
-sizeEl.unit=tr.b.u.Units.sizeInBytes;else
-sizeEl.unit=tr.b.u.Units.unitlessNumber;if(!isDelta)
-return sizeEl;sizeEl.isDelta=true;if(value===0)
-return sizeEl;var wrapperEl=document.createElement('span');wrapperEl.style.color=value>0?'red':'green';wrapperEl.appendChild(sizeEl);return wrapperEl;},compareSingleAttributes:function(attrA,attrB){return attrA.value-attrB.value;},compareMultipleAttributes:function(attrA,attrB){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:var diffA=this.getDiffAttrValue(attrA)||0;var diffB=this.getDiffAttrValue(attrB)||0;return diffA-diffB;case MemoryColumn.AggregationMode.MAX:return this.getMaxAttrValue(attrA)-this.getMaxAttrValue(attrB);default:return 0;}},getDiffAttrValue:function(attrs){var firstAttr=attrs[0];var lastAttr=attrs[attrs.length-1];if(firstAttr===undefined&&lastAttr===undefined)
-return undefined;var firstValue=firstAttr===undefined?0:firstAttr.value;var lastValue=lastAttr===undefined?0:lastAttr.value;return lastValue-firstValue;},getMaxAttrValue:function(attrs){return attrs.reduce(function(accumulator,attr){if(attr===undefined)
-return accumulator;if(accumulator===undefined||attr.value>accumulator)
-accumulator=attr.value;return accumulator;},undefined);}};function MemoryCell(attrs){this.attrs=attrs;}
-MemoryCell.extractAttributes=function(cell){if(cell===undefined)
-return undefined;return cell.attrs;};function fieldGetter(){var fields=tr.b.asArray(arguments);return function(row){var value=row;for(var i=0;i<fields.length;i++)
-value=value[fields[i]];return value;};}
-var RECURSIVE_EXPANSION_MAX_SUB_ROW_COUNT=10;function expandTableRowsRecursively(table){function expandRowRecursively(row){if(row.subRows===undefined||row.subRows.length===0)
-return;if(row.subRows.length>RECURSIVE_EXPANSION_MAX_SUB_ROW_COUNT)
-return;table.setExpandedForTableRow(row,true);row.subRows.forEach(expandRowRecursively);}
-table.tableRows.forEach(expandRowRecursively);}
-function aggregateTableRowCellsRecursively(row,cellKey){var subRows=row.subRows;if(subRows===undefined)
-return;subRows.forEach(function(subRow){aggregateTableRowCellsRecursively(subRow,cellKey);});aggregateTableRowCells(row,subRows,cellKey);}
-function aggregateTableRowCells(row,subRows,cellKey){var rowCells=row[cellKey];if(rowCells===undefined)
-row[cellKey]=rowCells={};var subRowCellNames={};subRows.forEach(function(subRow){var subRowCells=subRow[cellKey];if(subRowCells===undefined)
-return;tr.b.iterItems(subRowCells,function(columnName){subRowCellNames[columnName]=true;});});tr.b.iterItems(subRowCellNames,function(cellName){var existingRowCell=rowCells[cellName];var existingRowAttributes=MemoryCell.extractAttributes(existingRowCell);var timestampCount=undefined;if(existingRowAttributes!==undefined)
-timestampCount=existingRowAttributes.length;subRows.forEach(function(subRow){var subRowCells=subRow[cellKey];if(subRowCells===undefined)
-return;var subRowCellAttributes=MemoryCell.extractAttributes(subRowCells[cellName]);if(subRowCellAttributes===undefined)
-return;if(timestampCount===undefined)
-timestampCount=subRowCellAttributes.length;else if(timestampCount!==subRowCellAttributes.length)
-throw new Error('Rows have different number of timestamps');});if(timestampCount===undefined)
-throw new Error('Handling non-existent cell name \''+cellName+'\'');var aggregatedAttributes=new Array(timestampCount);for(var i=0;i<timestampCount;i++){var existingRowAttribute=undefined;if(existingRowAttributes!==undefined)
-existingRowAttribute=existingRowAttributes[i];var subRowAttributes=subRows.map(function(subRow){var subRowCells=subRow[cellKey];if(subRowCells===undefined)
-return undefined;var subRowCellAttributes=MemoryCell.extractAttributes(subRowCells[cellName]);if(subRowCellAttributes===undefined)
-return;return subRowCellAttributes[i];});aggregatedAttributes[i]=tr.model.Attribute.aggregate(subRowAttributes,existingRowAttribute);}
-if(existingRowCell!==undefined){existingRowCell.attrs=aggregatedAttributes;}else{rowCells[cellName]=new MemoryCell(aggregatedAttributes);}});}
-function createCells(timeToValues,valueAttrsGetter,opt_cellAddedCallback){var attrNameToAttrs=tr.b.invertArrayOfDicts(timeToValues,valueAttrsGetter);return tr.b.mapItems(attrNameToAttrs,function(attrName,attrs){var cell=new tr.ui.analysis.MemoryCell(attrs);if(opt_cellAddedCallback!==undefined)
-opt_cellAddedCallback(attrName,cell);return cell;});}
-function addAttributeIfDefined(dstDict,attrName,attrClass,units,value,opt_addedCallback){if(value===undefined)
-return;var attr=new attrClass(units,value);dstDict[attrName]=attr;if(opt_addedCallback!==undefined)
-opt_addedCallback(attr);}
-return{TitleColumn:TitleColumn,MemoryColumn:MemoryColumn,ScalarMemoryColumn:ScalarMemoryColumn,MemoryCell:MemoryCell,fieldGetter:fieldGetter,expandTableRowsRecursively:expandTableRowsRecursively,aggregateTableRowCellsRecursively:aggregateTableRowCellsRecursively,aggregateTableRowCells:aggregateTableRowCells,createCells:createCells,addAttributeIfDefined:addAttributeIfDefined};});'use strict';Polymer('tr-ui-a-stacked-pane',{rebuild:function(){if(!this.paneDirty_){return;}
-this.paneDirty_=false;this.rebuildPane_();},scheduleRebuildPane_:function(){if(this.paneDirty_)
-return;this.paneDirty_=true;setTimeout(this.rebuild.bind(this),0);},rebuildPane_:function(){},set childPaneBuilder(childPaneBuilder){this.childPaneBuilder_=childPaneBuilder;this.dispatchEvent(new tr.b.Event('request-child-pane-change'));},get childPaneBuilder(){return this.childPaneBuilder_;},appended:function(){this.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){var COLUMN_IMPORTANCE_RULES=tr.ui.analysis.MemoryColumn.columnNamesToImportanceRules(['Total size','Self size']);Polymer('tr-ui-a-memory-dump-heap-details-pane',{created:function(){this.heapDumps_=undefined;this.aggregationMode_=undefined;this.bottomUpView_=false;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.view_mode_container.appendChild(tr.ui.b.createSelector(this,'bottomUpView','memoryDumpHeapDetailsPane.bottomUpView',false,[{label:'Tree (top down)',value:false},{label:'Heavy (bottom up)',value:true}]));},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},get heapDumps(){return this.heapDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},set bottomUpView(bottomUpView){this.bottomUpView_=bottomUpView;this.scheduleRebuildPane_();},get bottomUpView(){return this.bottomUpView_;},rebuildPane_:function(){if(this.heapDumps_===undefined||this.heapDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.view_mode_container.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';this.$.view_mode_container.style.display='block';var stackFrameTrees=this.createStackFrameTrees_(this.heapDumps_);var rows=this.createRows_(stackFrameTrees);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createStackFrameTrees_:function(heapDumps){return heapDumps.map(function(heapDump){if(heapDump===undefined)
-return undefined;var rootNode=new tr.ui.analysis.StackFrameTreeNode(heapDump.allocatorName);var sumSize=undefined;heapDump.entries.forEach(function(entry){var size=entry.size;var leafStackFrame=entry.leafStackFrame;if(leafStackFrame===undefined){if(sumSize!==undefined)
-throw new Error('Multiple sum stack frames');sumSize=size;return;}
-rootNode.addStackTrace(leafStackFrame.stackTrace,size,true);},this);if(sumSize!==undefined&&sumSize>rootNode.total){var unspecifiedSize=sumSize-rootNode.total;rootNode.total=sumSize;var unspecifiedNode=rootNode.getOrCreateChild('<unspecified>');unspecifiedNode.total+=unspecifiedSize;unspecifiedNode.self+=unspecifiedSize;}
-if(this.bottomUpView)
-return rootNode.convertToBottomUpView();else
-return rootNode;},this);},createRows_:function(stackFrameTrees){return[this.createHeapRowRecursively_(stackFrameTrees)];},createHeapRowRecursively_:function(nodes){var title=tr.b.findFirstInArray(nodes).title;var defined=nodes.map(function(node){return node!==undefined;});var cells=tr.ui.analysis.createCells(nodes,function(node){return{'Total size':new tr.model.ScalarAttribute('bytes',node.total),'Self size':new tr.model.ScalarAttribute('bytes',node.self)};});var groupedChildNodes=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(nodes,function(node){return node.children;}));var row={title:title,defined:defined,cells:cells};if(groupedChildNodes.length>0){row.subRows=groupedChildNodes.map(this.createHeapRowRecursively_,this);}
-return row;},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.TitleColumn('Stack frame');titleColumn.width='500px';var attributeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'cells',this.aggregationMode_);tr.ui.analysis.MemoryColumn.sortByImportance(attributeColumns,COLUMN_IMPORTANCE_RULES);tr.ui.analysis.MemoryColumn.spaceEqually(attributeColumns);var columns=[titleColumn].concat(attributeColumns);return columns;}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){var IMPORTANCE_RULES=[{condition:tr.model.MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME,importance:10},{condition:tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME,importance:9},{condition:'page_size',importance:0},{condition:/size/,importance:5},{importance:0}];function AllocatorDumpNameColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
-AllocatorDumpNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(!row.suballocation)
-return row.title;return tr.ui.b.createSpan({textContent:row.title,italic:true,tooltip:row.fullName});}};Polymer('tr-ui-a-memory-dump-allocator-details-pane',{created:function(){this.memoryAllocatorDumps_=undefined;this.heapDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.scheduleRebuildPane_();},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){if(this.memoryAllocatorDumps_===undefined||this.memoryAllocatorDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();this.childPaneBuilder=undefined;return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);if(this.heapDumps_===undefined){this.childPaneBuilder=undefined;}else{this.childPaneBuilder=function(){var pane=document.createElement('tr-ui-a-memory-dump-heap-details-pane');pane.heapDumps=this.heapDumps_;pane.aggregationMode=this.aggregationMode_;return pane;}.bind(this);}},createRows_:function(){return[this.createAllocatorRowRecursively_(this.memoryAllocatorDumps_)];},createAllocatorRowRecursively_:function(dumps){var definedDump=tr.b.findFirstInArray(dumps);var title=definedDump.name;var fullName=definedDump.fullName;var defined=dumps.map(function(dump){return dump!==undefined;});var cells=tr.ui.analysis.createCells(dumps,function(dump){return dump.attributes;});var suballocatedBy=undefined;if(title.startsWith('__')){for(var i=0;i<dumps.length;i++){var dump=dumps[i];if(dump===undefined||dump.ownedBy.length===0){continue;}
-var ownerDump=dump.ownedBy[0].source;if(dump.ownedBy.length>1||dump.children.length>0||ownerDump.containerMemoryDump!==dump.containerMemoryDump){suballocatedBy=undefined;break;}
-if(suballocatedBy===undefined){suballocatedBy=ownerDump.fullName;}else if(suballocatedBy!==ownerDump.fullName){suballocatedBy=undefined;break;}}}
-var row={title:title,fullName:fullName,defined:defined,cells:cells,suballocatedBy:suballocatedBy};var childDumpNameToDumps=tr.b.invertArrayOfDicts(dumps,function(dump){return tr.b.arrayToDict(dump.children,function(child){return child.name;});});var subRows=[];var suballocationClassificationRootNode=undefined;tr.b.iterItems(childDumpNameToDumps,function(childName,childDumps){var childRow=this.createAllocatorRowRecursively_(childDumps);if(childRow.suballocatedBy===undefined){subRows.push(childRow);}else{suballocationClassificationRootNode=this.classifySuballocationRow_(childRow,suballocationClassificationRootNode);}},this);if(suballocationClassificationRootNode!==undefined){var suballocationRow=this.createSuballocationRowRecursively_('suballocations',suballocationClassificationRootNode);tr.ui.analysis.aggregateTableRowCellsRecursively(suballocationRow,'cells');subRows.push(suballocationRow);}
-if(subRows.length>0)
-row.subRows=subRows;return row;},classifySuballocationRow_:function(suballocationRow,rootNode){if(rootNode===undefined){rootNode={children:{},row:undefined};}
-var suballocationLevels=suballocationRow.suballocatedBy.split('/');var currentNode=rootNode;for(var i=0;i<suballocationLevels.length;i++){var suballocationLevel=suballocationLevels[i];var nextNode=currentNode.children[suballocationLevel];if(nextNode===undefined){currentNode.children[suballocationLevel]=nextNode={children:{},row:undefined};}
-var currentNode=nextNode;}
-if(currentNode.row!==undefined)
-throw new Error('Multiple suballocations with the same owner name');currentNode.row=suballocationRow;return rootNode;},createSuballocationRowRecursively_:function(name,node){var childCount=Object.keys(node.children).length;if(childCount===0){if(node.row===undefined)
-throw new Error('Suballocation node must have a row or children');var row=node.row;row.title=name;row.suballocation=true;return row;}
-var subRows=tr.b.dictionaryValues(tr.b.mapItems(node.children,this.createSuballocationRowRecursively_,this));if(node.row!==undefined){var row=node.row;row.title='<unspecified>';row.suballocation=true;subRows.unshift(row);}
-var defined=new Array(subRows[0].defined.length);for(var i=0;i<subRows.length;i++){subRows[i].defined.forEach(function(definedValue,index){defined[index]=defined[index]||definedValue;});}
-return{title:name,suballocation:true,defined:defined,cells:{},subRows:subRows};},createColumns_:function(rows){var titleColumn=new AllocatorDumpNameColumn('Component');titleColumn.width='200px';var attributeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'cells',this.aggregationMode_);tr.ui.analysis.MemoryColumn.spaceEqually(attributeColumns);tr.ui.analysis.MemoryColumn.sortByImportance(attributeColumns,IMPORTANCE_RULES);var columns=[titleColumn].concat(attributeColumns);return columns;}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){var COLUMN_IMPORTANCE_RULES=tr.ui.analysis.MemoryColumn.columnNamesToImportanceRules(['Start address','Virtual size','Protection flags','PSS','Private dirty','Private clean','Shared dirty','Shared clean','Swapped']);var CLASSIFICATION_RULES={name:'Total',children:[{name:'Android',file:/^\/dev\/ashmem(?!\/libc malloc)/,children:[{name:'Java runtime',file:/^\/dev\/ashmem\/dalvik-/,children:[{name:'Spaces',file:/\/dalvik-(alloc|main|large object|non moving|zygote) space/,children:[{name:'Normal',file:/\/dalvik-(alloc|main)/},{name:'Large',file:/\/dalvik-large object/},{name:'Zygote',file:/\/dalvik-zygote/},{name:'Non-moving',file:/\/dalvik-non moving/}]},{name:'Linear Alloc',file:/\/dalvik-LinearAlloc/},{name:'Indirect Reference Table',file:/\/dalvik-indirect.ref/},{name:'Cache',file:/\/dalvik-jit-code-cache/},{name:'Accounting'}]},{name:'Cursor',file:/\/CursorWindow/},{name:'Ashmem'}]},{name:'Native heap',file:/^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|(\[discounted tracing overhead\])|$)/},{name:'Stack',file:/^\[stack/},{name:'Files',file:/\.((((jar)|(apk)|(ttf)|(odex)|(oat)|(arg))$)|(dex)|(so))/,children:[{name:'so',file:/\.so/},{name:'jar',file:/\.jar$/},{name:'apk',file:/\.apk$/},{name:'ttf',file:/\.ttf$/},{name:'dex',file:/\.((dex)|(odex$))/},{name:'oat',file:/\.oat$/},{name:'art',file:/\.art$/}]},{name:'Devices',file:/(^\/dev\/)|(anon_inode:dmabuf)/,children:[{name:'GPU',file:/\/((nv)|(mali)|(kgsl))/},{name:'DMA',file:/anon_inode:dmabuf/}]}]};function createEmptyRuleRow(rule){var row={title:rule.name,rule:rule,subRows:[]};if(rule.children!==undefined)
-row.subRows=rule.children.map(createEmptyRuleRow);return row;}
-function hexString(address,is64BitAddress){if(address===undefined)
-return undefined;var hexPadding=is64BitAddress?'0000000000000000':'00000000';return(hexPadding+address.toString(16)).substr(-hexPadding.length);}
-function classifyRegionRow(ruleRow,regionRow){var rule=ruleRow.rule;if(rule===undefined||rule.children===undefined||rule.children.length===0){ruleRow.subRows.push(regionRow);return;}
-function regionRowMatchesChildRule(childRule){var fileRegExp=childRule.file;if(fileRegExp===undefined)
-return true;return fileRegExp.test(regionRow.title);}
-var matchedChildRuleIndex=tr.b.findFirstIndexInArray(rule.children,regionRowMatchesChildRule);if(matchedChildRuleIndex===-1){matchedChildRuleIndex=rule.children.length;if(matchedChildRuleIndex>=ruleRow.subRows.length){ruleRow.subRows.push({title:'Other',subRows:[]});}}
-classifyRegionRow(ruleRow.subRows[matchedChildRuleIndex],regionRow);}
-function pruneEmptyRuleRows(row){if(row.subRows===undefined||row.subRows.length===0)
-return;if(row.subRows[0].rule===undefined){return;}
-row.subRows.forEach(pruneEmptyRuleRows);row.subRows=row.subRows.filter(function(subRow){return subRow.subRows.length>0;});}
-Polymer('tr-ui-a-memory-dump-vm-regions-details-pane',{created:function(){this.vmRegions_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set vmRegions(vmRegions){this.vmRegions_=vmRegions;this.scheduleRebuildPane_();},get vmRegions(){return this.vmRegions_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){var unclassifiedRows=[];if(this.vmRegions_!==undefined)
-unclassifiedRows=this.createUnclassifiedRows_(this.vmRegions_);if(unclassifiedRows.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.classifyRows_(unclassifiedRows);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},joinRegions_:function(timeToRegionIdToRegion){return tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToRegionIdToRegion,function(regionIdToRegion){return tr.b.arrayToDict(regionIdToRegion,function(region){return[region.mappedFile,region.startAddress].join('#');});}));},createUnclassifiedRows_:function(timeToRegionIdToRegion){var is64BitAddress=timeToRegionIdToRegion.some(function(regionIdToRegion){if(regionIdToRegion===undefined)
-return false;return regionIdToRegion.some(function(region){if(region.startAddress===undefined)
-return false;return region.startAddress>=4294967296;});});var regionIdToTimeToRegion=this.joinRegions_(timeToRegionIdToRegion);return regionIdToTimeToRegion.map(function(timeToRegion){var definedRegion=tr.b.findFirstInArray(timeToRegion);var defined=timeToRegion.map(function(region){return region!==undefined;});var constantCells=tr.ui.analysis.createCells([definedRegion],function(region){var attrs={};tr.ui.analysis.addAttributeIfDefined(attrs,'Start address',tr.model.StringAttribute,'',hexString(region.startAddress,is64BitAddress));return attrs;});var variableCells=tr.ui.analysis.createCells(timeToRegion,function(region){var attrs={};tr.ui.analysis.addAttributeIfDefined(attrs,'Virtual size',tr.model.ScalarAttribute,'bytes',region.sizeInBytes);tr.ui.analysis.addAttributeIfDefined(attrs,'Protection flags',tr.model.StringAttribute,'',region.protectionFlagsToString);tr.ui.analysis.addAttributeIfDefined(attrs,'PSS',tr.model.ScalarAttribute,'bytes',region.byteStats.proportionalResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Private dirty',tr.model.ScalarAttribute,'bytes',region.byteStats.privateDirtyResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Private clean',tr.model.ScalarAttribute,'bytes',region.byteStats.privateCleanResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Shared dirty',tr.model.ScalarAttribute,'bytes',region.byteStats.sharedDirtyResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Shared clean',tr.model.ScalarAttribute,'bytes',region.byteStats.sharedCleanResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Swapped',tr.model.ScalarAttribute,'bytes',region.byteStats.swapped);return attrs;});return{title:definedRegion.mappedFile||'',defined:defined,constantCells:constantCells,variableCells:variableCells};});},classifyRows_:function(unclassifiedRows){var rootRow=createEmptyRuleRow(CLASSIFICATION_RULES);unclassifiedRows.map(classifyRegionRow.bind(undefined,rootRow));pruneEmptyRuleRows(rootRow);tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,'constantCells');tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,'variableCells');return[rootRow];},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.TitleColumn('Mapped file');titleColumn.width='200px';var constantColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'constantCells');var variableColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'variableCells',this.aggregationMode_);var attributeColumns=constantColumns.concat(variableColumns);tr.ui.analysis.MemoryColumn.sortByImportance(attributeColumns,COLUMN_IMPORTANCE_RULES);tr.ui.analysis.MemoryColumn.spaceEqually(attributeColumns);var columns=[titleColumn].concat(attributeColumns);return columns;}});return{};});'use strict';Polymer('tr-ui-b-color-legend',{ready:function(){var blackSquareCharCode=9632;this.$.square.innerText=String.fromCharCode(blackSquareCharCode);this.label_=undefined;this.compoundEventSelectionState_=tr.model.CompoundEventSelectionState.NOT_SELECTED;},set compoundEventSelectionState(compoundEventSelectionState){this.compoundEventSelectionState_=compoundEventSelectionState;},get label(){return this.label_;},set label(label){if(label===undefined){this.setLabelAndColorId(undefined,undefined);return;}
-var colorId=tr.b.ColorScheme.getColorIdForGeneralPurposeString(label);this.setLabelAndColorId(label,colorId);},setLabelAndColorId:function(label,colorId){this.label_=label;this.$.label.textContent='';this.$.label.appendChild(tr.ui.b.asHTMLOrTextNode(label));if(colorId===undefined)
-this.$.square.style.color='initial';else
-this.$.square.style.color=tr.b.ColorScheme.colorsAsStrings[colorId];}});'use strict';Polymer('tr-ui-b-view-specific-brushing-state',{get viewId(){return this.getAttribute('view-id');},set viewId(viewId){this.setAttribute('view-id',viewId);},get:function(){var viewId=this.viewId;if(!viewId)
-throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
-return undefined;return brushingStateController.getViewSpecificBrushingState(viewId);},set:function(state){var viewId=this.viewId;if(!viewId)
-throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
-return;brushingStateController.changeViewSpecificBrushingState(viewId,state);}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ColorScheme=tr.b.ColorScheme;var USED_MEMORY_SIZE_COLUMNS_IMPORTANCE_RULES=tr.ui.analysis.MemoryColumn.columnNamesToImportanceRules(['Total resident','Peak total resident','PSS','Private dirty','Swapped']);var ALLOCATOR_SIZE_COLUMNS_IMPORTANCE_RULES=[{condition:'tracing',importance:0},{importance:1}];var DISPLAYED_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_ATTRIBUTE_NAME;var LINK_SYMBOL=String.fromCharCode(9903);var GREATER_THAN_OR_EQUAL_TO_SYMBOL=String.fromCharCode(8805);function ProcessNameColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
-ProcessNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(row.noLegend)
-return row.title;var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=row.title;return titleEl;}};Polymer('tr-ui-a-memory-dump-overview-pane',{created:function(){this.processMemoryDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.CELL;this.$.table.addEventListener('selection-changed',function(tableEvent){tableEvent.stopPropagation();this.changeChildPane_();}.bind(this));},set processMemoryDumps(processMemoryDumps){this.processMemoryDumps_=processMemoryDumps;this.scheduleRebuildPane_();},get processMemoryDumps(){return this.processMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},get selectedMemoryCell(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
-var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)
-return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)
-return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];var selectedMemoryCell=selectedColumn.cell(selectedTableRow);return selectedMemoryCell;},changeChildPane_:function(){this.storeSelection_();var builder=undefined;if(this.selectedMemoryCell!==undefined)
-builder=this.selectedMemoryCell.buildDetailsPane;this.childPaneBuilder=builder;},rebuildPane_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var footerRows=this.createFooterRows_(rows);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.tableColumns=columns;this.$.table.rebuild();this.restoreSelection_();},createRows_:function(){var timeToPidToProcessMemoryDump=this.processMemoryDumps_;var pidToTimeToProcessMemoryDump=tr.b.invertArrayOfDicts(timeToPidToProcessMemoryDump);var rows=[];var aggregationMode=this.aggregationMode_;return tr.b.dictionaryValues(tr.b.mapItems(pidToTimeToProcessMemoryDump,function(pid,timeToDump){var process=tr.b.findFirstInArray(timeToDump).process;var defined=timeToDump.map(function(dump){return dump!==undefined;});var timeToVmRegions=timeToDump.map(function(dump){if(dump===undefined)
-return undefined;return dump.mostRecentVmRegions;});function buildVmRegionsPane(){var pane=document.createElement('tr-ui-a-memory-dump-vm-regions-details-pane');pane.vmRegions=timeToVmRegions;pane.aggregationMode=aggregationMode;return pane;}
-var usedMemoryCells=tr.ui.analysis.createCells(timeToDump,function(dump){var sizes={};if(dump.totals!==undefined){tr.ui.analysis.addAttributeIfDefined(sizes,'Total resident',tr.model.ScalarAttribute,'bytes',dump.totals.residentBytes);tr.ui.analysis.addAttributeIfDefined(sizes,'Peak total resident',tr.model.ScalarAttribute,'bytes',dump.totals.peakResidentBytes,function(attr){if(dump.totals.arePeakResidentBytesResettable){attr.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.RECENT_VALUE,'Peak RSS since previous memory dump.'));}else{attr.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.OVERALL_VALUE,'Peak RSS since process startup. Finer grained '+'peaks require a Linux kernel version '+
-GREATER_THAN_OR_EQUAL_TO_SYMBOL+' 4.0.'));}});}
-var vmRegionAttributeAddedCallback=undefined;if(!dump.hasOwnVmRegions){vmRegionAttributeAddedCallback=function(attr){attr.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.LINK,'Older value (process did not dump memory maps).'));attr.isOlderValue=true;};}
-tr.ui.analysis.addAttributeIfDefined(sizes,'PSS',tr.model.ScalarAttribute,'bytes',dump.getMostRecentTotalVmRegionStat('proportionalResident'),vmRegionAttributeAddedCallback);tr.ui.analysis.addAttributeIfDefined(sizes,'Private dirty',tr.model.ScalarAttribute,'bytes',dump.getMostRecentTotalVmRegionStat('privateDirtyResident'),vmRegionAttributeAddedCallback);tr.ui.analysis.addAttributeIfDefined(sizes,'Swapped',tr.model.ScalarAttribute,'bytes',dump.getMostRecentTotalVmRegionStat('swapped'),vmRegionAttributeAddedCallback);return sizes;},function(attrName,cell){cell.buildDetailsPane=buildVmRegionsPane;});var allocatorCells=tr.ui.analysis.createCells(timeToDump,function(dump){if(dump.memoryAllocatorDumps===undefined)
-return undefined;var sizes={};dump.memoryAllocatorDumps.forEach(function(allocatorDump){var rootAttribute=allocatorDump.attributes[DISPLAYED_SIZE_ATTRIBUTE_NAME];if(rootAttribute===undefined)
-return;var allocatorName=allocatorDump.fullName;var overviewAttribute=new rootAttribute.constructor(rootAttribute.units,rootAttribute.value);if(dump.heapDumps!==undefined&&dump.heapDumps[allocatorName]!==undefined){overviewAttribute.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.HAS_HEAP_DUMP,'Heap dump provided'));}
-sizes[allocatorName]=overviewAttribute;});return sizes;},function(allocatorName,cell){var memoryAllocatorDumps=timeToDump.map(function(dump){if(dump===undefined)
-return undefined;return dump.getMemoryAllocatorDumpByFullName(allocatorName);});var heapDumps=undefined;timeToDump.forEach(function(dump,index){if(dump===undefined||dump.heapDumps===undefined)
-return;if(heapDumps===undefined)
-heapDumps=new Array(timeToDump.length);heapDumps[index]=dump.heapDumps[allocatorName];});cell.buildDetailsPane=function(){var pane=document.createElement('tr-ui-a-memory-dump-allocator-details-pane');pane.memoryAllocatorDumps=memoryAllocatorDumps;pane.heapDumps=heapDumps;pane.aggregationMode=aggregationMode;return pane;};});return{title:process.userFriendlyName,defined:defined,usedMemoryCells:usedMemoryCells,allocatorCells:allocatorCells};}));},createFooterRows_:function(rows){if(rows.length<=1)
-return[];var totalRow={title:'Total',noLegend:true};tr.ui.analysis.aggregateTableRowCells(totalRow,rows,'usedMemoryCells');tr.ui.analysis.aggregateTableRowCells(totalRow,rows,'allocatorCells');return[totalRow];},createColumns_:function(rows){var titleColumn=new ProcessNameColumn('Process');titleColumn.width='200px';var usedMemorySizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'usedMemoryCells',this.aggregationMode_);tr.ui.analysis.MemoryColumn.sortByImportance(usedMemorySizeColumns,USED_MEMORY_SIZE_COLUMNS_IMPORTANCE_RULES);var allocatorSizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'allocatorCells',this.aggregationMode_,function(allocatorName){var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=allocatorName;return titleEl;});tr.ui.analysis.MemoryColumn.sortByImportance(allocatorSizeColumns,ALLOCATOR_SIZE_COLUMNS_IMPORTANCE_RULES);var tracingColumn=tr.b.findFirstInArray(allocatorSizeColumns,function(column){return column.name==='tracing';});if(tracingColumn!==undefined){var tracingColumnColor=ColorScheme.getColorForReservedNameAsString('tracing_memory_column');tracingColumn.title=tr.ui.b.createSpan({textContent:'tracing',color:tracingColumnColor});tracingColumn.color=tracingColumnColor;}
-usedMemorySizeColumns.forEach(function(column){var olderUsedMCC=ColorScheme.getColorForReservedNameAsString('older_used_memory_column');var usedMCC=ColorScheme.getColorForReservedNameAsString('used_memory_column');column.title=tr.ui.b.createSpan({textContent:column.title,color:usedMCC});column.color=function(attrs){return attrs.length===1&&attrs[0].isOlderValue?olderUsedMCC:usedMCC;}});var sizeColumns=usedMemorySizeColumns.concat(allocatorSizeColumns);tr.ui.analysis.MemoryColumn.spaceEqually(sizeColumns);var columns=[titleColumn].concat(sizeColumns);return columns;},storeSelection_:function(){var selectedRowTitle;var selectedRow=this.$.table.selectedTableRow;if(selectedRow!==undefined)
-selectedRowTitle=selectedRow.title;var selectedColumnName;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex!==undefined){var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];selectedColumnName=selectedColumn.name;}
-this.$.state.set({rowTitle:selectedRowTitle,columnName:selectedColumnName});},restoreSelection_:function(){var settings=this.$.state.get();if(settings===undefined||settings.rowTitle===undefined||settings.columnName===undefined)
-return;var selectedColumnName=settings.columnName;var selectedColumnIndex=tr.b.findFirstIndexInArray(this.$.table.tableColumns,function(column){return column.name===selectedColumnName;});if(selectedColumnIndex<0)
-return;var selectedRowTitle=settings.rowTitle;var selectedRow=tr.b.findFirstInArray(this.$.table.tableRows,function(row){return row.title===selectedRowTitle;});if(selectedRow===undefined)
-return;this.$.table.selectedTableRow=selectedRow;this.$.table.selectedColumnIndex=selectedColumnIndex;}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-memory-dump-header-pane',{created:function(){this.containerMemoryDumps_=undefined;},ready:function(){this.$.aggregation_mode_container.appendChild(tr.ui.b.createSelector(this,'aggregationMode','memoryDumpHeaderPane.aggregationMode',tr.ui.analysis.MemoryColumn.AggregationMode.DIFF,[{label:'Diff',value:tr.ui.analysis.MemoryColumn.AggregationMode.DIFF},{label:'Max',value:tr.ui.analysis.MemoryColumn.AggregationMode.MAX}]));},set containerMemoryDumps(containerMemoryDumps){this.containerMemoryDumps_=containerMemoryDumps;this.scheduleRebuildPane_();},get containerMemoryDumps(){return this.containerMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){this.updateLabel_();this.updateAggregationModeSelector_();this.changeChildPane_();},updateLabel_:function(){this.$.label.textContent='';if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){this.$.label.textContent='No memory dumps selected';return;}
-var containerDumpCount=this.containerMemoryDumps_.length;var isMultiSelection=containerDumpCount>1;this.$.label.appendChild(document.createTextNode('Selected '+containerDumpCount+' memory dump'+
-(isMultiSelection?'s':'')+' in '+this.containerMemoryDumps_[0].containerName+' at '));this.$.label.appendChild(document.createTextNode(tr.b.u.TimeStamp.format(this.containerMemoryDumps_[0].start)));if(isMultiSelection){var ELLIPSIS=String.fromCharCode(8230);this.$.label.appendChild(document.createTextNode(ELLIPSIS));this.$.label.appendChild(document.createTextNode(tr.b.u.TimeStamp.format(this.containerMemoryDumps_[containerDumpCount-1].start)));}},updateAggregationModeSelector_:function(){var displayStyle;if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=1)
-displayStyle='none';else
-displayStyle='initial';this.$.aggregation_mode_container.style.display=displayStyle;},changeChildPane_:function(){this.childPaneBuilder=function(){if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0)
-return undefined;var overviewPane=document.createElement('tr-ui-a-memory-dump-overview-pane');overviewPane.processMemoryDumps=this.containerMemoryDumps_.map(function(containerDump){return containerDump.processMemoryDumps;});overviewPane.aggregationMode=this.aggregationMode;return overviewPane;}.bind(this);}});return{};});'use strict';Polymer('tr-ui-a-stacked-pane-view',{setPaneBuilder:function(paneBuilder,opt_parentPane){var paneContainer=this.$.pane_container;if(opt_parentPane){if(!(opt_parentPane instanceof HTMLElement))
-throw new Error('Parent pane must be an HTML element');if(opt_parentPane.parentElement!==paneContainer)
-throw new Error('Parent pane must be a child of the pane container');}
-while(paneContainer.lastElementChild!==null&&paneContainer.lastElementChild!==opt_parentPane){var removedPane=this.$.pane_container.lastElementChild;var listener=this.listeners_.get(removedPane);if(listener===undefined)
-throw new Error('No listener associated with pane');this.listeners_.delete(removedPane);removedPane.removeEventListener('request-child-pane-change',listener);paneContainer.removeChild(removedPane);}
-if(opt_parentPane&&opt_parentPane.parentElement!==paneContainer)
-throw new Error('Parent pane was removed from the pane container');if(!paneBuilder)
-return;var pane=paneBuilder();if(!pane)
-return;if(!(pane instanceof HTMLElement))
-throw new Error('Pane must be an HTML element');var listener=function(event){this.setPaneBuilder(pane.childPaneBuilder,pane);}.bind(this);if(!this.listeners_){this.listeners_=new WeakMap();}
-this.listeners_.set(pane,listener);pane.addEventListener('request-child-pane-change',listener);paneContainer.appendChild(pane);pane.appended();},rebuild:function(){var currentPane=this.$.pane_container.firstElementChild;while(currentPane){currentPane.rebuild();currentPane=currentPane.nextElementSibling;}},get panesForTesting(){var panes=[];var currentChild=this.$.pane_container.firstElementChild;while(currentChild){panes.push(currentChild);currentChild=currentChild.nextElementSibling;}
-return panes;}});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-container-memory-dump-sub-view',{set selection(selection){if(selection===undefined){this.currentSelection_=undefined;this.dumpsByContainerName_=undefined;this.updateContents_();return;}
-selection.forEach(function(event){if(!(event instanceof tr.model.ContainerMemoryDump)){throw new Error('Memory dump sub-view only supports container memory dumps');}});this.currentSelection_=selection;this.dumpsByContainerName_=tr.b.group(this.currentSelection_.toArray(),function(dump){return dump.containerName;});tr.b.iterItems(this.dumpsByContainerName_,function(containerName,dumps){dumps.sort(function(a,b){return a.start-b.start;});});this.updateContents_();},get selection(){return this.currentSelection_;},get requiresTallView(){return true;},updateContents_:function(){this.$.content.textContent='';if(this.dumpsByContainerName_===undefined)
-return;var containerNames=Object.keys(this.dumpsByContainerName_);if(containerNames.length===0)
-return;if(containerNames.length>1)
-this.buildViewForMultipleContainerNames_();else
-this.buildViewForSingleContainerName_();},buildViewForSingleContainerName_:function(){var containerMemoryDumps=this.currentSelection_;var dumpView=this.ownerDocument.createElement('tr-ui-a-stacked-pane-view');this.$.content.appendChild(dumpView);dumpView.setPaneBuilder(function(){var headerPane=document.createElement('tr-ui-a-memory-dump-header-pane');headerPane.containerMemoryDumps=containerMemoryDumps;return headerPane;});},buildViewForMultipleContainerNames_:function(){var ownerDocument=this.ownerDocument;var rows=tr.b.dictionaryValues(tr.b.mapItems(this.dumpsByContainerName_,function(containerName,dumps){return{containerName:containerName,subRows:dumps,isExpanded:true};}));rows.sort(function(a,b){return a.containerName.localeCompare(b.containerName);});var columns=[{title:'Dump',value:function(row){if(row.subRows===undefined)
-return this.singleDumpValue_(row);else
-return this.groupedDumpValue_(row);},singleDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([row]));linkEl.appendChild(tr.ui.units.createTimeStampSpan(row.start,{ownerDocument:ownerDocument}));return linkEl;},groupedDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(row.subRows));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.subRows.length+' memory dump'+
-(row.subRows.length===1?'':'s')+' in '}));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.containerName,bold:true}));return linkEl;}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.tableColumns=columns;table.tableRows=rows;table.showHeader=false;table.rebuild();this.$.content.appendChild(table);}});return{};});'use strict';var EventSet=tr.model.EventSet;Polymer('tr-ui-a-power-sample-table',{ready:function(){this.$.table.tableColumns=[{title:'Time',width:'100px',value:function(row){return tr.ui.units.createTimeStampSpan(row.start);}},{title:'Power (mW)',width:'100%',value:function(row){return row.power;}}];this.samples=new EventSet();},get samples(){return this.samples_;},set samples(samples){this.samples_=(samples===undefined)?new EventSet():samples;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.samples.toArray();this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-single-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.samplesTable.samples=this.selection;}});!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function T(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function z(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o,a=0,c=0,s=0;if(u=/([a-z]+)\((.*)\)/i.exec(n))switch(i=u[2].split(","),u[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(o=Va.get(n))?t(o.r,o.g,o.b):(null!=n&&"#"===n.charAt(0)&&(r=parseInt(n.substring(1),16),isNaN(r)||(4===n.length?(a=(3840&r)>>4,a=a>>4|a,c=240&r,c=c>>4|c,s=15&r,s=s<<4|s):7===n.length&&(a=(16711680&r)>>16,c=(65280&r)>>8,s=255&r))),t(a,c,s))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Xo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function zt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=zt;var r=new zt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=zt;var r=new zt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==zt,o=new(i?zt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=zt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=zt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);hc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Sa,k=p*x;if(hc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*ka:_,S^h>=e^m>=e){var E=fe(se(f),se(n));pe(E);var A=fe(u,E);pe(A);var C=(S^_>=0?-1:1)*X(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ze(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),Tc>t&&(Tc=t),t>zc&&(zc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||oa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function Tr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function zr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),zr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(zu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function zu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function Ti(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():zi(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=zi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=zi(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return zi(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function To(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function zo(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=zi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=zi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.3"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=Sizzle,va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={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/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=T(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=T(o);for(;f>r;++r)p[r]=T(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=z.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,Ta=Math.SQRT2,qa=2,za=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(Ta*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(Ta*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+za*f)/(2*i*qa*h),p=(c*c-i*i-za*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ta;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,T,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({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,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});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv("	","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;zt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",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"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,Te,ze,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,Tc,qc,zc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=zc=-(Lc=Tc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,Tc],[qc,zc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},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()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ti,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ti(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ti:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(To(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=zo,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),T=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",y):T.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(Math.ceil(n/e)*e,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var svgNS='http://www.w3.org/2000/svg';var ColorScheme=tr.b.ColorScheme;function getColorOfKey(key,selected){var id=ColorScheme.getColorIdForGeneralPurposeString(key);if(selected)
-id+=ColorScheme.properties.brightenedOffsets[0];return ColorScheme.colorsAsStrings[id];}
-var ChartBase=tr.ui.b.define('svg',undefined,svgNS);ChartBase.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.classList.add('chart-base');this.chartTitle_=undefined;this.seriesKeys_=undefined;this.width_=400;this.height_=300;var template=THIS_DOC.querySelector('#chart-base-template');var svgEl=template.content.querySelector('svg');for(var i=0;i<svgEl.children.length;i++)
-this.appendChild(svgEl.children[i].cloneNode(true));Object.defineProperty(this,'width',{get:function(){return this.width_;},set:function(width){this.width_=width;this.updateContents_();}});Object.defineProperty(this,'height',{get:function(){return this.height_;},set:function(height){this.height_=height;this.updateContents_();}});},get chartTitle(){return this.chartTitle_;},set chartTitle(chartTitle){this.chartTitle_=chartTitle;this.updateContents_();},get chartAreaElement(){return this.querySelector('#chart-area');},setSize:function(size){this.width_=size.width;this.height_=size.height;this.updateContents_();},getMargin_:function(){var margin={top:20,right:20,bottom:30,left:50};if(this.chartTitle_)
-margin.top+=20;return margin;},get margin(){return this.getMargin_();},get chartAreaSize(){var margin=this.margin;return{width:this.width_-margin.left-margin.right,height:this.height_-margin.top-margin.bottom};},getLegendKeys_:function(){throw new Error('Not implemented');},updateScales_:function(){throw new Error('Not implemented');},updateContents_:function(){var margin=this.margin;var thisSel=d3.select(this);thisSel.attr('width',this.width_);thisSel.attr('height',this.height_);var chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.attr('transform','translate('+margin.left+','+margin.top+')');this.updateScales_();this.updateTitle_(chartAreaSel);this.updateLegend_();},updateTitle_:function(chartAreaSel){var titleSel=chartAreaSel.select('#title');if(!this.chartTitle_){titleSel.style('display','none');return;}
-var width=this.chartAreaSize.width;titleSel.attr('transform','translate('+width*0.5+',-5)').style('display',undefined).style('text-anchor','middle').attr('class','title').attr('width',width).text(this.chartTitle_);},updateLegend_:function(){var keys=this.getLegendKeys_();if(keys===undefined)
-return;var chartAreaSel=d3.select(this.chartAreaElement);var chartAreaSize=this.chartAreaSize;var legendEntriesSel=chartAreaSel.selectAll('.legend').data(keys.slice().reverse());legendEntriesSel.enter().append('g').attr('class','legend').attr('transform',function(d,i){return'translate(0,'+i*20+')';}).append('text').text(function(key){return key;});legendEntriesSel.exit().remove();legendEntriesSel.attr('x',chartAreaSize.width-18).attr('width',18).attr('height',18).style('fill',function(key){var selected=this.currentHighlightedLegendKey===key;return getColorOfKey(key,selected);}.bind(this));legendEntriesSel.selectAll('text').attr('x',chartAreaSize.width-24).attr('y',9).attr('dy','.35em').style('text-anchor','end').text(function(d){return d;});},get highlightedLegendKey(){return this.highlightedLegendKey_;},set highlightedLegendKey(highlightedLegendKey){this.highlightedLegendKey_=highlightedLegendKey;this.updateHighlight_();},get currentHighlightedLegendKey(){if(this.tempHighlightedLegendKey_)
-return this.tempHighlightedLegendKey_;return this.highlightedLegendKey_;},pushTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_)
-throw new Error('push cannot nest');this.tempHighlightedLegendKey_=key;this.updateHighlight_();},popTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_!=key)
-throw new Error('pop cannot happen');this.tempHighlightedLegendKey_=undefined;this.updateHighlight_();},updateHighlight_:function(){var chartAreaSel=d3.select(this.chartAreaElement);var legendEntriesSel=chartAreaSel.selectAll('.legend');var that=this;legendEntriesSel.each(function(key){var highlighted=key==that.currentHighlightedLegendKey;var color=getColorOfKey(key,highlighted);this.style.fill=color;if(highlighted)
-this.style.fontWeight='bold';else
-this.style.fontWeight='';});}};return{getColorOfKey:getColorOfKey,ChartBase:ChartBase};});'use strict';tr.exportTo('tr.ui.b',function(){function MouseTracker(opt_targetElement){this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.targetElement=opt_targetElement;}
-MouseTracker.prototype={get targetElement(){return this.targetElement_;},set targetElement(targetElement){if(this.targetElement_)
-this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);this.targetElement_=targetElement;if(this.targetElement_)
-this.targetElement_.addEventListener('mousedown',this.onMouseDown_);},onMouseDown_:function(e){if(e.button!==0)
-return true;e=this.remakeEvent_(e,'mouse-tracker-start');this.targetElement_.dispatchEvent(e);document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);this.targetElement_.addEventListener('blur',this.onMouseUp_);this.savePreviousUserSelect_=document.body.style['-webkit-user-select'];document.body.style['-webkit-user-select']='none';e.preventDefault();return true;},onMouseMove_:function(e){e=this.remakeEvent_(e,'mouse-tracker-move');this.targetElement_.dispatchEvent(e);},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);this.targetElement_.removeEventListener('blur',this.onMouseUp_);document.body.style['-webkit-user-select']=this.savePreviousUserSelect_;e=this.remakeEvent_(e,'mouse-tracker-end');this.targetElement_.dispatchEvent(e);},remakeEvent_:function(e,newType){var remade=new tr.b.Event(newType,true,true);remade.x=e.x;remade.y=e.y;remade.offsetX=e.offsetX;remade.offsetY=e.offsetY;remade.clientX=e.clientX;remade.clientY=e.clientY;return remade;}};function trackMouseMovesUntilMouseUp(mouseMoveHandler,opt_mouseUpHandler,opt_keyUpHandler){function cleanupAndDispatchToMouseUp(e){document.removeEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
-document.removeEventListener('keyup',opt_keyUpHandler);document.removeEventListener('mouseup',cleanupAndDispatchToMouseUp);if(opt_mouseUpHandler)
-opt_mouseUpHandler(e);}
-document.addEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
-document.addEventListener('keyup',opt_keyUpHandler);document.addEventListener('mouseup',cleanupAndDispatchToMouseUp);}
-return{MouseTracker:MouseTracker,trackMouseMovesUntilMouseUp:trackMouseMovesUntilMouseUp};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var ChartBase2D=tr.ui.b.define('chart-base-2d',ChartBase);ChartBase2D.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('chart-base-2d');this.xScale_=d3.scale.linear();this.yScale_=d3.scale.linear();this.data_=[];this.seriesKeys_=[];this.leftMargin_=50;d3.select(this.chartAreaElement).append('g').attr('id','brushes');d3.select(this.chartAreaElement).append('g').attr('id','series');this.addEventListener('mousedown',this.onMouseDown_.bind(this));},get data(){return this.data_;},set data(data){if(data===undefined)
-throw new Error('data must be an Array');this.data_=data;this.updateSeriesKeys_();this.updateContents_();},getSampleWidth_:function(data,index,leftSide){var leftIndex,rightIndex;if(leftSide){leftIndex=Math.max(index-1,0);rightIndex=index;}else{leftIndex=index;rightIndex=Math.min(index+1,data.length-1);}
-var leftWidth=this.getXForDatum_(data[index],index)-
-this.getXForDatum_(data[leftIndex],leftIndex);var rightWidth=this.getXForDatum_(data[rightIndex],rightIndex)-
-this.getXForDatum_(data[index],index);return leftWidth*0.5+rightWidth*0.5;},getLegendKeys_:function(){if(this.seriesKeys_&&this.seriesKeys_.length>1)
-return this.seriesKeys_.slice();return[];},updateSeriesKeys_:function(){var keySet={};this.data_.forEach(function(datum){Object.keys(datum).forEach(function(key){if(this.isDatumFieldSeries_(key))
-keySet[key]=true;},this);},this);this.seriesKeys_=Object.keys(keySet);},isDatumFieldSeries_:function(fieldName){throw new Error('Not implemented');},getXForDatum_:function(datum,index){throw new Error('Not implemented');},updateScales_:function(){if(this.data_.length===0)
-return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;this.xScale_.range([0,width]);this.xScale_.domain(d3.extent(this.data_,this.getXForDatum_.bind(this)));var yRange=new tr.b.Range();this.data_.forEach(function(datum){this.seriesKeys_.forEach(function(key){if(datum[key]!==undefined)
-yRange.addValue(datum[key]);});},this);this.yScale_.range([height,0]);this.yScale_.domain([yRange.min,yRange.max]);},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();},updateXAxis_:function(xAxis){xAxis.selectAll('*').remove();xAxis[0][0].style.opacity=0;xAxis.attr('transform','translate(0,'+this.chartAreaSize.height+')').call(d3.svg.axis().scale(this.xScale_).orient('bottom'));window.requestAnimationFrame(function(){var previousRight=undefined;xAxis.selectAll('.tick')[0].forEach(function(tick){var currentLeft=tick.transform.baseVal[0].matrix.e;if((previousRight===undefined)||(currentLeft>(previousRight+3))){var currentWidth=tick.getBBox().width;previousRight=currentLeft+currentWidth;}else{tick.style.opacity=0;}});xAxis[0][0].style.opacity=1;});},getMargin_:function(){var margin=ChartBase.prototype.getMargin_.call(this);margin.left=this.leftMargin_;return margin;},updateYAxis_:function(yAxis){yAxis.selectAll('*').remove();yAxis[0][0].style.opacity=0;yAxis.call(d3.svg.axis().scale(this.yScale_).orient('left'));window.requestAnimationFrame(function(){var previousTop=undefined;var leftMargin=0;yAxis.selectAll('.tick')[0].forEach(function(tick){var bbox=tick.getBBox();leftMargin=Math.max(leftMargin,bbox.width);var currentTop=tick.transform.baseVal[0].matrix.f;var currentBottom=currentTop+bbox.height;if((previousTop===undefined)||(previousTop>(currentBottom+3))){previousTop=currentTop;}else{tick.style.opacity=0;}});if(leftMargin>this.leftMargin_){this.leftMargin_=leftMargin;this.updateContents_();}else{yAxis[0][0].style.opacity=1;}}.bind(this));},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);var chartAreaSel=d3.select(this.chartAreaElement);this.updateXAxis_(chartAreaSel.select('.x.axis'));this.updateYAxis_(chartAreaSel.select('.y.axis'));this.updateBrushContents_(chartAreaSel.select('#brushes'));this.updateDataContents_(chartAreaSel.select('#series'));},updateDataContents_:function(seriesSel){throw new Error('Not implemented');},getDataBySeriesKey_:function(){var dataBySeriesKey={};this.seriesKeys_.forEach(function(seriesKey){dataBySeriesKey[seriesKey]=[];});this.data_.forEach(function(multiSeriesDatum,index){var x=this.getXForDatum_(multiSeriesDatum,index);d3.keys(multiSeriesDatum).forEach(function(seriesKey){if(seriesKey==='x')
-return;if(multiSeriesDatum[seriesKey]===undefined)
-return;var singleSeriesDatum={x:x};singleSeriesDatum[seriesKey]=multiSeriesDatum[seriesKey];dataBySeriesKey[seriesKey].push(singleSeriesDatum);});},this);return dataBySeriesKey;},getDataPointAtClientPoint_:function(clientX,clientY){var rect=this.getBoundingClientRect();var margin=this.margin;var x=clientX-rect.left-margin.left;var y=clientY-rect.top-margin.top;x=this.xScale_.invert(x);y=this.yScale_.invert(y);x=tr.b.clamp(x,this.xScale_.domain()[0],this.xScale_.domain()[1]);y=tr.b.clamp(y,this.yScale_.domain()[0],this.yScale_.domain()[1]);return{x:x,y:y};},prepareDataEvent_:function(mouseEvent,dataEvent){var dataPoint=this.getDataPointAtClientPoint_(mouseEvent.clientX,mouseEvent.clientY);dataEvent.x=dataPoint.x;dataEvent.y=dataPoint.y;},onMouseDown_:function(mouseEvent){tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_.bind(this,mouseEvent.button),this.onMouseUp_.bind(this,mouseEvent.button));mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mousedown');dataEvent.button=mouseEvent.button;this.classList.add('updating-brushing-state');this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseMove_:function(button,mouseEvent){if(mouseEvent.buttons!==undefined){mouseEvent.preventDefault();mouseEvent.stopPropagation();}
-var dataEvent=new tr.b.Event('item-mousemove');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseUp_:function(button,mouseEvent){mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mouseup');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);this.classList.remove('updating-brushing-state');}};return{ChartBase2D:ChartBase2D};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2D=tr.ui.b.ChartBase2D;var ChartBase2DBrushX=tr.ui.b.define('chart-base-2d-brush-1d',ChartBase2D);ChartBase2DBrushX.prototype={__proto__:ChartBase2D.prototype,decorate:function(){ChartBase2D.prototype.decorate.call(this);this.brushedRange_=new tr.b.Range();},set brushedRange(range){this.brushedRange_.reset();this.brushedRange_.addRange(range);this.updateContents_();},computeBrushRangeFromIndices:function(indexA,indexB){indexA=tr.b.clamp(indexA,0,this.data_.length-1);indexB=tr.b.clamp(indexB,0,this.data_.length-1);var leftIndex=Math.min(indexA,indexB);var rightIndex=Math.max(indexA,indexB);var r=new tr.b.Range();r.addValue(this.getXForDatum_(this.data_[leftIndex],leftIndex)-
-this.getSampleWidth_(this.data_,leftIndex,true));r.addValue(this.getXForDatum_(this.data_[rightIndex],rightIndex)+
-this.getSampleWidth_(this.data_,rightIndex,false));return r;},getDataIndex_:function(dataX){if(!this.data_)
-return undefined;var bisect=d3.bisector(this.getXForDatum_.bind(this)).right;return bisect(this.data_,dataX)-1;},prepareDataEvent_:function(mouseEvent,dataEvent){ChartBase2D.prototype.prepareDataEvent_.call(this,mouseEvent,dataEvent);dataEvent.index=this.getDataIndex_(dataEvent.x);if(dataEvent.index!==undefined)
-dataEvent.data=this.data_[dataEvent.index];},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();var brushes=this.brushedRange_.isEmpty?[]:[this.brushedRange_];var brushRectsSel=brushSel.selectAll('rect').data(brushes);brushRectsSel.enter().append('rect');brushRectsSel.exit().remove();brushRectsSel.attr('x',function(d){return this.xScale_(d.min);}.bind(this)).attr('y',0).attr('width',function(d){return this.xScale_(d.max)-this.xScale_(d.min);}.bind(this)).attr('height',this.chartAreaSize.height);}};return{ChartBase2DBrushX:ChartBase2DBrushX};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2DBrushX=tr.ui.b.ChartBase2DBrushX;var LineChart=tr.ui.b.define('line-chart',ChartBase2DBrushX);LineChart.prototype={__proto__:ChartBase2DBrushX.prototype,decorate:function(){ChartBase2DBrushX.prototype.decorate.call(this);this.classList.add('line-chart');},isDatumFieldSeries_:function(fieldName){return fieldName!='x';},getXForDatum_:function(datum,index){return datum.x;},updateDataContents_:function(dataSel){dataSel.selectAll('*').remove();var dataBySeriesKey=this.getDataBySeriesKey_();var pathsSel=dataSel.selectAll('path').data(this.seriesKeys_);pathsSel.enter().append('path').attr('class','line').style('stroke',function(key){return tr.ui.b.getColorOfKey(key);}).attr('d',function(key){var line=d3.svg.line().x(function(d){return this.xScale_(d.x);}.bind(this)).y(function(d){return this.yScale_(d[key]);}.bind(this));return line(dataBySeriesKey[key]);}.bind(this));pathsSel.exit().remove();}};return{LineChart:LineChart};});'use strict';var EventSet=tr.model.EventSet;var CHART_TITLE='Power (in mW) by ms since vertical sync';var CHART_WIDTH_FRACTION_OF_BODY=0.5;Polymer('tr-ui-a-frame-power-usage-chart',{ready:function(){this.chart_=undefined;this.samples_=new EventSet();this.vSyncTimestamps_=[];},get chart(){return this.chart_;},get samples(){return this.samples_;},get vSyncTimestamps(){return this.vSyncTimestamps_;},setData:function(samples,vSyncTimestamps){this.samples_=(samples===undefined)?new EventSet():samples;this.vSyncTimestamps_=(vSyncTimestamps===undefined)?[]:vSyncTimestamps;this.updateContents_();},updateContents_:function(){this.clearChart_();var data=this.getDataForLineChart_();if(data.length===0)
-return;this.chart_=this.createChart_(data);this.$.content.appendChild(this.chart_);},createChart_:function(data){var chart=new tr.ui.b.LineChart();var width=document.body.clientWidth*CHART_WIDTH_FRACTION_OF_BODY;chart.setSize({width:width,height:chart.height});chart.chartTitle=CHART_TITLE;chart.data=data;return chart;},clearChart_:function(){var content=this.$.content;while(content.firstChild)
-content.removeChild(content.firstChild);this.chart_=undefined;},getDataForLineChart_:function(){var sortedSamples=this.sortSamplesByTimestampAscending_(this.samples);var vSyncTimestamps=this.vSyncTimestamps.slice();var lastVSyncTimestamp=undefined;var points=[];var frameNumber=0;sortedSamples.forEach(function(sample){while(vSyncTimestamps.length>0&&vSyncTimestamps[0]<=sample.start){lastVSyncTimestamp=vSyncTimestamps.shift();frameNumber++;}
-if(lastVSyncTimestamp===undefined)
-return;var point={x:sample.start-lastVSyncTimestamp};point['f'+frameNumber]=sample.power;points.push(point);});return points;},sortSamplesByTimestampAscending_:function(samples){return samples.toArray().sort(function(smpl1,smpl2){return smpl1.start-smpl2.start;});}});'use strict';Polymer('tr-ui-a-power-sample-summary-table',{ready:function(){this.$.table.tableColumns=[{title:'Min power',width:'100px',value:function(row){return tr.b.u.Units.powerInWatts.format(row.min/1000.0);}},{title:'Max power',width:'100px',value:function(row){return tr.b.u.Units.powerInWatts.format(row.max/1000.0);}},{title:'Time-weighted average',width:'100px',value:function(row){return tr.b.u.Units.powerInWatts.format(row.timeWeightedAverage/1000.0);}},{title:'Energy consumed',width:'100px',value:function(row){return tr.b.u.Units.energyInJoules.format(row.energyConsumed);}},{title:'Sample count',width:'100%',value:function(row){return row.sampleCount;}}];this.samples=new tr.model.EventSet();},get samples(){return this.samples_;},set samples(samples){if(samples===this.samples)
-return;this.samples_=(samples===undefined)?new tr.model.EventSet():samples;this.updateContents_();},updateContents_:function(){if(this.samples.length===0){this.$.table.tableRows=[];}else{this.$.table.tableRows=[{min:this.getMin(),max:this.getMax(),timeWeightedAverage:this.getTimeWeightedAverage(),energyConsumed:this.getEnergyConsumed(),sampleCount:this.samples.length}];}
-this.$.table.rebuild();},getMin:function(){return Math.min.apply(null,this.samples.map(function(sample){return sample.power;}));},getMax:function(){return Math.max.apply(null,this.samples.map(function(sample){return sample.power;}));},getTimeWeightedAverage:function(){var energyConsumed=this.getEnergyConsumed();if(energyConsumed==='N/A')
-return'N/A';return this.getEnergyConsumed()/this.samples.bounds.duration*1000;},getEnergyConsumed:function(){if(this.samples.length<2)
-return'N/A';var bounds=this.samples.bounds;return this.samples[0].series.getEnergyConsumed(bounds.min,bounds.max);}});'use strict';Polymer('tr-ui-a-multi-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){var samples=this.selection;var vSyncTimestamps=(this.selection===undefined)?[]:this.selection[0].series.device.vSyncTimestamps;this.$.summaryTable.samples=samples;this.$.samplesTable.samples=samples;this.$.chart.setData(this.selection,vSyncTimestamps);}});'use strict';(function(){var EventRegistry=tr.model.EventRegistry;Polymer('tr-ui-a-analysis-view',{ready:function(){this.tabView_=document.createElement('tr-ui-a-tab-view');this.tabView_.style.flex='1 1 auto';this.appendChild(this.tabView_);this.brushingStateController_=undefined;this.onSelectedTabChange_=this.onSelectedTabChange_.bind(this);this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.lastSeenSelection_=new tr.model.EventSet();},set tallMode(value){if(value)
-this.classList.add('tall-mode');else
-this.classList.remove('tall-mode');},get tallMode(){return this.classList.contains('tall-mode');},get tabView(){return this.tabView_;},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}
-this.onSelectionChanged_();},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(e){var selection=this.brushingStateController_.selection;var selectionHasSameValue=this.lastSeenSelection_.equals(selection);this.lastSeenSelection_=selection;if(selectionHasSameValue)
-return;var lastSelectedTabTagName;var lastSelectedTabTypeName;if(this.tabView_.selectedTab){lastSelectedTabTagName=this.tabView_.selectedTab.tagName;lastSelectedTabTypeName=this.tabView_.selectedTab._eventTypeName;}
-this.tallMode=false;var previouslySelectedTab=this.tabView_.selectedTab;this.tabView_.removeEventListener('selected-tab-change',this.onSelectedTabChange_);var previousSubViews={};for(var i=0;i<this.tabView_.children.length;i++){var previousSubView=this.tabView_.children[i];previousSubViews[previousSubView._eventTypeName]=previousSubView;}
-this.tabView_.saveTabStates();this.tabView_.textContent='';if(selection.length==0){this.tabView_.tabStripHeadingText='Nothing selected. Tap stuff.';}else if(selection.length==1){this.tabView_.tabStripHeadingText='1 item selected: ';}else{this.tabView_.tabStripHeadingText=selection.length+' items selected: ';}
-var eventsByBaseTypeName=selection.getEventsOrganizedByBaseType(true);var numBaseTypesToAnalyze=tr.b.dictionaryLength(eventsByBaseTypeName);for(var eventTypeName in eventsByBaseTypeName){var subSelection=eventsByBaseTypeName[eventTypeName];var subView=this.createSubViewForSelection_(eventTypeName,subSelection,previousSubViews[eventTypeName]);subView._eventTypeName=eventTypeName;this.tabView_.appendChild(subView);subView.selection=subSelection;}
-var tab;if(lastSelectedTabTagName)
-tab=this.tabView_.querySelector(lastSelectedTabTagName);if(!tab&&lastSelectedTabTypeName){var tab=tr.b.findFirstInArray(this.tabView_.children,function(tab){return tab._eventTypeName===lastSelectedTabTypeName;});}
-if(!tab)
-tab=this.tabView_.firstChild;this.tabView_.selectedTab=tab;this.onSelectedTabChange_();this.tabView_.addEventListener('selected-tab-change',this.onSelectedTabChange_);},createSubViewForSelection_:function(eventTypeName,subSelection,previousSubView){var eventTypeInfo=EventRegistry.getEventTypeInfoByTypeName(eventTypeName);var singleMode=subSelection.length==1;var tagName;if(subSelection.length===1)
-tagName=eventTypeInfo.metadata.singleViewElementName;else
-tagName=eventTypeInfo.metadata.multiViewElementName;if(!tr.ui.b.getPolymerElementNamed(tagName))
-throw new Error('Element not registered: '+tagName);var subView;if(previousSubView&&previousSubView.tagName===tagName.toUpperCase())
-subView=previousSubView;else
-subView=document.createElement(tagName);var camelLabel;if(subSelection.length===1)
-camelLabel=EventRegistry.getUserFriendlySingularName(eventTypeName);else
-camelLabel=EventRegistry.getUserFriendlyPluralName(eventTypeName);subView.tabLabel=camelLabel+' ('+subSelection.length+')';return subView;},onSelectedTabChange_:function(){var brushingStateController=this.brushingStateController_;if(this.tabView_.selectedTab){var selectedTab=this.tabView_.selectedTab;this.tallMode=selectedTab.requiresTallView;if(brushingStateController){var rlth=selectedTab.relatedEventsToHighlight;brushingStateController.changeAnalysisViewRelatedEvents(rlth);}}else{this.tallMode=false;if(brushingStateController)
-brushingStateController.changeAnalysisViewRelatedEvents(undefined);}}});})();'use strict';tr.exportTo('tr.ui.b',function(){var DragHandle=tr.ui.b.define('x-drag-handle');DragHandle.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.lastMousePos_=0;this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.target_=undefined;this.horizontal=true;this.observer_=new WebKitMutationObserver(this.didTargetMutate_.bind(this));this.targetSizesByModeKey_={};},get modeKey_(){return this.target_.className==''?'.':this.target_.className;},get target(){return this.target_;},set target(target){this.observer_.disconnect();this.target_=target;if(!this.target_)
+indentSpan.textContent+=' ';row.appendChild(indentSpan);var labelSpan=document.createElement('span');labelSpan.textContent=label;row.appendChild(labelSpan);row.appendChild(dataElement);var suffixSpan=document.createElement('span');suffixSpan.textContent=suffix;row.appendChild(suffixSpan);row.dataElement=dataElement;this.$.content.appendChild(row);},appendSimpleText_:function(label,indent,text,suffix){var el=this.ownerDocument.createElement('span');el.textContent=text;this.appendElementWithLabel_(label,indent,el,suffix);return el;}});'use strict';Polymer('tr-ui-a-generic-object-view-with-label',{ready:function(){this.labelEl_=document.createElement('div');this.genericObjectView_=document.createElement('tr-ui-a-generic-object-view');this.shadowRoot.appendChild(this.labelEl_);this.shadowRoot.appendChild(this.genericObjectView_);},get label(){return this.labelEl_.textContent;},set label(label){this.labelEl_.textContent=label;},get object(){return this.genericObjectView_.object;},set object(object){this.genericObjectView_.object=object;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectSnapshotView=tr.ui.b.define('object-snapshot-view');ObjectSnapshotView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectSnapshot_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectSnapshot=obj;},get modelEvent(){return this.objectSnapshot;},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(i){this.objectSnapshot_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshotView;options.defaultMetadata={showInstances:true,showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectSnapshotView,options);return{ObjectSnapshotView:ObjectSnapshotView};});'use strict';Polymer('tr-ui-b-drag-handle',{__proto__:HTMLDivElement.prototype,created:function(){this.lastMousePos_=0;this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.target_=undefined;this.horizontal=true;this.observer_=new WebKitMutationObserver(this.didTargetMutate_.bind(this));this.targetSizesByModeKey_={};},get modeKey_(){return this.target_.className==''?'.':this.target_.className;},get target(){return this.target_;},set target(target){this.observer_.disconnect();this.target_=target;if(!this.target_)
 return;this.observer_.observe(this.target_,{attributes:true,attributeFilter:['class']});},get horizontal(){return this.horizontal_;},set horizontal(h){this.horizontal_=h;if(this.horizontal_)
 this.className='horizontal-drag-handle';else
 this.className='vertical-drag-handle';},get vertical(){return!this.horizontal_;},set vertical(v){this.horizontal=!v;},forceMutationObserverFlush_:function(){var records=this.observer_.takeRecords();if(records.length)
@@ -5758,25 +5825,18 @@
 this.target_.style[this.targetStyleKey_]='';},get targetStyleKey_(){return this.horizontal_?'height':'width';},getTargetSize_:function(){var targetStyleKey=this.targetStyleKey_;if(!this.target_.style[targetStyleKey]){this.target_.style[targetStyleKey]=window.getComputedStyle(this.target_)[targetStyleKey];}
 var size=parseInt(this.target_.style[targetStyleKey]);this.targetSizesByModeKey_[this.modeKey_]=size;return size;},setTargetSize_:function(s){this.target_.style[this.targetStyleKey_]=s+'px';this.targetSizesByModeKey_[this.modeKey_]=s;},applyDelta_:function(delta){var curSize=this.getTargetSize_();var newSize;if(this.target_===this.nextElementSibling){newSize=curSize+delta;}else{newSize=curSize-delta;}
 this.setTargetSize_(newSize);},onMouseMove_:function(e){var curMousePos=this.horizontal_?e.clientY:e.clientX;var delta=this.lastMousePos_-curMousePos;this.applyDelta_(delta);this.lastMousePos_=curMousePos;e.preventDefault();return true;},onMouseDown_:function(e){if(!this.target_)
-return;this.forceMutationObserverFlush_();this.lastMousePos_=this.horizontal_?e.clientY:e.clientX;document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);e.preventDefault();return true;},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);e.preventDefault();}};return{DragHandle:DragHandle};});'use strict';Polymer('tr-ui-b-dropdown',{ready:function(){this.$.outer.tabIndex=0;},get iconElement(){return this.$.icon;},onOuterKeyDown_:function(e){if(e.keyCode===' '.charCodeAt(0)){this.toggle_();e.preventDefault();e.stopPropagation();}},onOuterClick_:function(e){var or=this.$.outer.getBoundingClientRect();var inside=true;inside&=e.clientX>=or.left;inside&=e.clientX<or.right;inside&=e.clientY>=or.top;inside&=e.clientY<or.bottom;if(!inside)
-return;e.preventDefault();this.toggle_();},toggle_:function(){if(!this.isOpen)
-this.show();else
-this.close();},show:function(){if(this.isOpen)
-return;this.$.outer.classList.add('open');var ddr=this.$.outer.getBoundingClientRect();var rW=Math.max(ddr.width,150);this.$.dialog.style.minWidth=rW+'px';this.$.dialog.showModal();var ddw=this.$.outer.getBoundingClientRect().width;var w=this.$.dialog.getBoundingClientRect().width;this.$.dialog.style.top=ddr.bottom-1+'px';this.$.dialog.style.left=ddr.left+'px';},onDialogClick_:function(e){if(!this.isOpen)
-return;if(e.srcElement!==this.$.dialog)
-return;e.preventDefault();this.close();},onDialogCancel_:function(e){e.preventDefault();this.close();},close:function(){if(!this.isOpen)
-return;this.$.dialog.close();this.$.outer.classList.remove('open');this.$.outer.focus();},get isOpen(){return this.$.dialog.hasAttribute('open');}});'use strict';tr.exportTo('tr.ui.b',function(){var FaviconsByHue={blue:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjj8xAGArIgqOPzE8nUY3dqJJOJeiSTiXnUY3do4/MTxhKyIKjkAxAAAAAAAAAAAAAAAAAAAAAABQJBwAAAAAAZJBMzSoSzqlsU8+6bRQP/21UT//tVE//7RQP/2wTz3ppko6pY9AMjQAAAABTyMbAAAAAAB7e3sAAP//AKFSRE+wTz3dtVE//7VRP/+1UT//tVE//7VRP/+zUD7/sE89/7BOPf+qTDvdl0M0TwAAAABWJx4A+fn5ANjd3TnIiX7ftVA9/7VRP/+1UT//tVE//7VRP/+xTz3/rE08/6xMO/+sTDv/rE08/6dKOt+SQTM5q0w7ALO0tA3v8fGu05uR/7NMOf+0Tzz/tE88/7RPPv+uTT3/p0o7/6ZJOv+mSTr/pkk6/6ZJOv+mSjr/n0Y4rnIwKg3h4eFK9/j48N2zrP/FeGr/xnps/8Z6bP/AaUv/tlw1/7RbNf+1WzX/tFs1/7RbNf+0WzX/tFs1/7NbNPCqWy1K7e3tjPn5+f/49vX/9vLy//by8v/28vH/8bZv/+6RH//ukyP/7pMj/+6SI//ukiP/7pMj/+2SIv/qjyL/34kfjPHx8bL5+fn/+fn5//n5+f/5+fr/+fn5//W7cP/zlB3/85Yh//OWIf/zliH/85Yh//GVIf/rkR//6ZAf/+KLHrLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f/1unD/85Qd//OWIf/zliH/85Yh//CUIP/mjh//44we/+OMHv/diR628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/9bx0//OXI//zmCb/85gm/++VIv/hjB//3Yoe/92KHv/dih7/2IYdmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5//jo0//33bv/9929//bbtf/euDX/06oJ/9OrC//Tqwv/06oM98yfD1zr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/5+vv/+fv8//n7/f/3+PH/3Ms6/9O8AP/UvQD/1L0A/9K8AMbItAAY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/5+fr/9/bu/9zKOf/TuwD/1LwA/9S8APLQuABW3cQAAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+fn6//f27v/cyTn/07sA/9S8APTRugB4w60ABcmyAAAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/49/H/5Ndu/NjEIdLSugBdybIABsy1AAAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tvX063Lt6MMhOQAAAM+/RAAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCwUEDDgZExxWJx4tYiwiN2IsIjdWJx4tOBkTHAsFBAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAbDAkKZS0jMYs+MWydRjeipko6x6tMO9utTTzjrU0846tMO9umSjrHnUY3oos+MWxlLSMxGwwJCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgZFAAPBwUHcjMoPJtFNpqsTTzhs1A+/LVRP/+2UT//tVE//7VRP/+1UT//tVE//7ZRP/+1UT//s1A+/KxNPOGbRTaacTInPA8HBQc4GRMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yp4AUCQcGZVDNICtTjzktVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+0UT//s1A+/7JQPv+rTDvkkkEzgE8jGxn/xZoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA////AGswJSqiSTivs1A++7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tFA+/7FPPf+xTz3/sU89/7FPPf+vTj37nkc3r2guJCr///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP/DogB/VEwsqE09v7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7NQPv+vTj3/r049/69OPf+vTj3/r049/69OPf+uTjz/oUg4v20xJiz/nnsAAgEBAAAAAAAAAAAAAAAAAAAAAAD19fUAkp2fHdK2sbW5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+yUD7/rU08/6xNPP+tTTz/rU08/61NPP+tTTz/rU08/61NPP+sTTz/nkY3tWAqIR2pSzsAAAAAAAAAAAAAAAAAeXl5ADY2Ngnd39+O6tbT/blbSv+1UD7/tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//slA+/6xNPP+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+qTDv9lkM0jiUQDQlSJR0AAAAAAAAAAAD///8AxMTES/X29u3s2NX/uVtK/7VQPv+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7FPPv+qTDv/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6lLOv+lSTnthDsuS/+TcgAAAAAAm5ubAHBwcA/o6Oix+vv8/+zY1P+5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+xTz3/qEs6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+bRTaxSiEaD2cuJAD///8AycnJRfX19fD6+/z/69fU/7hYR/+0Tjv/tE48/7ROPP+0Tjz/tE48/7ROPP+0Tz3/r04+/6VJOv+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDr/o0g5/6NIOf+jSDn/o0g6/6BHOfCCOS9F0FxKAAAAAALk5OSN+fn5//n6+v/y5+X/05uS/9CTiP/QlIn/0JSJ/9CUif/QlIn/0JSK/8yGb//AaDb/vWc0/71nNf+9ZzT/vWc0/71nNP+9ZjT/vWY0/71mNP+9ZjT/vGY0/7xmNP+8ZjT/vGY0/7xmNP+8ZjT/u2U0/7FiLY0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+vr/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//KWI//ylSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//CUIf/vkyD/5Y0fxY1XExbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/wlCD/7pIg/+6SIP/pjx/lunIZM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/75Mg/+uRH//qkB//6pAf/+iPH/TIfBtQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+6TIP/ojx//548f/+ePH//njx//5o4f+c1/HGHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/tkiD/5Y0f/+SNH//ljR//5Y0f/+WNH//kjB/6zn8cZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/65Eg/+KMHv/iix7/4ose/+KLHv/iix7/4ose/+CLHvfLfRta3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+qRIP/gih7/34oe/9+KHv/fih7/34oe/9+KHv/fih7/3Yge78V6GkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LH/85Yg//OVHv/zlR7/85Ue//OVHv/zlR7/85Ue//OVIf/pjyH/3ogf/92HH//dhx//3Ycf/92HH//dhx//3Ycf/92HH//ahh7ZunMZI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fr7//jr2f/2ypL/9smP//bJkP/2yZD/9smQ//bJkP/2yZD/5rNI/9OeFP/SnhX/0p4V/9KeFf/SnhX/0Z0V/9GdFf/RnRX/0Z0V/8yWFq6KVBcI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn6//n6/P/5+vz/+fr8//n6/P/5+vz/+fr8//n6/P/h013/0rsA/9O8AP/TvAD/07wA/9O8AP/TvAD/07wA/9O8AP/SvAD+yLMAav/mAADr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6ANu/qgAkyLEAALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/zrYAgQAAAACfjQAAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6AMzCrAAeybIAAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/TuwDsy7QATu7UAACXhQAAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/07wA9M63AG6ZiQADtqIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9O8APDPuABzuKMABsGrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+HSW//TugD/1LsA/9S8AP/TuwDazrcAWbejAATBqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/7uas/+bZdv/j1mvt2cYznMu0ACsUFAAAtaEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL4+frS9/j8kPT1/Trs8v8G8PP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',green:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbWJLAEpCMwptYks8eWxTdn1wVpd9cFaXeWxTdm1iSzxKQzMKbWJLAAAAAAAAAAAAAAAAAAAAAAA+OCsAAAAAAXBlTTSBdFmliHpe6Yp8X/2LfWD/i31g/4p8X/2HeV3pf3NYpW5jTDQAAAABPTcqAAAAAAB7e3sAlv//AIB1Xk+HeV3di31g/4t9YP+LfWD/i31g/4t9YP+Je1//h3pd/4d5Xf+DdVrddGhQTwAAAABDPC4A+fn5ANrb3DmupZPfinxf/4t9YP+LfWD/i31g/4t9YP+Iel7/hHdb/4R2W/+Edlv/hHdb/4BzWN9wZU05g3ZaALS0tA3w8PGuu7Sj/4h5W/+Je17/iXte/4t8X/+HeFz/gnNY/4FyWP+Bclj/gXJY/4FyWP+Bclj/fG1Url9NPA3h4eFK9/j48MvFuf+kmoP/ppuF/6abhf+JkHL/c4Rj/3OEY/9zhGP/coNj/3KDY/9yg2P/coNj/3CDYvBgf19K7e3tjPn5+f/39vb/9fTz//X08//09PP/itKw/0m+h/9Mv4n/TL+J/0y/if9Mv4n/TL+J/0y+iP9Lu4b/RrJ/jPHx8bL5+fn/+fn5//n5+f/5+fn/+fn5/4rXtP9Hwon/SsOL/0rDi/9Kw4v/SsOL/0nCiv9HvYb/RruF/0S1gbLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f+K17P/R8KJ/0rDi/9Kw4v/SsOL/0nBif9GuYT/RbaC/0W2gv9Dsn+28vLymfn5+f/5+fn/+fn5//n5+f/5+fn/jdi1/0vDjP9OxI7/TsSO/0rAiv9FtoP/RLKA/0SygP9EsoD/Qq59mfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9rw5v/H6tn/yOra/8Lp2f9e1b7/O8yz/z3MtP89zLT/Pcuy9zzApVzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+vr//Pr7//z6+//z+fn/ZuPY/zbczv853c7/Od3O/zjbzcY10sYY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/8Pj3/2Xj1/823Mz/OdzN/znczfI42MlWO+XWAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5//D49/9j4tf/NdvM/znczfQ42ct4Ncu9BTbRwgAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/z+Pj/jung/FLf0tI42ctdNdHCBjfUxgAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tu329XLO7+whAFQmAGrUygAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQgGDCsmHRxCOy4tS0M0N0tDNDdCOy4tKyYdHAkIBgwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAVEg4KTUU1MWtgSmx5bVOigHNYx4N2W9uFd1zjhXdc44N2W9uAc1jHeW1TomtgSmxNRjUxFRMOCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsnHgALCggHWE88PHdrUpqEd1vhiXxf/It9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXxf/IR3W+F3a1KaV048PAsKCAcrJx4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///AAPjcqGXJnT4CFeFzki31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+KfWD/iXxf/4l7Xv+DdlrkcGVNgDw2Khn//+sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AFJKOSp9cFavinxf+4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/inxf/4h6Xv+Iel3/iHpd/4h6Xv+GeV37eW1Ur1BINyr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP//3gBsZ1osgnVbv4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4l8X/+HeV3/hnlc/4Z5XP+GeVz/hnlc/4Z5XP+GeFz/fG9Vv1RLOiz/9LoAAgIBAAAAAAAAAAAAAAAAAAAAAAD19fUAl5ibHcbCurWShGn/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Je1//hXhc/4R3W/+Fd1v/hXdb/4V3W/+Fd1v/hXdb/4V3W/+Ed1v/eW1TtUlCMh2CdVkAAAAAAAAAAAAAAAAAeXl5ADY2Ngne3t+O4t/Z/ZKFaf+LfV//i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXte/4R3W/+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+CdVr9c2dPjhwZEwk/OSsAAAAAAAAAAAD///8AxMTES/X19u3k4dv/koRp/4t9X/+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4h6Xv+CdVr/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf9+clftZVtGS/3jrgAAAAAAm5ubAHBwcA/o6Oix+/v7/+Pg2/+ShGn/i31f/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Iel7/gXRZ/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP93a1KxOTMnD1BHNwD///8AycnJRfX19fD7+/v/4+Da/5CCZ/+Jel3/iXtd/4l7Xf+Je13/iXtd/4l7Xf+Ke17/iHhd/4BxV/9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/31uVPBnWURFo45tAAAAAALk5OSN+fn5//r6+v/t7Oj/vLSk/7aunP+3rp3/t66d/7eunf+3rp3/uK+e/6Gmjv9vkG3/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmr/bI1q/2yNav9sjWr/bI1q/2uNav9rjWr/a41q/16GZI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+fr/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/wOfV/0vCi/9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0nAif9Jv4j/RreCxStxUBbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMSM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9JwYn/SL6I/0i+iP9GuoXlOJVqM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/ScCJ/0e8hv9HvIb/R7yG/0a6hfQ9oXJQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0i/iP9GuoX/RrqE/0a6hP9GuoT/RrmD+T6ldWHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMOM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Ivof/RbiD/0W3gv9FuIP/RbiD/0W4g/9Ft4L6PqZ2ZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SL2H/0W2gv9FtYH/RbWB/0W1gf9FtYH/RbWB/0S0gPc+o3Ra3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0e8hv9EtID/RLOA/0SzgP9Es4D/RLOA/0SzgP9Es4D/Q7F/7zyecULS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/SsOL/0jCiv9Iwor/SMKK/0jCiv9Iwor/SMKK/0rCiv9HuoT/RLF+/0Owff9EsH3/RLB9/0Swff9EsH3/RLB9/0Swff9CrnzZOJZrI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6/9/x6f+l38X/o9/D/6Tfw/+k38P/pN/D/6Tfw/+k38T/a9Kz/0DBof9BwKH/QcCh/0HAof9BwKD/QcCg/0G/oP9Bv6D/Qb+g/0C4mK4tbU4I////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6//v6+//7+vv/+/r7//v6+//7+vv//Pr7//v6+/+B597/NdvN/znczf853M3/OdzN/znczf853M3/OdzN/znczf85283+NtHDakb/+gDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f823Mz/OdzN/znczf853M3/OdzN/znczf853M3/OdzN/zjay9s0x7kkNs/BALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdzN/znczf853M3/N9XHgQAAAAAspZoAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znczf853M3/OdzN/zjay8w0yrweNtDCAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f8228z/OdzN/znczf853M3/OdzN/znczf8528zsN9PETkD45gAonJEAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdvM9DjWx24qoJUDMb2wAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znbzPA418hzMr6xBjTIugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/37m3f8z28z/N9zN/znczf8528zaONbIWTK/sgQ0yLsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/vfDr/5Tq4v+L6ODtYODUnDTTxSsAGBsAMrywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+PjS+vf3kPv09Tr/6u4G/+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',red:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQxmbAC0RagpDGZs8ShysdkwdspdMHbKXShysdkMZmzwuEWoKQxmcAAAAAAAAAAAAAAAAAAAAAAAmDlgAAAAAAUQanzRPHrilUx/B6VQgxf1VIMb/VSDG/1Qgxf1TH8DpTh22pUMZnDQAAAABJQ5XAAAAAAB7ensA//8AAFUrr09SH8DdVSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/Ux/B/1IfwP9QHrrdRxqlTwAAAAAoD14A+fn5ANzf1zmMatPfVB7G/1Ugxv9VIMb/VSDG/1Ugxv9TH8L/UR68/1AevP9QHrz/UR68/04dt99EGaA5UB67ALS0sw3x8u+unYDd/1AZxP9THcX/Ux3F/1Qexf9THr//Tx23/08ctv9PHbb/Tx22/08dtv9PHbb/SxuurjkSfg3h4eFK+Pj38LWf5P97UtL/fVXS/31V0/9fOcz/SSfC/0knwP9JJ8D/SSfA/0knwP9JJ8D/SSfA/0gnv/A/KLNK7e3tjPn5+f/29fj/8vD3//Px9//y8Pf/fILz/zQ/8P83QvD/N0Lw/zdC8P83QvD/N0Lw/zdB7/82QOz/Mz3gjPHx8bL5+fn/+fn5//n6+f/5+vn/+fn5/36G9v8yQPT/NkP0/zZD9P82Q/T/NkP0/zVC8v80QOz/M0Dq/zI+47Lz8/O2+fn5//n5+f/5+fn/+fn5//n5+f99hvb/MkD0/zZD9P82Q/T/NkP0/zVC8f8zP+f/Mj7k/zI+5P8xPd628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/gYn2/zdE9P87R/T/O0f0/zZF8P8yQOP/MT/e/zE/3v8xP97/Lz3ZmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9fZ+P/Bxfj/wsb4/7vD+P87j/X/Dnzx/xF98f8RffH/EXzw9xZv5Vzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+/n//Pz5//38+f/x+Pn/OrD+/wCY//8Amf//AJn//wCZ/cYAlPMY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/7vX5/zmu/v8Al///AJj//wCY/vIAlfpWAJ//AOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5/+71+f85rf7/AJb//wCY//QAlvx4AIzrBQCQ8gAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/x9vn/bsP8/CGk/tIAlvxdAJDyBgCT9QAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tuvy93LD4fUhAAC7AESo6wAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgIMDBoKPRwoD14tLhFrNy4RazcoD14tGgo9HAYCDAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+3/wANBR0KLxJuMUEYmGxKHKyiTh22x1Aeu9tRHr3jUR6941Aeu9tOHbbHShysokEYmGwvEm4xDQUeCv+6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoKPgAHAxAHNhR9PEkbqppRHr3hVCDE/FUgxv9VIMf/VSDH/1Ugxv9VIMb/VSDH/1Ugx/9VIMb/VCDE/FEevOFIG6maNRR8PAcDEAcaCj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVUP8AJg5YGUYao4BRH77kVSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMX/VB/E/1Qfw/9QHrvkRRmggCUOVhnQTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA////ADITdSpMHbKvVCDE+1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VCDE/1Mfwv9TH8H/Ux/B/1Mfwv9SH7/7ShytrzEScSr///8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAMto/wBVPoYsUSC3v1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1QfxP9SHsD/Uh6//1Iev/9SHr//Uh6//1Iev/9SHr//SxywvzMTdyymPf8AAQACAAAAAAAAAAAAAAAAAAAAAAD19fUAnaKQHbep1rVfLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/UR6+/1Eevf9RHr3/UR69/1Eevf9RHr3/UR69/1Eevf9RHr3/ShuttS0RaB1PHrkAAAAAAAAAAAAAAAAAeXl5ADY2Ngnf4NyO18zu/V8tyf9UH8b/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VB/D/1EevP9QHrr/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrr9RhqkjhEGKAknDloAAAAAAAAAAAD///8AxMTES/b39O3Zzu//Xy3J/1Qfxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Mfwv9QHbr/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duf9NHLTtPheRS5s5/wAAAAAAm5ubAHBwcA/o6Oix+/z6/9jO7/9fLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9TH8H/Tx24/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9JG6mxIw1RDzAScQD///8AycnJRfX19fD7/Pr/2M3v/1wqyP9SHMX/UhzF/1Icxf9SHMX/UhzF/1Icxf9THcX/Ux7A/04ctf9NHLL/Thyz/04cs/9NHLP/TRyz/00cs/9OHLP/Thyz/04cs/9OHLP/Thyz/04cs/9NHLP/Thyz/0wcsPA/Fo9FYyTkAAAAAALk5OSN+fn5//r6+f/n4vT/noDd/5Z22v+Wdtr/lnba/5Z22v+Wdtr/mHfb/35g1/9KMMr/SC/H/0gvx/9IL8f/SC/H/0gvx/9IL8b/SC/G/0gvxv9HL8b/Ry/G/0cvxv9HL8b/Ry/G/0cvxv9HL8X/Ry7F/z8tuI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/6+vn/+fr5//n6+f/5+vn/+fr5//n6+f/9/fn/ub73/zhF8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zVC8f81QvD/Mz/mxR8njhbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P81QvH/NEHv/zRB7/8zQOrlKTO6M9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NULw/zRA7P80QOv/NEDr/zNA6fQsN8lQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zVB7/8zQOn/Mz/o/zM/6P8zQOj/Mz/n+S04zmHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P80Qe7/Mz/m/zM/5f8zP+b/Mz/m/zM/5v8yP+X6LjnPZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NEHs/zI+4/8yPuP/Mj7j/zI+4/8yPuP/Mj7j/zI+4fctOMxa3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zRA6/8xPeH/MT3g/zE94P8xPeD/MT3g/zE94P8xPeD/MT3e7ys2xkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+4vff/NkP0/zNB9P80QfT/NEH0/zRB9P80QfT/NEH0/zZC8/81P+n/Mjze/zI73f8yO93/Mjvd/zI73f8yO93/Mjvd/zI73f8xO9rZKTO7I56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/9ze+P+covf/mqD3/5qg9/+aoPf/mqD3/5qg9/+aoPf/UoLz/x1p5/8eaeb/Hmnm/x5p5v8eaeX/Hmnl/x5p5f8eaOX/Hmjl/yBh3a4jJokI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vr5//z8+f/8/Pn//Pz5//z8+f/8/Pn//Pz5//z8+f9dvfz/AJf+/wCZ/v8Amf7/AJn+/wCZ/v8Amf7/AJn+/wCZ/v8AmP7+AJLxagC4/wDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/NsAieckAI/xALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJP3gQAAAAAAcr8AAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/MwAi+oeAJDxAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8Al/7sAJL0TgCr/wAAa7QAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj+9ACU+G4AbrgDAIPaAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY/vAAlflzAITcBgCK5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u7/f8Alf//AJf//wCY//8Al/7aAJT4WQCE3AQAiucAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/rNv7/3bG/P9rwfztM6r7nACR9SsAER0AAIPZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+fjS/Pj2kP338jr/+eIG//fqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',yellow:'data:image/vndmicrosofticon;base64,AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAZKhQAOWAiAEV0KgBFdCoAOWAiABkqFAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8ZAAAChAHAEp8JwBvu10AgNeSAInluACN7c4Aj/DXAI/w1wCN7c4AieW4AIDXkgBvu10ASnwnAAoQBwA8ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbLgAAAAAFAFmWMwB/1YwAj/DXAJX7+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJX7+QCP79cAftWMAFmVMwAAAAUAGy4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7v8AAD1mFQB6zXYAkPLdAJf+/gCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP7/AJf+/wCV/P4AjvDdAHjKdgA8ZBUA6f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AABWkCYAh+KoAJb8+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJf+/wCV+v8AlPr/AJT6/wCV+v8Akvf5AIPdqABTjCYA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICABb//wAka5wqAozquwCY/v8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCX/f8Ak/j/AJP3/wCT9/8Ak/f/AJP3/wCT9/8Akvb/AIbiuwBZlyoA//8AAAECAAAAAAAAAAAAAAAAAAAAAADz8/MAqJaJHZDD5rQLnP7/AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alvz/AJL2/wCR9P8AkfT/AJH0/wCR9P8AkfT/AJH0/wCR9P8AkfT/AITftABQhh0AjO0AAAAAAAAAAAAAAAAAfX19ADw8PAni3tuPuuD5/Quc//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJb8/wCQ8/8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8AjvD9AH7UjwAiOQkASHkAAAAAAAgICAD///8AxcXFT/j19O+94vv/Cpz//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCV+/8Aj/H/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCO7v8AiunvAHC8TwD//wAABQgAqKioAHp6ehHp6em3/fv5/7zh+v8KnP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alfr/AI7u/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8Ag9y3AERyEQBenQD///8AzMzMTfb29vP9+/n/vOH6/wqb//8Alv//AJb//wCW//8Alv//AJb//wCW//8Al///AJT5/wCL6/8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCH5fMAb75NAMP/AAAAAAXl5eWX+fn5//v6+f/T6vr/Wbv9/0+3/f9Qt/3/ULf9/1C3/f9Qt/3/Ubj9/zew+/8InO//B5nr/weZ6/8Hmev/B5nq/weZ6v8Hmer/B5nq/weZ6v8Hmer/B5jq/weY6v8HmOn/B5jp/weY6f8HmOn/Bpjp/weP15cBAAAFpKSkHfDw8M/5+fn/+fn5//n5+f/1+Pn/9Pf5//T3+f/09/n/9Pf5//T3+f/4+Pn/o+T6/wq//f8Hv/3/CL/9/wi//f8Iv/3/CL/9/wi//f8Iv/3/CL/8/wi+/P8Ivvz/CL78/wi+/P8Ivvz/CL78/we9+/8HvPr/BrbxzwR9pR3Ly8tA9fX17Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcL//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hv/3/Br36/wa9+v8GuvbsBZnLQNra2mD39/f4+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B778/wa79/8Guvf/Brr3/wa59fgFo9hg4uLidPj4+P35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we++/8GufX/Brj0/wa49P8GuPT/Brfz/QWm3XTk5OR6+Pj4/fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcH//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hvfr/Brfy/wa28f8GtvH/Brbx/wa28f8GtfD9BafdeuXl5W/4+Pj8+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B7z5/wa17/8GtO7/BrTu/wa07v8GtO7/BrTu/waz7fwFpdtv4eHhVvj4+Pb5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we7+P8Gsu3/BrHr/wax6/8Gsev/BrHr/wax6/8Gsev/BrDq9gWh1Vba2toz9vb25vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+k5fv/BsH//wPA//8DwP//A8D//wPA//8DwP//A8D//wXA//8Guvb/BrDq/wau6P8Gruj/Bq7o/wau6P8Gruj/Bq7o/wau6P8GreXmBZnLM7+/vxH09PTC+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/83v+v9x2vz/btn9/2/Z/f9v2f3/b9n9/2/Z/f9v2f3/RdL5/yXG7v8mxOz/JsTs/ybE6/8mxOv/JsTr/yXE6/8lw+v/JcPr/yK95cIQirAR////APDw8IH5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn5//r5+f/6+fn/+vn5//r5+f/6+fn/+vn5//r5+f+H8Pz/Oer+/zzq/v886v7/POr+/zzq/v886v7/POr+/zzq/v886v3/OuDzgWz//wD09PQA5+fnNPf39+n5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876///O+v//zvp/ek32+00Ouf6AMrKygCzs7MF8/Pzmvn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v//zvr//876///OuX5miqptwUwv88AAAAAAPPz8wDp6eku9/f33fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//876///O+v//zvp/d033O8uOuX5AAAAAAAAAAAAvr6+AP///wDx8fFl+Pj49fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876v71OeP2ZY7//wAus8IAAAAAAAAAAAAAAAAA4ODgANPT0wj09PSI+fn5+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v/+jrm+Ygyx9gINdPlAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOHh4Q309PSM+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//g65/qMNtXnDTjd7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOLi4gr09PRw+Pj45/n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Pw/f816///Oev//zvr//876v7nOub5cDbW5wo33O4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ODgANHR0QLx8fE89/f3sfn5+fX5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/t/T7/4Xx/f+A8P31Xez8sTnk9zwuxdUCNtTkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREAP///wDo6OgM9PT0Tff396T4+Pjf+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+fj5+Pjf9vf3pPL09E3m6OgM7/3/APtbOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMjIwD19fUA4uLiBvHx8Sn19fVd9vb2jff396739/e99/f3vff396729vaN9fX1XfHx8Snl4uIG9PX1AFEnIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/wD///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABgAAAAcAAAAPgAAAH4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/KAAAABAAAAAgAAAAAQAgAAAAAAAABAAAEgsAABILAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABorgAAS34IAHTDNQCC22wAh+OMAIfjjACC22wAdMQ1AEx/CABorwAAAAAAAAAAAAAAAAAAAAAAAEBrAAAAAAAAecswAIzsngCU+OUAl/37AJj+/wCY/v8Al/37AJP35QCL6Z4Ad8gwAAAAAAA+aQAAAAAAcXd6AP8AAAAOiNtNAJP32gCY//8AmP//AJj//wCY//8AmP//AJb8/wCU+f8Ak/j/AI7w2gB+1E0AAAAAAEd4APn7/ADc2NU5T7P33gCX//8AmP//AJj//wCY//8AmP//AJX6/wCR8/8AkPL/AJDz/wCQ8/8AjOzeAHrOOQCR9AC3t7cO8e/vsGnA/f8Alf//AJf//wCX//8Al///AJP4/wCN7v8AjOz/AIzs/wCM7P8AjOz/AIzt/wCG4rAAY6oO4uLiT/j39/GIzfz/Mav+/zSs/v80rP7/FaH5/wOV7f8DlOv/A5Tr/wOU6/8DlOv/A5Tr/wOU6/8Dk+jxBIvVT+3t7ZT5+fn/8fb5/+vz+f/r9Pn/6vP5/1nR+/8EvPz/B738/we9/P8Hvfz/B738/we9/P8HvPv/B7r4/wax7ZTy8vK7+fn5//n5+f/6+fn/+vn5//n5+f9e1f3/A8D//wfB//8Hwf//B8H//wfB//8HwP3/Brv3/wa59f8GtO678/Pzwfn5+f/5+fn/+fn5//n5+f/4+fn/XtX9/wPA//8Hwf//B8H//wfB//8Hv/z/Brfz/wa17/8Gte//BrHqwfPz86X5+fn/+fn5//n5+f/5+fn/+Pn5/2DW/f8Gwf//CsL//wrC//8Jv/v/CLXu/wix6f8Isen/CLHp/wet5KXy8vJo+fn5+vn5+f/5+fn/+fn5//n5+f/I7vr/quf7/6zn+/+m5/v/Tdz5/yzV9P8u1fT/LtX0/y7U8/ooyOpo7OzsH/f399D5+fn/+fn5//n5+f/5+fn//Pr5//36+f/++vn/9fn5/2rv/v857P//POz//zzs//886/3QOuLzH////wD09PRh+fn59vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//H4+f9o7v7/OOv//zvr//876//2Ouf6YUH//wDu7u4A6enpB/b29oT5+fn3+fn5//n5+f/5+fn/+fn5//n5+f/x+Pn/Zu7+/zfr//876//3Ouj8hDfc7wc44PMAAAAAAPHx8QDu7u4I9vb2aPj4+Nn5+fn9+fn5//n5+f/5+fn/8/n5/4zx/P1S7P7ZO+n8aDfh9Ag55PcAAAAAAAAAAAAAAAAA6+vrAN/f3wH19fUo9/f3fvj4+MH4+Pje+Pj43vj4+MHq9vh+w/H2KADM5wFk4e8AAAAAAAAAAADwDwAA4AcAAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAgAEAAMADAADgBwAA'};return{FaviconsByHue:FaviconsByHue};});'use strict';tr.exportTo('tr.ui.b',function(){function HotKey(dict){if(dict.eventType===undefined)
+return;this.forceMutationObserverFlush_();this.lastMousePos_=this.horizontal_?e.clientY:e.clientX;document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);e.preventDefault();return true;},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);e.preventDefault();}});'use strict';tr.exportTo('tr.ui.b',function(){function HotKey(dict){if(dict.eventType===undefined)
 throw new Error('eventType must be given');if(dict.keyCode===undefined&&dict.keyCodes===undefined)
 throw new Error('keyCode or keyCodes must be given');if(dict.keyCode!==undefined&&dict.keyCodes!==undefined)
 throw new Error('Only keyCode or keyCodes can be given');if(dict.callback===undefined)
 throw new Error('callback must be given');this.eventType_=dict.eventType;this.keyCodes_=[];if(dict.keyCode)
 this.pushKeyCode_(dict.keyCode);else if(dict.keyCodes){dict.keyCodes.forEach(this.pushKeyCode_,this);}
 this.useCapture_=!!dict.useCapture;this.callback_=dict.callback;this.thisArg_=dict.thisArg!==undefined?dict.thisArg:undefined;this.helpText_=dict.helpText!==undefined?dict.helpText:undefined;}
-HotKey.prototype={get eventType(){return this.eventType_;},get keyCodes(){return this.keyCodes_;},get helpText(){return this.helpText_;},call:function(e){this.callback_.call(this.thisArg_,e);},pushKeyCode_:function(keyCode){this.keyCodes_.push(keyCode);}};return{HotKey:HotKey};});'use strict';Polymer('tv-ui-b-hotkey-controller',{created:function(){this.globalMode_=false;this.slavedToParentController_=undefined;this.curHost_=undefined;this.childControllers_=[];this.bubblingKeyDownHotKeys_={};this.capturingKeyDownHotKeys_={};this.bubblingKeyPressHotKeys_={};this.capturingKeyPressHotKeys_={};this.onBubblingKeyDown_=this.onKey_.bind(this,false);this.onCapturingKeyDown_=this.onKey_.bind(this,true);this.onBubblingKeyPress_=this.onKey_.bind(this,false);this.onCapturingKeyPress_=this.onKey_.bind(this,true);},attached:function(){var host=this.findHost_();if(host.__hotkeyController)
+HotKey.prototype={get eventType(){return this.eventType_;},get keyCodes(){return this.keyCodes_;},get helpText(){return this.helpText_;},call:function(e){this.callback_.call(this.thisArg_,e);},pushKeyCode_:function(keyCode){this.keyCodes_.push(keyCode);}};return{HotKey:HotKey};});'use strict';Polymer('tv-ui-b-hotkey-controller',{created:function(){this.isAttached_=false;this.globalMode_=false;this.slavedToParentController_=undefined;this.curHost_=undefined;this.childControllers_=[];this.bubblingKeyDownHotKeys_={};this.capturingKeyDownHotKeys_={};this.bubblingKeyPressHotKeys_={};this.capturingKeyPressHotKeys_={};this.onBubblingKeyDown_=this.onKey_.bind(this,false);this.onCapturingKeyDown_=this.onKey_.bind(this,true);this.onBubblingKeyPress_=this.onKey_.bind(this,false);this.onCapturingKeyPress_=this.onKey_.bind(this,true);},attached:function(){this.isAttached_=true;var host=this.findHost_();if(host.__hotkeyController)
 throw new Error('Multiple hotkey controllers attached to this host');host.__hotkeyController=this;this.curHost_=host;var parentElement;if(host.parentElement)
 parentElement=host.parentElement;else
 parentElement=host.parentNode.host;var parentController=tr.b.getHotkeyControllerForElement(parentElement);if(parentController){this.slavedToParentController_=parentController;parentController.addChildController_(this);return;}
-host.addEventListener('keydown',this.onBubblingKeyDown_,false);host.addEventListener('keydown',this.onCapturingKeyDown_,true);host.addEventListener('keypress',this.onBubblingKeyPress_,false);host.addEventListener('keypress',this.onCapturingKeyPress_,true);},detached:function(){var host=this.curHost_;if(!host)
+host.addEventListener('keydown',this.onBubblingKeyDown_,false);host.addEventListener('keydown',this.onCapturingKeyDown_,true);host.addEventListener('keypress',this.onBubblingKeyPress_,false);host.addEventListener('keypress',this.onCapturingKeyPress_,true);},detached:function(){this.isAttached_=false;var host=this.curHost_;if(!host)
 return;delete host.__hotkeyController;this.curHost_=undefined;if(this.slavedToParentController_){this.slavedToParentController_.removeChildController_(this);this.slavedToParentController_=undefined;return;}
 host.removeEventListener('keydown',this.onBubblingKeyDown_,false);host.removeEventListener('keydown',this.onCapturingKeyDown_,true);host.removeEventListener('keypress',this.onBubblingKeyPress_,false);host.removeEventListener('keypress',this.onCapturingKeyPress_,true);},addChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i!==-1)
 throw new Error('Controller already registered');this.childControllers_.push(controller);},removeChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i===-1)
@@ -5792,7 +5852,9 @@
 throw new Error('hotKey must be a tr.ui.b.HotKey');var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(!keyMap[keyCode])
 throw new Error('Key is not bound for keyCode='+keyCode);keyMap[keyCode]=hotKey;}
 for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];delete keyMap[keyCode];}
-return hotKey;},get globalMode(){return this.globalMode_;},set globalMode(globalMode){this.detached();this.globalMode_=!!globalMode;this.attached();},get topmostConroller_(){if(this.slavedToParentController_)
+return hotKey;},get globalMode(){return this.globalMode_;},set globalMode(globalMode){var wasAttached=this.isAttached_;if(wasAttached)
+this.detached();this.globalMode_=!!globalMode;if(wasAttached)
+this.attached();},get topmostConroller_(){if(this.slavedToParentController_)
 return this.slavedToParentController_.topmostConroller_;return this;},childRequestsGeneralFocus:function(child){var topmost=this.topmostConroller_;if(topmost.curHost_){if(topmost.curHost_.hasAttribute('tabIndex')){topmost.curHost_.focus();}else{if(document.activeElement)
 document.activeElement.blur();}}else{if(document.activeElement)
 document.activeElement.blur();}},childRequestsBlur:function(child){child.blur();var topmost=this.topmostConroller_;if(topmost.curHost_){topmost.curHost_.focus();}},findHost_:function(){if(this.globalMode_){return document.body;}else{if(this.parentElement)
@@ -5810,17 +5872,35 @@
 return node.host;}
 return{getHotkeyControllerForElement:getHotkeyControllerForElement};});'use strict';Polymer('tr-ui-b-info-bar',{ready:function(){this.messageEl_=this.$.message;this.buttonsEl_=this.$.buttons;this.message='';this.visible=false;},get message(){return this.messageEl_.textContent;},set message(message){this.messageEl_.textContent=message;},get visible(){return!this.classList.contains('info-bar-hidden');},set visible(visible){if(visible)
 this.classList.remove('info-bar-hidden');else
-this.classList.add('info-bar-hidden');},removeAllButtons:function(){this.buttonsEl_.textContent='';},addButton:function(text,clickCallback){var button=document.createElement('button');button.textContent=text;button.addEventListener('click',clickCallback);this.buttonsEl_.appendChild(button);return button;}});'use strict';Polymer('tr-ui-b-info-bar-group',{ready:function(){this.messages_=[];},clearMessages:function(){this.messages_=[];this.updateContents_();},addMessage:function(text,opt_buttons){opt_buttons=opt_buttons||[];for(var i=0;i<opt_buttons.length;i++){if(opt_buttons[i].buttonText===undefined)
-throw new Error('buttonText must be provided');if(opt_buttons[i].onClick===undefined)
-throw new Error('onClick must be provided');}
-this.messages_.push({text:text,buttons:opt_buttons||[]});this.updateContents_();},updateContents_:function(){this.$.messages.textContent='';this.messages_.forEach(function(message){var bar=document.createElement('tr-ui-b-info-bar');bar.message=message.text;bar.visible=true;message.buttons.forEach(function(button){bar.addButton(button.buttonText,button.onClick);},this);this.$.messages.appendChild(bar);},this);}});'use strict';tr.exportTo('tr.ui',function(){var Task=tr.b.Task;function FindController(brushingStateController){this.brushingStateController_=brushingStateController;this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;this.activePromise_=Promise.resolve();this.activeTask_=undefined;};FindController.prototype={__proto__:Object.prototype,get model(){return this.brushingStateController_.model;},get brushingStateController(){return this.brushingStateController_;},enqueueOperation_:function(operation){var task;if(operation instanceof tr.b.Task)
-task=operation;else
-task=new tr.b.Task(operation,this);if(this.activeTask_){this.activeTask_=this.activeTask_.enqueue(task);}else{this.activeTask_=task;this.activePromise_=Task.RunWhenIdle(this.activeTask_);this.activePromise_.then(function(){this.activePromise_=undefined;this.activeTask_=undefined;}.bind(this));}},startFiltering:function(filterText){var sc=this.brushingStateController_;if(!sc)
-return;this.enqueueOperation_(function(){this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;}.bind(this));var stateFromString;try{stateFromString=sc.uiStateFromString(filterText);}catch(e){this.enqueueOperation_(function(){var overlay=new tr.ui.b.Overlay();overlay.textContent=e.message;overlay.title='UI State Navigation Error';overlay.visible=true;});return this.activePromise_;}
-if(stateFromString!==undefined){this.enqueueOperation_(sc.navToPosition.bind(this,stateFromString,true));}else{if(filterText.length===0){this.enqueueOperation_(sc.findTextCleared.bind(sc));}else{var filter=new tr.c.FullTextFilter(filterText);var filterHits=new tr.model.EventSet();this.enqueueOperation_(sc.addAllEventsMatchingFilterToSelectionAsTask(filter,filterHits));this.enqueueOperation_(function(){this.filterHits_=filterHits;sc.findTextChangedTo(filterHits);}.bind(this));}}
-return this.activePromise_;},get filterHits(){return this.filterHits_;},get currentHitIndex(){return this.currentHitIndex_;},find_:function(dir){var firstHit=this.currentHitIndex_===-1;if(firstHit&&dir<0)
-this.currentHitIndex_=0;var N=this.filterHits.length;this.currentHitIndex_=(this.currentHitIndex_+dir+N)%N;if(!this.brushingStateController_)
-return;this.brushingStateController_.findFocusChangedTo(this.filterHits.subEventSet(this.currentHitIndex_,1));},findNext:function(){this.find_(1);},findPrevious:function(){this.find_(-1);}};return{FindController:FindController};});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE={};MOUSE_SELECTOR_MODE.SELECTION=0x1;MOUSE_SELECTOR_MODE.PANSCAN=0x2;MOUSE_SELECTOR_MODE.ZOOM=0x4;MOUSE_SELECTOR_MODE.TIMING=0x8;MOUSE_SELECTOR_MODE.ROTATE=0x10;MOUSE_SELECTOR_MODE.ALL_MODES=0x1F;var MOUSE_SELECTOR_MODE_INFOS={};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.PANSCAN]={mode:MOUSE_SELECTOR_MODE.PANSCAN,title:'pan',eventNames:{enter:'enterpan',begin:'beginpan',update:'updatepan',end:'endpan',exit:'exitpan'},activeBackgroundPosition:'-30px -10px',defaultBackgroundPosition:'0 -10px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION]={mode:MOUSE_SELECTOR_MODE.SELECTION,title:'selection',eventNames:{enter:'enterselection',begin:'beginselection',update:'updateselection',end:'endselection',exit:'exitselection'},activeBackgroundPosition:'-30px -40px',defaultBackgroundPosition:'0 -40px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ZOOM]={mode:MOUSE_SELECTOR_MODE.ZOOM,title:'zoom',eventNames:{enter:'enterzoom',begin:'beginzoom',update:'updatezoom',end:'endzoom',exit:'exitzoom'},activeBackgroundPosition:'-30px -70px',defaultBackgroundPosition:'0 -70px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.TIMING]={mode:MOUSE_SELECTOR_MODE.TIMING,title:'timing',eventNames:{enter:'entertiming',begin:'begintiming',update:'updatetiming',end:'endtiming',exit:'exittiming'},activeBackgroundPosition:'-30px -100px',defaultBackgroundPosition:'0 -100px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ROTATE]={mode:MOUSE_SELECTOR_MODE.ROTATE,title:'rotate',eventNames:{enter:'enterrotate',begin:'beginrotate',update:'updaterotate',end:'endrotate',exit:'exitrotate'},activeBackgroundPosition:'-30px -130px',defaultBackgroundPosition:'0 -130px'};return{MOUSE_SELECTOR_MODE_INFOS:MOUSE_SELECTOR_MODE_INFOS,MOUSE_SELECTOR_MODE:MOUSE_SELECTOR_MODE};});'use strict';Polymer('tr-ui-b-mouse-mode-icon',{publish:{modeName:{value:undefined,reflect:true}},created:function(){this.active_=false;this.acceleratorKey_=undefined;},ready:function(){this.updateContents_();},get mode(){return tr.ui.b.MOUSE_SELECTOR_MODE[this.modeName];},set mode(mode){var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];var modeName=tr.b.findFirstKeyInDictMatching(tr.ui.b.MOUSE_SELECTOR_MODE,function(modeName,candidateMode){return candidateMode===mode;});if(modeName===undefined)
+this.classList.add('info-bar-hidden');},removeAllButtons:function(){this.buttonsEl_.textContent='';},addButton:function(text,clickCallback){var button=document.createElement('button');button.textContent=text;button.addEventListener('click',clickCallback);this.buttonsEl_.appendChild(button);return button;}});'use strict';tr.exportTo('tr.ui.b',function(){var ContainerThatDecoratesItsChildren=tr.ui.b.define('div');ContainerThatDecoratesItsChildren.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.observer_=new WebKitMutationObserver(this.didMutate_.bind(this));this.observer_.observe(this,{childList:true});Object.defineProperty(this,'textContent',{get:undefined,set:this.onSetTextContent_});},appendChild:function(x){HTMLUnknownElement.prototype.appendChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},insertBefore:function(x,y){HTMLUnknownElement.prototype.insertBefore.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},removeChild:function(x){HTMLUnknownElement.prototype.removeChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},replaceChild:function(x,y){HTMLUnknownElement.prototype.replaceChild.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},onSetTextContent_:function(textContent){if(textContent!='')
+throw new Error('textContent can only be set to \'\'.');this.clear();},clear:function(){while(this.lastChild)
+HTMLUnknownElement.prototype.removeChild.call(this,this.lastChild);this.didMutate_(this.observer_.takeRecords());},didMutate_:function(records){this.beginDecorating_();for(var i=0;i<records.length;i++){var addedNodes=records[i].addedNodes;if(addedNodes){for(var j=0;j<addedNodes.length;j++)
+this.decorateChild_(addedNodes[j]);}
+var removedNodes=records[i].removedNodes;if(removedNodes){for(var j=0;j<removedNodes.length;j++){this.undecorateChild_(removedNodes[j]);}}}
+this.doneDecoratingForNow_();},decorateChild_:function(child){throw new Error('Not implemented');},undecorateChild_:function(child){throw new Error('Not implemented');},beginDecorating_:function(){},doneDecoratingForNow_:function(){}};return{ContainerThatDecoratesItsChildren:ContainerThatDecoratesItsChildren};});'use strict';tr.exportTo('tr.ui.b',function(){var ListView=tr.ui.b.define('x-list-view',tr.ui.b.ContainerThatDecoratesItsChildren);ListView.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);this.classList.add('x-list-view');this.onItemClicked_=this.onItemClicked_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.tabIndex=0;this.addEventListener('keydown',this.onKeyDown_);this.selectionChanged_=false;},decorateChild_:function(item){item.classList.add('list-item');item.addEventListener('click',this.onItemClicked_,true);var listView=this;Object.defineProperty(item,'selected',{configurable:true,set:function(value){var oldSelection=listView.selectedElement;if(oldSelection&&oldSelection!=this&&value)
+listView.selectedElement.removeAttribute('selected');if(value)
+this.setAttribute('selected','selected');else
+this.removeAttribute('selected');var newSelection=listView.selectedElement;if(newSelection!=oldSelection)
+tr.b.dispatchSimpleEvent(listView,'selection-changed',false);},get:function(){return this.hasAttribute('selected');}});},undecorateChild_:function(item){this.selectionChanged_|=item.selected;item.classList.remove('list-item');item.removeEventListener('click',this.onItemClicked_);delete item.selected;},beginDecorating_:function(){this.selectionChanged_=false;},doneDecoratingForNow_:function(){if(this.selectionChanged_)
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get selectedElement(){var el=this.querySelector('.list-item[selected]');if(!el)
+return undefined;return el;},set selectedElement(el){if(!el){if(this.selectedElement)
+this.selectedElement.selected=false;return;}
+if(el.parentElement!=this)
+throw new Error('Can only select elements that are children of this list view');el.selected=true;},getElementByIndex:function(index){return this.querySelector('.list-item:nth-child('+index+')');},clear:function(){var changed=this.selectedElement!==undefined;tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);if(changed)
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onItemClicked_:function(e){var currentSelectedElement=this.selectedElement;if(currentSelectedElement)
+currentSelectedElement.removeAttribute('selected');var element=e.target;while(element.parentElement!=this)
+element=element.parentElement;if(element!==currentSelectedElement)
+element.setAttribute('selected','selected');tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onKeyDown_:function(e){if(this.selectedElement===undefined)
+return;if(e.keyCode==38){var prev=this.selectedElement.previousSibling;if(prev){prev.selected=true;tr.ui.b.scrollIntoViewIfNeeded(prev);e.preventDefault();return true;}}else if(e.keyCode==40){var next=this.selectedElement.nextSibling;if(next){next.selected=true;tr.ui.b.scrollIntoViewIfNeeded(next);e.preventDefault();return true;}}},addItem:function(textContent){var item=document.createElement('div');item.textContent=textContent;this.appendChild(item);return item;}};return{ListView:ListView};});'use strict';tr.exportTo('tr.ui.b',function(){function MouseTracker(opt_targetElement){this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.targetElement=opt_targetElement;}
+MouseTracker.prototype={get targetElement(){return this.targetElement_;},set targetElement(targetElement){if(this.targetElement_)
+this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);this.targetElement_=targetElement;if(this.targetElement_)
+this.targetElement_.addEventListener('mousedown',this.onMouseDown_);},onMouseDown_:function(e){if(e.button!==0)
+return true;e=this.remakeEvent_(e,'mouse-tracker-start');this.targetElement_.dispatchEvent(e);document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);this.targetElement_.addEventListener('blur',this.onMouseUp_);this.savePreviousUserSelect_=document.body.style['-webkit-user-select'];document.body.style['-webkit-user-select']='none';e.preventDefault();return true;},onMouseMove_:function(e){e=this.remakeEvent_(e,'mouse-tracker-move');this.targetElement_.dispatchEvent(e);},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);this.targetElement_.removeEventListener('blur',this.onMouseUp_);document.body.style['-webkit-user-select']=this.savePreviousUserSelect_;e=this.remakeEvent_(e,'mouse-tracker-end');this.targetElement_.dispatchEvent(e);},remakeEvent_:function(e,newType){var remade=new tr.b.Event(newType,true,true);remade.x=e.x;remade.y=e.y;remade.offsetX=e.offsetX;remade.offsetY=e.offsetY;remade.clientX=e.clientX;remade.clientY=e.clientY;return remade;}};function trackMouseMovesUntilMouseUp(mouseMoveHandler,opt_mouseUpHandler,opt_keyUpHandler){function cleanupAndDispatchToMouseUp(e){document.removeEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
+document.removeEventListener('keyup',opt_keyUpHandler);document.removeEventListener('mouseup',cleanupAndDispatchToMouseUp);if(opt_mouseUpHandler)
+opt_mouseUpHandler(e);}
+document.addEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
+document.addEventListener('keyup',opt_keyUpHandler);document.addEventListener('mouseup',cleanupAndDispatchToMouseUp);}
+return{MouseTracker:MouseTracker,trackMouseMovesUntilMouseUp:trackMouseMovesUntilMouseUp};});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE={};MOUSE_SELECTOR_MODE.SELECTION=0x1;MOUSE_SELECTOR_MODE.PANSCAN=0x2;MOUSE_SELECTOR_MODE.ZOOM=0x4;MOUSE_SELECTOR_MODE.TIMING=0x8;MOUSE_SELECTOR_MODE.ROTATE=0x10;MOUSE_SELECTOR_MODE.ALL_MODES=0x1F;var MOUSE_SELECTOR_MODE_INFOS={};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.PANSCAN]={mode:MOUSE_SELECTOR_MODE.PANSCAN,title:'pan',eventNames:{enter:'enterpan',begin:'beginpan',update:'updatepan',end:'endpan',exit:'exitpan'},activeBackgroundPosition:'-30px -10px',defaultBackgroundPosition:'0 -10px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION]={mode:MOUSE_SELECTOR_MODE.SELECTION,title:'selection',eventNames:{enter:'enterselection',begin:'beginselection',update:'updateselection',end:'endselection',exit:'exitselection'},activeBackgroundPosition:'-30px -40px',defaultBackgroundPosition:'0 -40px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ZOOM]={mode:MOUSE_SELECTOR_MODE.ZOOM,title:'zoom',eventNames:{enter:'enterzoom',begin:'beginzoom',update:'updatezoom',end:'endzoom',exit:'exitzoom'},activeBackgroundPosition:'-30px -70px',defaultBackgroundPosition:'0 -70px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.TIMING]={mode:MOUSE_SELECTOR_MODE.TIMING,title:'timing',eventNames:{enter:'entertiming',begin:'begintiming',update:'updatetiming',end:'endtiming',exit:'exittiming'},activeBackgroundPosition:'-30px -100px',defaultBackgroundPosition:'0 -100px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ROTATE]={mode:MOUSE_SELECTOR_MODE.ROTATE,title:'rotate',eventNames:{enter:'enterrotate',begin:'beginrotate',update:'updaterotate',end:'endrotate',exit:'exitrotate'},activeBackgroundPosition:'-30px -130px',defaultBackgroundPosition:'0 -130px'};return{MOUSE_SELECTOR_MODE_INFOS:MOUSE_SELECTOR_MODE_INFOS,MOUSE_SELECTOR_MODE:MOUSE_SELECTOR_MODE};});'use strict';Polymer('tr-ui-b-mouse-mode-icon',{publish:{modeName:{value:undefined,reflect:true}},created:function(){this.active_=false;this.acceleratorKey_=undefined;},ready:function(){this.updateContents_();},get mode(){return tr.ui.b.MOUSE_SELECTOR_MODE[this.modeName];},set mode(mode){var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];var modeName=tr.b.findFirstKeyInDictMatching(tr.ui.b.MOUSE_SELECTOR_MODE,function(modeName,candidateMode){return candidateMode===mode;});if(modeName===undefined)
 throw new Error('Unknown mode');this.modeName=modeName;},modeNameChanged:function(){this.updateContents_();},get active(){return this.active_;},set active(active){this.active_=!!active;if(this.active_)
 this.classList.add('active');else
 this.classList.remove('active');this.updateContents_();},get acceleratorKey(){return this.acceleratorKey_;},set acceleratorKey(acceleratorKey){this.acceleratorKey_=acceleratorKey;this.updateContents_();},updateContents_:function(){if(this.modeName===undefined)
@@ -5878,703 +5958,7 @@
 tr.b.Settings.set(this.settingsKey_+'.pos',this.pos);},constrainPositionToBounds_:function(pos){var parent=this.offsetParent||document.body;var parentRect=tr.ui.b.windowRectForElement(parent);var top=0;var bottom=parentRect.height-this.offsetHeight;var left=0;var right=parentRect.width-this.offsetWidth;var res={};res.x=Math.max(pos.x,left);res.x=Math.min(res.x,right);res.y=Math.max(pos.y,top);res.y=Math.min(res.y,bottom);return res;},onDragHandleMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();var mouseDownPos={x:e.clientX-this.offsetLeft,y:e.clientY-this.offsetTop};tr.ui.b.trackMouseMovesUntilMouseUp(function(e){var pos={};pos.x=e.clientX-mouseDownPos.x;pos.y=e.clientY-mouseDownPos.y;this.pos=pos;}.bind(this));},checkIsClick_:function(e){if(!this.isInteracting_||!this.isClick_)
 return;var deltaX=this.mousePos_.x-this.mouseDownPos_.x;var deltaY=this.mousePos_.y-this.mouseDownPos_.y;var minDist=MIN_MOUSE_SELECTION_DISTANCE;if(deltaX*deltaX+deltaY*deltaY>minDist*minDist)
 this.isClick_=false;},dispatchClickEvents_:function(e){if(!this.isClick_)
-return;var modeInfo=MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION];var eventNames=modeInfo.eventNames;var mouseEvent=this.createEvent_(eventNames.begin);mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);mouseEvent=this.createEvent_(eventNames.end);this.dispatchEvent(mouseEvent);}});return{MIN_MOUSE_SELECTION_DISTANCE:MIN_MOUSE_SELECTION_DISTANCE,MODIFIER:MODIFIER};});'use strict';tr.exportTo('tr.ui.b',function(){function TimingTool(viewport,targetElement){this.viewport_=viewport;this.onMouseMove_=this.onMouseMove_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.targetElement_=targetElement;this.isMovingLeftEdge_=false;};TimingTool.prototype={onEnterTiming:function(e){this.targetElement_.addEventListener('mousemove',this.onMouseMove_);this.targetElement_.addEventListener('dblclick',this.onDblClick_);},onBeginTiming:function(e){if(!this.isTouchPointInsideTrackBounds_(e.clientX,e.clientY))
-return;var pt=this.getSnappedToEventPosition_(e);this.mouseDownAt_(pt.x,pt.y);this.updateSnapIndicators_(pt);},updateSnapIndicators_:function(pt){if(!pt.snapped)
-return;var ir=this.viewport_.interestRange;if(ir.min===pt.x)
-ir.leftSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);if(ir.max===pt.x)
-ir.rightSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);},onUpdateTiming:function(e){var pt=this.getSnappedToEventPosition_(e);this.mouseMoveAt_(pt.x,pt.y,true);this.updateSnapIndicators_(pt);},onEndTiming:function(e){this.mouseUp_();},onExitTiming:function(e){this.targetElement_.removeEventListener('mousemove',this.onMouseMove_);this.targetElement_.removeEventListener('dblclick',this.onDblClick_);},onMouseMove_:function(e){if(e.button)
-return;var worldX=this.getWorldXFromEvent_(e);this.mouseMoveAt_(worldX,e.clientY,false);},onDblClick_:function(e){console.error('not implemented');},isTouchPointInsideTrackBounds_:function(clientX,clientY){if(!this.viewport_||!this.viewport_.modelTrackContainer||!this.viewport_.modelTrackContainer.canvas)
-return false;var canvas=this.viewport_.modelTrackContainer.canvas;var canvasRect=canvas.getBoundingClientRect();if(clientX>=canvasRect.left&&clientX<=canvasRect.right&&clientY>=canvasRect.top&&clientY<=canvasRect.bottom)
-return true;return false;},mouseDownAt_:function(worldX,y){var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(ir.isEmpty){ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;return;}
-if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.min=worldX;this.isMovingLeftEdge_=true;return;}
-if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.rightSelected=true;ir.max=worldX;this.isMovingLeftEdge_=false;return;}
-ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;},mouseMoveAt_:function(worldX,y,mouseDown){var ir=this.viewport_.interestRange;if(mouseDown){this.updateMovingEdge_(worldX);return;}
-var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.rightSelected=false;return;}
-if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.leftSelected=false;ir.rightSelected=true;return;}
-ir.leftSelected=false;ir.rightSelected=false;return;},updateMovingEdge_:function(newWorldX){var ir=this.viewport_.interestRange;var a=ir.min;var b=ir.max;if(this.isMovingLeftEdge_)
-a=newWorldX;else
-b=newWorldX;if(a<=b)
-ir.setMinAndMax(a,b);else
-ir.setMinAndMax(b,a);if(ir.min==newWorldX){this.isMovingLeftEdge_=true;ir.leftSelected=true;ir.rightSelected=false;}else{this.isMovingLeftEdge_=false;ir.leftSelected=false;ir.rightSelected=true;}},mouseUp_:function(){var dt=this.viewport_.currentDisplayTransform;var ir=this.viewport_.interestRange;ir.leftSelected=false;ir.rightSelected=false;var pixelRatio=window.devicePixelRatio||1;var minWidthValue=dt.xViewVectorToWorld(2*pixelRatio);if(ir.range<minWidthValue)
-ir.reset();},getWorldXFromEvent_:function(e){var pixelRatio=window.devicePixelRatio||1;var canvas=this.viewport_.modelTrackContainer.canvas;var worldOffset=canvas.getBoundingClientRect().left;var viewX=(e.clientX-worldOffset)*pixelRatio;return this.viewport_.currentDisplayTransform.xViewToWorld(viewX);},getSnappedToEventPosition_:function(e){var pixelRatio=window.devicePixelRatio||1;var EVENT_SNAP_RANGE=16*pixelRatio;var modelTrackContainer=this.viewport_.modelTrackContainer;var modelTrackContainerRect=modelTrackContainer.getBoundingClientRect();var viewport=this.viewport_;var dt=viewport.currentDisplayTransform;var worldMaxDist=dt.xViewVectorToWorld(EVENT_SNAP_RANGE);var worldX=this.getWorldXFromEvent_(e);var mouseY=e.clientY;var selection=new tr.model.EventSet();modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,mouseY,mouseY,selection);if(!selection.length){modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,modelTrackContainerRect.top,modelTrackContainerRect.bottom,selection);}
-var minDistX=worldMaxDist;var minDistY=Infinity;var pixWidth=dt.xViewVectorToWorld(1);var result={x:worldX,y:mouseY-modelTrackContainerRect.top,height:0,snapped:false};var eventBounds=new tr.b.Range();for(var i=0;i<selection.length;i++){var event=selection[i];var track=viewport.trackForEvent(event);var trackRect=track.getBoundingClientRect();eventBounds.reset();event.addBoundsToRange(eventBounds);var eventX;if(Math.abs(eventBounds.min-worldX)<Math.abs(eventBounds.max-worldX)){eventX=eventBounds.min;}else{eventX=eventBounds.max;}
-var distX=eventX-worldX;var eventY=trackRect.top;var eventHeight=trackRect.height;var distY=Math.abs(eventY+eventHeight/2-mouseY);if((distX<=minDistX||Math.abs(distX-minDistX)<pixWidth)&&distY<minDistY){minDistX=distX;minDistY=distY;result.x=eventX;result.y=eventY+
-modelTrackContainer.scrollTop-modelTrackContainerRect.top;result.height=eventHeight;result.snapped=true;}}
-return result;}};return{TimingTool:TimingTool};});'use strict';tr.exportTo('tr.ui',function(){var kDefaultPanAnimatoinDurationMs=100.0;function TimelineDisplayTransformPanAnimation(deltaX,deltaY,opt_durationMs){this.deltaX=deltaX;this.deltaY=deltaY;if(opt_durationMs===undefined)
-this.durationMs=kDefaultPanAnimatoinDurationMs;else
-this.durationMs=opt_durationMs;this.startPanX=undefined;this.startPanY=undefined;this.startTimeMs=undefined;}
-TimelineDisplayTransformPanAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.deltaY!==0;},canTakeOverFor:function(existingAnimation){return existingAnimation instanceof TimelineDisplayTransformPanAnimation;},takeOverFor:function(existing,timestamp,target){var remainingDeltaXOnExisting=existing.goalPanX-target.panX;var remainingDeltaYOnExisting=existing.goalPanY-target.panY;var remainingTimeOnExisting=timestamp-(existing.startTimeMs+existing.durationMs);remainingTimeOnExisting=Math.max(remainingTimeOnExisting,0);this.deltaX+=remainingDeltaXOnExisting;this.deltaY+=remainingDeltaYOnExisting;this.durationMs+=remainingTimeOnExisting;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startPanX=target.panX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.panX=tr.b.lerp(percentDone,this.startPanX,this.goalPanX);if(this.affectsPanY)
-target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalPanY);return timestamp>=this.startTimeMs+this.durationMs;},get goalPanX(){return this.startPanX+this.deltaX;},get goalPanY(){return this.startPanY+this.deltaY;}};function TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,goalFocalPointY,zoomInRatioX,opt_durationMs){this.goalFocalPointXWorld=goalFocalPointXWorld;this.goalFocalPointXView=goalFocalPointXView;this.goalFocalPointY=goalFocalPointY;this.zoomInRatioX=zoomInRatioX;if(opt_durationMs===undefined)
-this.durationMs=kDefaultPanAnimatoinDurationMs;else
-this.durationMs=opt_durationMs;this.startTimeMs=undefined;this.startScaleX=undefined;this.goalScaleX=undefined;this.startPanY=undefined;}
-TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!=this.goalFocalPointY;},canTakeOverFor:function(existingAnimation){return false;},takeOverFor:function(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.scaleX=tr.b.lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalFocalPointY);}
-target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation:TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation:TimelineDisplayTransformZoomToAnimation};});'use strict';tr.exportTo('tr.ui.b',function(){var ContainerThatDecoratesItsChildren=tr.ui.b.define('div');ContainerThatDecoratesItsChildren.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.observer_=new WebKitMutationObserver(this.didMutate_.bind(this));this.observer_.observe(this,{childList:true});Object.defineProperty(this,'textContent',{get:undefined,set:this.onSetTextContent_});},appendChild:function(x){HTMLUnknownElement.prototype.appendChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},insertBefore:function(x,y){HTMLUnknownElement.prototype.insertBefore.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},removeChild:function(x){HTMLUnknownElement.prototype.removeChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},replaceChild:function(x,y){HTMLUnknownElement.prototype.replaceChild.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},onSetTextContent_:function(textContent){if(textContent!='')
-throw new Error('textContent can only be set to \'\'.');this.clear();},clear:function(){while(this.lastChild)
-HTMLUnknownElement.prototype.removeChild.call(this,this.lastChild);this.didMutate_(this.observer_.takeRecords());},didMutate_:function(records){this.beginDecorating_();for(var i=0;i<records.length;i++){var addedNodes=records[i].addedNodes;if(addedNodes){for(var j=0;j<addedNodes.length;j++)
-this.decorateChild_(addedNodes[j]);}
-var removedNodes=records[i].removedNodes;if(removedNodes){for(var j=0;j<removedNodes.length;j++){this.undecorateChild_(removedNodes[j]);}}}
-this.doneDecoratingForNow_();},decorateChild_:function(child){throw new Error('Not implemented');},undecorateChild_:function(child){throw new Error('Not implemented');},beginDecorating_:function(){},doneDecoratingForNow_:function(){}};return{ContainerThatDecoratesItsChildren:ContainerThatDecoratesItsChildren};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Track=tr.ui.b.define('track',tr.ui.b.ContainerThatDecoratesItsChildren);Track.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(viewport){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);if(viewport===undefined)
-throw new Error('viewport is required when creating a Track.');this.viewport_=viewport;this.classList.add('track');},get viewport(){return this.viewport_;},get drawingContainer(){var cur=this;while(cur){if(cur instanceof tr.ui.tracks.DrawingContainer)
-return cur;cur=cur.parentElement;}
-return undefined;},get eventContainer(){},invalidateDrawingContainer:function(){var dc=this.drawingContainer;if(dc)
-dc.invalidate();},context:function(){if(!this.parentNode)
-return undefined;if(!this.parentNode.context)
-throw new Error('Parent container does not support context() method.');return this.parentNode.context();},decorateChild_:function(childTrack){},undecorateChild_:function(childTrack){if(childTrack.detach)
-childTrack.detach();},updateContents_:function(){},drawTrack:function(type){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.draw(type,viewLWorld,viewRWorld);ctx.restore();},draw:function(type,viewLWorld,viewRWorld){},addEventsToTrackMap:function(eventToTrackMap){},addContainersToTrackMap:function(containerToTrackMap){},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loVY,hiVY,selection){var pixelRatio=window.devicePixelRatio||1;var dt=this.viewport.currentDisplayTransform;var viewPixWidthWorld=dt.xViewVectorToWorld(1);var loWX=dt.xViewToWorld(loVX*pixelRatio);var hiWX=dt.xViewToWorld(hiVX*pixelRatio);var clientRect=this.getBoundingClientRect();var a=Math.max(loVY,clientRect.top);var b=Math.min(hiVY,clientRect.bottom);if(a>b)
-return;this.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){},addClosestInstantEventToSelection:function(instantEvents,worldX,worldMaxDist,selection){var instantEvent=tr.b.findClosestElementInSortedArray(instantEvents,function(x){return x.start;},worldX,worldMaxDist);if(!instantEvent)
-return;selection.push(instantEvent);}};return{Track:Track};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={HEADING_WIDTH:250};return{constants:constants};});'use strict';tr.exportTo('tr.ui.tracks',function(){var DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};var DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';this.appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);},get canvas(){return this.canvas_;},context:function(){return this.ctx_;},viewportChange_:function(){this.invalidate();},invalidate:function(){if(this.rafPending_)
-return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_:function(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_:function(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);var typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(var idx in typesToDraw){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
-continue;this.children[i].drawTrack(typesToDraw[idx]);}}
-var pixelRatio=window.devicePixelRatio||1;var bounds=this.canvas_.getBoundingClientRect();var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld);},updateCanvasSizeIfNeeded_:function(){var visibleChildTracks=tr.b.asArray(this.children).filter(this.visibleFilter_);var thisBounds=this.getBoundingClientRect();var firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();var lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();var innerWidth=firstChildTrackBounds.width-
-tr.ui.b.constants.HEADING_WIDTH;var innerHeight=lastChildTrackBounds.bottom-firstChildTrackBounds.top;var pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!=innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
-if(this.canvas_.height!=innerHeight*pixelRatio){this.canvas_.height=innerHeight*pixelRatio;this.canvas_.style.height=innerHeight+'px';}},visibleFilter_:function(element){if(!(element instanceof tr.ui.tracks.Track))
-return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
-continue;var trackClientRect=this.children[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
-continue;this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer:DrawingContainer,DrawType:DrawType};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);};ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){var modelItem=this.modelItem_;if(modelItem===undefined)
-return SelectionState.NONE;return modelItem.selectionState;}};return{ProxySelectableItem:ProxySelectableItem};});'use strict';Polymer('tr-ui-heading',{DOWN_ARROW:String.fromCharCode(0x25BE),RIGHT_ARROW:String.fromCharCode(0x25B8),ready:function(viewport){this.style.width=(tr.ui.b.constants.HEADING_WIDTH-6)+'px';this.heading_='';this.expanded_=true;this.arrowVisible_=false;this.selectionGenerator_=undefined;this.updateContents_();},get heading(){return this.heading_;},set heading(text){if(this.heading_===text)
-return;this.heading_=text;this.updateContents_();},set arrowVisible(val){if(this.arrowVisible_===val)
-return;this.arrowVisible_=!!val;this.updateContents_();},set tooltip(text){this.$.heading.title=text;},set selectionGenerator(generator){if(this.selectionGenerator_===generator)
-return;this.selectionGenerator_=generator;this.updateContents_();},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)
-return;this.expanded_=!!expanded;this.updateContents_();},onHeadingDivClicked_:function(){this.dispatchEvent(new tr.b.Event('heading-clicked',{'bubbles':true}));},updateContents_:function(){if(this.arrowVisible_){this.$.arrow.style.display='';}else{this.$.arrow.style.display='none';this.$.heading.style.display=this.expanded_?'':'none';}
-if(this.arrowVisible_){this.$.arrow.textContent=this.expanded_?this.DOWN_ARROW:this.RIGHT_ARROW;}
-this.$.link.style.display='none';this.$.heading_content.style.display='none';if(this.selectionGenerator_){this.$.link.style.display='inline-block';this.$.link.selection=this.selectionGenerator_;this.$.link.textContent=this.heading_;}else{this.$.heading_content.style.display='inline-block';this.$.heading_content.textContent=this.heading_;}}});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){if(this.items_===undefined)
-return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var dumpRadiusView=this.dumpRadiusView;var itemRadiusWorld=dt.xViewVectorToWorld(height);var items=this.items_;var loI=tr.b.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);var oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';var drawItems=function(selected){for(var i=loI;i<items.length;++i){var item=items[i];var x=item.start;if(x-itemRadiusWorld>viewRWorld)
-break;if(item.selected!==selected)
-continue;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
-ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap:function(eventToTrackMap){if(this.items_===undefined)
-return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)
-return;var itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.items_===undefined)
-return;var items=this.items_;var index=tr.b.findFirstIndexInArray(items,function(item){return item.modelItem===event;});if(index===-1)
-return false;var newIndex=index+offset;if(newIndex>=0&&newIndex<items.length){items[newIndex].addToSelection(selection);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)
-return;var item=tr.b.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)
-return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;};LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack:LetterDotTrack,LetterDot:LetterDot};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
-this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack:AlertTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Task=tr.b.Task;var ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach:function(){this.textContent='';},get tracks_(){var tracks=[];for(var i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track)
-tracks.push(this.children[i]);}
-return tracks;},drawTrack:function(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b)
-this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}
-tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i)
-this.children[i].addEventsToTrackMap(eventToTrackMap);},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.tracks_.length;i++)
-this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var task=new Task();for(var i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}}(i),this);}
-return task;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap:function(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_:function(){this.tracks_.forEach(function(track){this.removeChild(track);},this);}};return{ContainerTrack:ContainerTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartAxis(opt_min,opt_max){this.guid_=tr.b.GUID.allocate();this.bounds=new tr.b.Range();if(opt_min!==undefined)
-this.bounds.addValue(opt_min);if(opt_max!==undefined)
-this.bounds.addValue(opt_max);};ChartAxis.prototype={get guid(){return this.guid_;},valueToUnitRange:function(value){if(this.bounds.isEmpty)
-throw new Error('Chart axis bounds are empty');var bounds=this.bounds;if(bounds.range===0)
-return 0;return(value-bounds.min)/bounds.range;},autoSetFromSeries:function(series,opt_config){var range=new tr.b.Range();series.forEach(function(s){range.addRange(s.range);},this);this.autoSetFromRange(range,opt_config);},autoSetFromRange:function(range,opt_config){if(range.isEmpty)
-return;var bounds=this.bounds;if(bounds.isEmpty){bounds.addRange(range);return;}
-if(!opt_config)
-return;var useRangeMin=(opt_config.expandMin&&range.min<bounds.min||opt_config.shrinkMin&&range.min>bounds.min);var useRangeMax=(opt_config.expandMax&&range.max>bounds.max||opt_config.shrinkMax&&range.max<bounds.max);if(!useRangeMin&&!useRangeMax)
-return;if(useRangeMin&&useRangeMax){bounds.min=range.min;bounds.max=range.max;return;}
-if(useRangeMin){bounds.min=Math.min(range.min,bounds.max);}else{bounds.max=Math.max(range.max,bounds.min);}}};return{ChartAxis:ChartAxis};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.yBase=opt_yBase;};ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{ChartPoint:ChartPoint};});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var ChartSeriesType={LINE:0,AREA:1};var DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5};var LAST_POINT_WIDTH=16;var ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,axis,opt_renderingConfig){this.points=points;this.axis=axis;this.useRenderingConfig_(opt_renderingConfig);}
-ChartSeries.prototype={useRenderingConfig_:function(opt_renderingConfig){var config=opt_renderingConfig||{};tr.b.iterItems(DEFAULT_RENDERING_CONFIG,function(key,defaultValue){var value=config[key];if(value===undefined)
-value=defaultValue;this[key+'_']=value;},this);this.topPadding=this.bottomPadding=Math.max(this.selectedPointSize_,this.unselectedPointSize_)/2;},get range(){var range=new tr.b.Range();this.points.forEach(function(point){range.addValue(point.y);},this);return range;},draw:function(ctx,transform,highDetails){if(this.points===undefined||this.points.length===0)
-return;if(this.chartType_===ChartSeriesType.AREA){this.drawComponent_(ctx,transform,ChartSeriesComponent.BACKGROUND,highDetails);}
-if(this.chartType_===ChartSeriesType.LINE||highDetails){this.drawComponent_(ctx,transform,ChartSeriesComponent.LINE,highDetails);}
-this.drawComponent_(ctx,transform,ChartSeriesComponent.DOTS,highDetails);},drawComponent_:function(ctx,transform,component,highDetails){var extraPixels=0;if(component===ChartSeriesComponent.DOTS){extraPixels=Math.max(this.selectedPointSize_,this.unselectedPointSize_);}
-var leftViewX=transform.leftViewX-extraPixels*transform.pixelRatio;var rightViewX=transform.rightViewX+
-extraPixels*transform.pixelRatio;var leftTimestamp=transform.leftTimestamp-extraPixels;var rightTimestamp=transform.rightTimestamp+extraPixels;var firstVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},leftTimestamp);var lastVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},rightTimestamp);if(lastVisibleIndex>=this.points.length||this.points[lastVisibleIndex].x>rightTimestamp){lastVisibleIndex--;}
-var viewSkipDistance=this.skipDistance_*transform.pixelRatio;var circleRadius;var squareSize;var squareHalfSize;var squareOpacity;switch(component){case ChartSeriesComponent.DOTS:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=transform.pixelRatio;circleRadius=(this.selectedPointSize_/2)*transform.pixelRatio;squareSize=this.unselectedPointSize_*transform.pixelRatio;squareHalfSize=squareSize/2;if(!highDetails){squareOpacity=0;break;}
-var visibleIndexRange=lastVisibleIndex-firstVisibleIndex;if(visibleIndexRange<=0){squareOpacity=1;break;}
-var visibleViewXRange=transform.worldXToViewX(this.points[lastVisibleIndex].x)-
-transform.worldXToViewX(this.points[firstVisibleIndex].x);if(visibleViewXRange===0){squareOpacity=1;break;}
-var density=visibleIndexRange/visibleViewXRange;var clampedDensity=tr.b.clamp(density,this.unselectedPointDensityOpaque_,this.unselectedPointDensityTransparent_);var densityRange=this.unselectedPointDensityTransparent_-
-this.unselectedPointDensityOpaque_;squareOpacity=(this.unselectedPointDensityTransparent_-clampedDensity)/densityRange;break;case ChartSeriesComponent.LINE:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=this.lineWidth_*transform.pixelRatio;break;case ChartSeriesComponent.BACKGROUND:break;default:throw new Error('Invalid component: '+component);}
-var previousViewX=undefined;var previousViewY=undefined;var previousViewYBase=undefined;var lastSelectionState=undefined;var baseSteps=undefined;var startIndex=Math.max(firstVisibleIndex-1,0);for(var i=startIndex;i<this.points.length;i++){var currentPoint=this.points[i];var currentViewX=transform.worldXToViewX(currentPoint.x);if(currentViewX>rightViewX){if(previousViewX!==undefined){previousViewX=currentViewX=rightViewX;if(component===ChartSeriesComponent.BACKGROUND||component===ChartSeriesComponent.LINE){ctx.lineTo(currentViewX,previousViewY);}}
-break;}
-if(i+1<this.points.length){var nextPoint=this.points[i+1];var nextViewX=transform.worldXToViewX(nextPoint.x);if(previousViewX!==undefined&&nextViewX-previousViewX<=viewSkipDistance&&nextViewX<rightViewX){continue;}
-if(currentViewX<leftViewX){currentViewX=leftViewX;}}
-if(previousViewX!==undefined&&currentViewX-previousViewX<viewSkipDistance){currentViewX=previousViewX+viewSkipDistance;}
-var currentViewY=Math.round(transform.worldYToViewY(currentPoint.y));var currentViewYBase;if(currentPoint.yBase===undefined){currentViewYBase=transform.outerBottomViewY;}else{currentViewYBase=Math.round(transform.worldYToViewY(currentPoint.yBase));}
-var currentSelectionState=currentPoint.selectionState;switch(component){case ChartSeriesComponent.DOTS:if(currentSelectionState!==lastSelectionState){if(currentSelectionState===SelectionState.SELECTED){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState);}else if(squareOpacity>0){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,squareOpacity);}}
-if(currentSelectionState===SelectionState.SELECTED){ctx.beginPath();ctx.arc(currentViewX,currentViewY,circleRadius,0,2*Math.PI);ctx.fill();ctx.stroke();}else if(squareOpacity>0){ctx.fillRect(currentViewX-squareHalfSize,currentViewY-squareHalfSize,squareSize,squareSize);}
-break;case ChartSeriesComponent.LINE:if(previousViewX===undefined){ctx.beginPath();ctx.moveTo(currentViewX,currentViewY);}else{ctx.lineTo(currentViewX,previousViewY);}
-ctx.lineTo(currentViewX,currentViewY);break;case ChartSeriesComponent.BACKGROUND:if(previousViewX!==undefined)
-ctx.lineTo(currentViewX,previousViewY);if(currentSelectionState!==lastSelectionState){if(previousViewX!==undefined){var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
-ctx.closePath();ctx.fill();}
-ctx.beginPath();ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,this.backgroundOpacity_);ctx.moveTo(currentViewX,currentViewYBase);baseSteps=[];}
-if(currentViewYBase!==previousViewYBase||currentSelectionState!==lastSelectionState){baseSteps.push({viewX:currentViewX,viewY:currentViewYBase});}
-ctx.lineTo(currentViewX,currentViewY);break;default:throw new Error('Not reachable');}
-previousViewX=currentViewX;previousViewY=currentViewY;previousViewYBase=currentViewYBase;lastSelectionState=currentSelectionState;}
-if(previousViewX!==undefined){switch(component){case ChartSeriesComponent.DOTS:break;case ChartSeriesComponent.LINE:ctx.stroke();break;case ChartSeriesComponent.BACKGROUND:var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
-ctx.closePath();ctx.fill();break;default:throw new Error('Not reachable');}}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var points=this.points;function getPointWidth(point,i){if(i===points.length-1)
-return LAST_POINT_WIDTH*viewPixWidthWorld;var nextPoint=points[i+1];return nextPoint.x-point.x;}
-function selectPoint(point){point.addToSelection(selection);}
-tr.b.iterateOverIntersectingIntervals(this.points,function(point){return point.x},getPointWidth,loWX,hiWX,selectPoint);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.points===undefined)
-return false;var index=tr.b.findFirstIndexInArray(this.points,function(point){return point.modelItem===event;},this);if(index===-1)
-return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.points.length)
-return false;this.points[newIndex].addToSelection(selection);return true;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.points===undefined)
-return;var item=tr.b.findClosestElementInSortedArray(this.points,function(point){return point.x},worldX,worldMaxDist);if(!item)
-return;item.addToSelection(selection);}};return{ChartSeries:ChartSeries,ChartSeriesType:ChartSeriesType};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartTransform(displayTransform,axis,trackWidth,trackHeight,topPadding,bottomPadding,pixelRatio){this.pixelRatio=pixelRatio;this.leftViewX=0;this.rightViewX=trackWidth;this.leftTimestamp=displayTransform.xViewToWorld(this.leftViewX);this.rightTimestamp=displayTransform.xViewToWorld(this.rightViewX);this.displayTransform_=displayTransform;this.outerTopViewY=0;this.innerTopViewY=topPadding;this.innerBottomViewY=trackHeight-bottomPadding;this.outerBottomViewY=trackHeight;this.axis_=axis;this.innerHeight_=this.innerBottomViewY-this.innerTopViewY;};ChartTransform.prototype={worldXToViewX:function(worldX){return this.displayTransform_.xWorldToView(worldX);},viewXToWorldX:function(viewX){return this.displayTransform_.xViewToWorld(viewX);},worldYToViewY:function(worldY){var innerHeightCoefficient=1-this.axis_.valueToUnitRange(worldY);return innerHeightCoefficient*this.innerHeight_+this.innerTopViewY;}};return{ChartTransform:ChartTransform};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ChartTrack=tr.ui.b.define('chart-track',tr.ui.tracks.Track);ChartTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('chart-track');this.series_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get series(){return this.series_;},set series(series){this.series_=series;this.calculateAxisDataAndPadding_();this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return!!this.series&&this.series.length>0;},calculateAxisDataAndPadding_:function(){if(!this.series_){this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;return;}
-var axisGuidToAxisData={};var topPadding=0;var bottomPadding=0;this.series_.forEach(function(series){var axis=series.axis;var axisGuid=axis.guid;if(!(axisGuid in axisGuidToAxisData)){axisGuidToAxisData[axisGuid]={axis:axis,series:[]};}
-axisGuidToAxisData[axisGuid].series.push(series);topPadding=Math.max(topPadding,series.topPadding);bottomPadding=Math.max(bottomPadding,series.bottomPadding);},this);this.axisGuidToAxisData_=axisGuidToAxisData;this.topPadding_=topPadding;this.bottomPadding_=bottomPadding;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawChart_(viewLWorld,viewRWorld);break;}},drawChart_:function(viewLWorld,viewRWorld){if(!this.series_)
-return;var ctx=this.context();var displayTransform=this.viewport.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var highDetails=this.viewport.highDetails;var width=bounds.width*pixelRatio;var height=bounds.height*pixelRatio;var topPadding=this.topPadding_*pixelRatio;var bottomPadding=this.bottomPadding_*pixelRatio;ctx.save();ctx.beginPath();ctx.rect(0,0,width,height);ctx.clip();this.series_.forEach(function(series){var chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,series.axis,width,height,topPadding,bottomPadding,pixelRatio);series.draw(ctx,chartTransform,highDetails);},this);ctx.restore();},addEventsToTrackMap:function(eventToTrackMap){this.series_.forEach(function(series){series.points.forEach(function(point){point.addToTrackMap(eventToTrackMap,this);},this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){this.series_.forEach(function(series){series.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},this);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var foundItem=false;this.series_.forEach(function(series){foundItem=foundItem||series.addEventNearToProvidedEventToSelection(event,offset,selection);},this);return foundItem;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.series_.forEach(function(series){series.addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);},this);},autoSetAllAxes:function(opt_config){tr.b.iterItems(this.axisGuidToAxisData_,function(axisGuid,axisData){var axis=axisData.axis;var series=axisData.series;axis.autoSetFromSeries(series,opt_config);},this);},autoSetAxis:function(axis,opt_config){var series=this.axisGuidToAxisData_[axis.guid].series;axis.autoSetFromSeries(series,opt_config);}};return{ChartTrack:ChartTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ChartTrack=tr.ui.tracks.ChartTrack;var PowerSeriesTrack=tr.ui.b.define('power-series-track',ChartTrack);PowerSeriesTrack.prototype={__proto__:ChartTrack.prototype,decorate:function(viewport){ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('power-series-track');this.heading='Power';this.powerSeries_=undefined;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return(this.powerSeries_&&this.powerSeries_.samples.length>0);},addContainersToTrackMap:function(containerToTrackMap){containerToTrackMap.addContainer(this.powerSeries_,this);},buildChartSeries_:function(){if(!this.hasVisibleContent)
-return[];var axis=new tr.ui.tracks.ChartAxis(0,undefined);var pts=this.powerSeries_.samples.map(function(smpl){return new tr.ui.tracks.ChartPoint(smpl,smpl.start,smpl.power);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString(this.heading)};return[new tr.ui.tracks.ChartSeries(pts,axis,renderingConfig)];}};return{PowerSeriesTrack:PowerSeriesTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SpacingTrack=tr.ui.b.define('spacing-track',tr.ui.tracks.Track);SpacingTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('spacing-track');this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},draw:function(type,viewLWorld,viewRWorld){},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{SpacingTrack:SpacingTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ContainerTrack=tr.ui.tracks.ContainerTrack;var DeviceTrack=tr.ui.b.define('device-track',ContainerTrack);DeviceTrack.prototype={__proto__:ContainerTrack.prototype,decorate:function(viewport){ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('device-track');this.device_=undefined;this.powerSeriesTrack_=undefined;},get device(){return this.device_;},set device(device){this.device_=device;this.updateContents_();},get powerSeriesTrack(){return this.powerSeriesTrack_;},get hasVisibleContent(){return(this.powerSeriesTrack_&&this.powerSeriesTrack_.hasVisibleContent);},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.device,this);},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},appendPowerSeriesTrack_:function(){this.powerSeriesTrack_=new tr.ui.tracks.PowerSeriesTrack(this.viewport);this.powerSeriesTrack_.powerSeries=this.device.powerSeries;if(this.powerSeriesTrack_.hasVisibleContent){this.appendChild(this.powerSeriesTrack_);this.appendChild(new tr.ui.tracks.SpacingTrack(this.viewport));}},updateContents_:function(){this.clearTracks_();this.appendPowerSeriesTrack_();}};return{DeviceTrack:DeviceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var DISPLAYED_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_ATTRIBUTE_NAME;function addDictionary(dstDict,srcDict){tr.b.iterItems(srcDict,function(key,value){var existingValue=dstDict[key];if(existingValue===undefined)
-existingValue=0;dstDict[key]=existingValue+value;});}
-function getProcessMemoryDumpAllocatorSizes(processMemoryDump){var allocatorDumps=processMemoryDump.memoryAllocatorDumps;if(allocatorDumps===undefined)
-return{};var allocatorSizes={};allocatorDumps.forEach(function(allocatorDump){if(allocatorDump.fullName==='tracing')
-return;var allocatorSize=allocatorDump.attributes[DISPLAYED_SIZE_ATTRIBUTE_NAME];if(allocatorSize===undefined)
-return;var allocatorSizeValue=allocatorSize.value;if(allocatorSizeValue===undefined)
-return;allocatorSizes[allocatorDump.fullName]=allocatorSizeValue;});return allocatorSizes;};function getGlobalMemoryDumpAllocatorSizes(globalMemoryDump){var globalAllocatorSizes={};tr.b.iterItems(globalMemoryDump.processMemoryDumps,function(pid,processMemoryDump){addDictionary(globalAllocatorSizes,getProcessMemoryDumpAllocatorSizes(processMemoryDump));});return globalAllocatorSizes;}
-function buildAllocatedMemoryChartSeries(memoryDumps,memoryDumpToAllocatorSizesFn){var allocatorNameToPoints={};var dumpsData=memoryDumps.map(function(memoryDump){var allocatorSizes=memoryDumpToAllocatorSizesFn(memoryDump);tr.b.iterItems(allocatorSizes,function(allocatorName){allocatorNameToPoints[allocatorName]=[];});return{dump:memoryDump,sizes:allocatorSizes};});if(Object.keys(allocatorNameToPoints).length===0)
-return undefined;dumpsData.forEach(function(dumpData){var memoryDump=dumpData.dump;var allocatorSizes=dumpData.sizes;tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var allocatorSize=allocatorSizes[allocatorName]||0;points.push(new tr.ui.tracks.ChartPoint(memoryDump,memoryDump.start,allocatorSize));});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var colorId=ColorScheme.getColorIdForGeneralPurposeString(allocatorName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.LINE,colorId:colorId};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});return series;}
-function buildMemoryLetterDots(memoryDumps){var lightMemoryColorId=ColorScheme.getColorIdForReservedName('light_memory_dump');var detailedMemoryColorId=ColorScheme.getColorIdForReservedName('detailed_memory_dump');return memoryDumps.map(function(memoryDump){var memoryColorId;switch(memoryDump.levelOfDetail){case'detailed':memoryColorId=detailedMemoryColorId;break;case'light':default:memoryColorId=lightMemoryColorId;}
-return new tr.ui.tracks.LetterDot(memoryDump,'M',memoryColorId,memoryDump.start);});}
-function buildGlobalUsedMemoryChartSeries(globalMemoryDumps){var containsVmRegions=globalMemoryDumps.some(function(globalDump){for(var pid in globalDump.processMemoryDumps)
-if(globalDump.processMemoryDumps[pid].mostRecentVmRegions)
-return true;return false;});if(!containsVmRegions)
-return undefined;var pidToProcess={};globalMemoryDumps.forEach(function(globalDump){tr.b.iterItems(globalDump.processMemoryDumps,function(pid,processDump){pidToProcess[pid]=processDump.process;});});var pidToPoints={};tr.b.iterItems(pidToProcess,function(pid,process){pidToPoints[pid]=[];});globalMemoryDumps.forEach(function(globalDump){var pssBase=0;tr.b.iterItems(pidToPoints,function(pid,points){var processMemoryDump=globalDump.processMemoryDumps[pid];var pss;if(processMemoryDump===undefined){pss=0;}else{pss=processMemoryDump.getMostRecentTotalVmRegionStat('proportionalResident');if(pss===undefined){pss=0;}}
-var cumulativePss=pssBase+pss;points.push(new tr.ui.tracks.ChartPoint(globalDump,globalDump.start,cumulativePss,pssBase));pssBase=cumulativePss;});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(pidToPoints,function(pid,points){var process=pidToProcess[pid];var colorId=ColorScheme.getColorIdForGeneralPurposeString(process.userFriendlyName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:colorId,backgroundOpacity:0.8};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});series.reverse();return series;}
-function buildProcessAllocatedMemoryChartSeries(processMemoryDumps){return buildAllocatedMemoryChartSeries(processMemoryDumps,getProcessMemoryDumpAllocatorSizes);}
-function buildGlobalAllocatedMemoryChartSeries(globalMemoryDumps){return buildAllocatedMemoryChartSeries(globalMemoryDumps,getGlobalMemoryDumpAllocatorSizes);}
-return{buildMemoryLetterDots:buildMemoryLetterDots,buildGlobalUsedMemoryChartSeries:buildGlobalUsedMemoryChartSeries,buildProcessAllocatedMemoryChartSeries:buildProcessAllocatedMemoryChartSeries,buildGlobalAllocatedMemoryChartSeries:buildGlobalAllocatedMemoryChartSeries};});'use strict';tr.exportTo('tr.ui.tracks',function(){var USED_MEMORY_TRACK_HEIGHT=50;var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var GlobalMemoryDumpTrack=tr.ui.b.define('global-memory-dump-track',tr.ui.tracks.ContainerTrack);GlobalMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
-return;this.appendDumpDotsTrack_();this.appendUsedMemoryTrack_();this.appendAllocatedMemoryTrack_();},appendDumpDotsTrack_:function(){var items=tr.ui.tracks.buildMemoryLetterDots(this.memoryDumps_);if(!items)
-return;var track=new tr.ui.tracks.LetterDotTrack(this.viewport);track.heading='Memory Dumps';track.items=items;this.appendChild(track);},appendUsedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalUsedMemoryChartSeries(this.memoryDumps_);if(!series)
-return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per process';track.height=USED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
-return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{GlobalMemoryDumpTrack:GlobalMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function Highlighter(viewport){if(viewport===undefined){throw new Error('viewport must be provided');}
-this.viewport_=viewport;};Highlighter.prototype={__proto__:Object.prototype,processModel:function(model){throw new Error('processModel implementation missing');},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){throw new Error('drawHighlight implementation missing');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Highlighter;tr.b.decorateExtensionRegistry(Highlighter,options);return{Highlighter:Highlighter};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate:function(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem:function(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){var numSeries=counter.series.length;var totals=counter.totals;var chartAxis=new tr.ui.tracks.ChartAxis(0,undefined);var chartSeries=counter.series.map(function(series,seriesIndex){var chartPoints=series.samples.map(function(sample,sampleIndex){var total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,chartAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack:CounterTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var startCompare=function(x,y){return x.start-y.start;}
-var FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)
-return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
-FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack:FrameTrack};});'use strict';tr.exportTo('tr.model',function(){var Settings=tr.b.Settings;function ModelSettings(model){this.model=model;this.objectsByKey_=[];this.nonuniqueKeys_=[];this.buildObjectsByKeyMap_();this.removeNonuniqueKeysFromSettings_();this.ephemeralSettingsByGUID_={};}
-ModelSettings.prototype={buildObjectsByKeyMap_:function(){var objects=[];this.model.iterateAllPersistableObjects(function(o){objects.push(o);});var objectsByKey={};var NONUNIQUE_KEY='nonuniqueKey';for(var i=0;i<objects.length;i++){var object=objects[i];var objectKey=object.getSettingsKey();if(!objectKey)
-continue;if(objectsByKey[objectKey]===undefined){objectsByKey[objectKey]=object;continue;}
-objectsByKey[objectKey]=NONUNIQUE_KEY;}
-var nonuniqueKeys={};tr.b.dictionaryKeys(objectsByKey).forEach(function(objectKey){if(objectsByKey[objectKey]!==NONUNIQUE_KEY)
-return;delete objectsByKey[objectKey];nonuniqueKeys[objectKey]=true;});this.nonuniqueKeys=nonuniqueKeys;this.objectsByKey_=objectsByKey;},removeNonuniqueKeysFromSettings_:function(){var settings=Settings.get('trace_model_settings',{});var settingsChanged=false;tr.b.dictionaryKeys(settings).forEach(function(objectKey){if(!this.nonuniqueKeys[objectKey])
-return;settingsChanged=true;delete settings[objectKey];},this);if(settingsChanged)
-Settings.set('trace_model_settings',settings);},hasUniqueSettingKey:function(object){var objectKey=object.getSettingsKey();if(!objectKey)
-return false;return this.objectsByKey_[objectKey]!==undefined;},getSettingFor:function(object,objectLevelKey,defaultValue){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){var settings=this.getEphemeralSettingsFor_(object);var ephemeralValue=settings[objectLevelKey];if(ephemeralValue!==undefined)
-return ephemeralValue;return defaultValue;}
-var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
-settings[objectKey]={};var value=settings[objectKey][objectLevelKey];if(value!==undefined)
-return value;return defaultValue;},setSettingFor:function(object,objectLevelKey,value){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){this.getEphemeralSettingsFor_(object)[objectLevelKey]=value;return;}
-var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
-settings[objectKey]={};if(settings[objectKey][objectLevelKey]===value)
-return;settings[objectKey][objectLevelKey]=value;Settings.set('trace_model_settings',settings);},getEphemeralSettingsFor_:function(object){if(object.guid===undefined)
-throw new Error('Only objects with GUIDs can be persisted');if(this.ephemeralSettingsByGUID_[object.guid]===undefined)
-this.ephemeralSettingsByGUID_[object.guid]={};return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings:ModelSettings};});'use strict';tr.exportTo('tr.ui.tracks',function(){var MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.itemsGroupedOnLastUpdateContents_=undefined;this.currentSubRows_=[];this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup:function(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateContents_();},get subRows(){return this.currentSubRows_;},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_==expanded)
-return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_:function(e){if(this.subRows.length<=1)
-return;this.expanded=!this.expanded;if(this.groupingSource_){var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
-e.stopPropagation();},updateExpandedStateFromGroupingSource_:function(){if(this.groupingSource_){var numSubRows=this.subRows.length;var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){var defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
-this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_:function(){var minH=Math.max(2,Math.ceil(18/this.children.length));var h=(this.expanded_?18:minH)+'px';for(var i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0)
-this.children[i].arrowVisible=true;this.children[i].expanded=this.expanded;}
-if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_:function(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);if(!this.itemsToGroup_){this.updateHeadingAndTooltip_();this.currentSubRows_=[];return;}
-if(this.areArrayContentsSame_(this.itemsGroupedOnLastUpdateContents_,this.itemsToGroup_)){this.updateHeadingAndTooltip_();return;}
-this.itemsGroupedOnLastUpdateContents_=this.itemsToGroup_;this.detach();if(!this.itemsToGroup_.length){this.currentSubRows_=[];return;}
-var subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRows_=subRows;for(var srI=0;srI<subRows.length;srI++){var subRow=subRows[srI];if(!subRow.length)
-continue;var track=this.addSubTrack_(subRow);track.addEventListener('heading-clicked',this.onHeadingClicked_.bind(this));}
-this.updateHeadingAndTooltip_();this.expandedStateChanged_();},updateHeadingAndTooltip_:function(){if(!this.firstChild)
-return;this.firstChild.heading=this.heading_;this.firstChild.tooltip=this.tooltip_;},buildSubRows_:function(itemsToGroup){throw new Error('Not implemented');},addSubTrack_:function(subRowItems){throw new Error('Not implemented');},areArrayContentsSame_:function(a,b){if(!a||!b)
-return false;if(!a.length||!b.length)
-return false;if(a.length!=b.length)
-return false;for(var i=0;i<a.length;++i){if(a[i]!=b[i])
-return false;}
-return true;}};return{MultiRowTrack:MultiRowTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ObjectInstanceTrack=tr.ui.b.define('object-instance-track',tr.ui.tracks.Track);ObjectInstanceTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('object-instance-track');this.objectInstances_=[];this.objectSnapshots_=[];this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get objectInstances(){return this.objectInstances_;},set objectInstances(objectInstances){if(!objectInstances||objectInstances.length==0){this.heading='';this.objectInstances_=[];this.objectSnapshots_=[];return;}
-this.heading=objectInstances[0].typeName;this.objectInstances_=objectInstances;this.objectSnapshots_=[];this.objectInstances_.forEach(function(instance){this.objectSnapshots_.push.apply(this.objectSnapshots_,instance.snapshots);},this);this.objectSnapshots_.sort(function(a,b){return a.ts-b.ts;});},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get snapshotRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=dt.xViewVectorToWorld(height);var loI;ctx.save();dt.applyTransformToCanvas(ctx);var objectInstances=this.objectInstances_;var loI=tr.b.findLowIndexInSortedArray(objectInstances,function(instance){return instance.deletionTs;},viewLWorld);ctx.strokeStyle='rgb(0,0,0)';for(var i=loI;i<objectInstances.length;++i){var instance=objectInstances[i];var x=instance.creationTs;if(x>viewRWorld)
-break;var right=instance.deletionTs==Number.MAX_VALUE?viewRWorld:instance.deletionTs;ctx.fillStyle=EventPresenter.getObjectInstanceColor(instance);ctx.fillRect(x,pixelRatio,right-x,height-2*pixelRatio);}
-ctx.restore();var objectSnapshots=this.objectSnapshots_;loI=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts+snapshotRadiusWorld;},viewLWorld);for(var i=loI;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var x=snapshot.ts;if(x-snapshotRadiusWorld>viewRWorld)
-break;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getObjectSnapshotColor(snapshot);ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView,0,twoPi);ctx.fill();if(snapshot.selected){ctx.lineWidth=5;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView-1,0,twoPi);ctx.lineWidth=2;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}}
-ctx.lineWidth=1;var selectionState=SelectionState.NONE;if(objectInstances.length&&objectInstances[0].selectionState===SelectionState.DIMMED){selectionState=SelectionState.DIMMED;}
-if(selectionState===SelectionState.DIMMED){var width=bounds.width*pixelRatio;ctx.fillStyle='rgba(255,255,255,0.5)';ctx.fillRect(0,0,width,height);ctx.restore();}},addEventsToTrackMap:function(eventToTrackMap){if(this.objectInstance_!==undefined){this.objectInstance_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}
-if(this.objectSnapshots_!==undefined){this.objectSnapshots_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var foundSnapshot=false;function onSnapshot(snapshot){selection.push(snapshot);foundSnapshot=true;}
-var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=viewPixWidthWorld*snapshotRadiusView;tr.b.iterateOverIntersectingIntervals(this.objectSnapshots_,function(x){return x.ts-snapshotRadiusWorld;},function(x){return 2*snapshotRadiusWorld;},loWX,hiWX,onSnapshot);if(foundSnapshot)
-return;tr.b.iterateOverIntersectingIntervals(this.objectInstances_,function(x){return x.creationTs;},function(x){return x.deletionTs-x.creationTs;},loWX,hiWX,selection.push.bind(selection));},addEventNearToProvidedEventToSelection:function(event,offset,selection){var events;if(event instanceof tr.model.ObjectSnapshot)
-events=this.objectSnapshots_;else if(event instanceof tr.model.ObjectInstance)
-events=this.objectInstances_;else
-throw new Error('Unrecognized event');var index=events.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<events.length){selection.push(events[newIndex]);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectSnapshots_,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
-return;selection.push(snapshot);}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ObjectInstanceTrack,options);return{ObjectInstanceTrack:ObjectInstanceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectInstanceGroupTrack=tr.ui.b.define('object-instance-group-track',tr.ui.tracks.MultiRowTrack);ObjectInstanceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('object-instance-group-track');this.objectInstances_=undefined;},get objectInstances(){return this.itemsToGroup;},set objectInstances(objectInstances){this.setItemsToGroup(objectInstances);},addSubTrack_:function(objectInstances){var hasMultipleRows=this.subRows.length>1;var track=new tr.ui.tracks.ObjectInstanceTrack(this.viewport);track.objectInstances=objectInstances;this.appendChild(track);return track;},buildSubRows_:function(objectInstances){objectInstances.sort(function(x,y){return x.creationTs-y.creationTs;});var subRows=[];for(var i=0;i<objectInstances.length;i++){var objectInstance=objectInstances[i];var found=false;for(var j=0;j<subRows.length;j++){var subRow=subRows[j];var lastItemInSubRow=subRow[subRow.length-1];if(objectInstance.creationTs>=lastItemInSubRow.deletionTs){found=true;subRow.push(objectInstance);break;}}
-if(!found){var subRow=[objectInstance];subRows.push(subRow);}}
-return subRows;},updateHeadingAndTooltip_:function(){}};return{ObjectInstanceGroupTrack:ObjectInstanceGroupTrack};});'use strict';tr.exportTo('tr.ui.b',function(){function FastRectRenderer(ctx,minRectSize,maxMergeDist,pallette){this.ctx_=ctx;this.minRectSize_=minRectSize;this.maxMergeDist_=maxMergeDist;this.pallette_=pallette;}
-FastRectRenderer.prototype={y_:0,h_:0,merging_:false,mergeStartX_:0,mergeCurRight_:0,mergedColorId_:0,mergedAlpha_:0,setYandH:function(y,h){if(this.y_===y&&this.h_===h)
-return;this.flush();this.y_=y;this.h_=h;},fillRect:function(x,w,colorId,alpha){var r=x+w;if(w<this.minRectSize_){if(r-this.mergeStartX_>this.maxMergeDist_)
-this.flush();if(!this.merging_){this.merging_=true;this.mergeStartX_=x;this.mergeCurRight_=r;this.mergedColorId_=colorId;this.mergedAlpha_=alpha;}else{this.mergeCurRight_=r;if(this.mergedAlpha_<alpha||(this.mergedAlpha_===alpha&&this.mergedColorId_<colorId)){this.mergedAlpha_=alpha;this.mergedColorId_=colorId;}}}else{if(this.merging_)
-this.flush();this.ctx_.fillStyle=this.pallette_[colorId];this.ctx_.globalAlpha=alpha;this.ctx_.fillRect(x,this.y_,w,this.h_);}},flush:function(){if(this.merging_){this.ctx_.fillStyle=this.pallette_[this.mergedColorId_];this.ctx_.globalAlpha=this.mergedAlpha_;this.ctx_.fillRect(this.mergeStartX_,this.y_,this.mergeCurRight_-this.mergeStartX_,this.h_);this.merging_=false;}}};return{FastRectRenderer:FastRectRenderer};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RectTrack=tr.ui.b.define('rect-track',tr.ui.tracks.Track);RectTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('rect-track');this.asyncStyle_=false;this.rects_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},set selectionGenerator(generator){this.heading_.selectionGenerator=generator;},set expanded(expanded){this.heading_.expanded=!!expanded;},set arrowVisible(arrowVisible){this.heading_.arrowVisible=!!arrowVisible;},get expanded(){return this.heading_.expanded;},get asyncStyle(){return this.asyncStyle_;},set asyncStyle(v){this.asyncStyle_=!!v;},get rects(){return this.rects_;},set rects(rects){this.rects_=rects||[];this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return this.rects_.length>0;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawRects_(viewLWorld,viewRWorld);break;}},drawRects_:function(viewLWorld,viewRWorld){var ctx=this.context();ctx.save();var bounds=this.getBoundingClientRect();tr.ui.b.drawSlices(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.rects_,this.asyncStyle_);ctx.restore();if(bounds.height<=6)
-return;var fontSize,yOffset;if(bounds.height<15){fontSize=6;yOffset=1.0;}else{fontSize=10;yOffset=2.5;}
-tr.ui.b.drawLabels(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,this.rects_,this.asyncStyle_,fontSize,yOffset);},addEventsToTrackMap:function(eventToTrackMap){if(this.rects_===undefined||this.rects_===null)
-return;this.rects_.forEach(function(rect){rect.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onRect(rect){rect.addToSelection(selection);}
-onRect=onRect.bind(this);var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.rects_,function(x){return x.start;},function(x){return x.duration==0?x.duration+instantEventWidth:x.duration;},loWX,hiWX,onRect);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var index=tr.b.findFirstIndexInArray(this.rects_,function(rect){return rect.modelItem===event;});if(index===-1)
-return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.rects_.length)
-return false;this.rects_[newIndex].addToSelection(selection);return true;},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.rects_.length;++i){var modelItem=this.rects_[i].modelItem;if(!modelItem)
-continue;if(filter.matchSlice(modelItem))
-selection.push(modelItem);}},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var rect=tr.b.findClosestIntervalInSortedIntervals(this.rects_,function(x){return x.start;},function(x){return x.end;},worldX,worldMaxDist);if(!rect)
-return;rect.addToSelection(selection);}};function Rect(modelItem,title,colorId,start,duration){tr.model.ProxySelectableItem.call(this,modelItem);this.title=title;this.colorId=colorId;this.start=start;this.duration=duration;this.end=start+duration;};Rect.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{RectTrack:RectTrack,Rect:Rect};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ProcessSummaryTrack=tr.ui.b.define('process-summary-track',tr.ui.tracks.RectTrack);ProcessSummaryTrack.buildRectsFromProcess=function(process){if(!process)
-return[];var ops=[];var pushOp=function(isStart,time,slice){ops.push({isStart:isStart,time:time,slice:slice});};for(var tid in process.threads){var sliceGroup=process.threads[tid].sliceGroup;sliceGroup.topLevelSlices.forEach(function(slice){pushOp(true,slice.start,undefined);pushOp(false,slice.end,undefined);});sliceGroup.slices.forEach(function(slice){if(slice.important){pushOp(true,slice.start,slice);pushOp(false,slice.end,slice);}});}
-ops.sort(function(a,b){return a.time-b.time;});var rects=[];var genericColorId=ColorScheme.getColorIdForReservedName('generic_work');var pushRect=function(start,end,slice){rects.push(new tr.ui.tracks.Rect(slice,slice?slice.title:'',slice?slice.colorId:genericColorId,start,end-start));}
-var depth=0;var currentSlice=undefined;var lastStart=undefined;ops.forEach(function(op){depth+=op.isStart?1:-1;if(currentSlice){if(!op.isStart&&op.slice==currentSlice){pushRect(lastStart,op.time,currentSlice);lastStart=depth>=1?op.time:undefined;currentSlice=undefined;}}else{if(op.isStart){if(depth==1){lastStart=op.time;currentSlice=op.slice;}else if(op.slice){if(op.time!=lastStart){pushRect(lastStart,op.time,undefined);lastStart=op.time;}
-currentSlice=op.slice;}}else{if(depth==0){pushRect(lastStart,op.time,undefined);lastStart=undefined;}}}});return rects;};ProcessSummaryTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get process(){return this.process_;},set process(process){this.process_=process;this.rects=ProcessSummaryTrack.buildRectsFromProcess(process);}};return{ProcessSummaryTrack:ProcessSummaryTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceTrack=tr.ui.b.define('slice-track',tr.ui.tracks.RectTrack);SliceTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get slices(){return this.rects;},set slices(slices){this.rects=slices;}};return{SliceTrack:SliceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AsyncSliceGroupTrack=tr.ui.b.define('async-slice-group-track',tr.ui.tracks.MultiRowTrack);AsyncSliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('async-slice-group-track');this.group_=undefined;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);track.asyncStyle=true;return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices,opt_skipSort){if(!opt_skipSort){slices.sort(function(x,y){return x.start-y.start;});}
-var findLevel=function(sliceToPut,rows,n){if(n>=rows.length)
-return true;var subRow=rows[n];var lastSliceInSubRow=subRow[subRow.length-1];if(sliceToPut.start>=lastSliceInSubRow.end){if(sliceToPut.subSlices===undefined||sliceToPut.subSlices.length===0){return true;}
-for(var i=0;i<sliceToPut.subSlices.length;i++){if(!findLevel(sliceToPut.subSlices[i],rows,n+1))
-return false;}
-return true;}
-return false;}
-var subRows=[];for(var i=0;i<slices.length;i++){var slice=slices[i];var found=false;var index=subRows.length;for(var j=0;j<subRows.length;j++){if(findLevel(slice,subRows,j)){found=true;index=j;break;}}
-if(!found)
-subRows.push([]);subRows[index].push(slice);var fitSubSlicesRecursively=function(subSlices,level,rows){if(subSlices===undefined||subSlices.length===0)
-return;if(level===rows.length)
-rows.push([]);for(var h=0;h<subSlices.length;h++){rows[level].push(subSlices[h]);fitSubSlicesRecursively(subSlices[h].subSlices,level+1,rows);}}
-fitSubSlicesRecursively(slice.subSlices,index+1,subRows);}
-return subRows;}};return{AsyncSliceGroupTrack:AsyncSliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SampleTrack=tr.ui.b.define('sample-track',tr.ui.tracks.RectTrack);SampleTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get samples(){return this.rects;},set samples(samples){this.rects=samples;}};return{SampleTrack:SampleTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceGroupTrack=tr.ui.b.define('slice-group-track',tr.ui.tracks.MultiRowTrack);SliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('slice-group-track');this.group_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=100;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices){var precisionUnit=this.group.model.intrinsicTimeUnit;if(!slices.length)
-return[];var ops=[];for(var i=0;i<slices.length;i++){if(slices[i].subSlices)
-slices[i].subSlices.splice(0,slices[i].subSlices.length);ops.push(i);}
-ops.sort(function(ix,iy){var x=slices[ix];var y=slices[iy];if(x.start!=y.start)
-return x.start-y.start;return ix-iy;});var subRows=[[]];this.badSlices_=[];for(var i=0;i<ops.length;i++){var op=ops[i];var slice=slices[op];var inserted=false;for(var j=subRows.length-1;j>=0;j--){if(subRows[j].length==0)
-continue;var insertedSlice=subRows[j][subRows[j].length-1];if(slice.start<insertedSlice.start){this.badSlices_.push(slice);inserted=true;}
-if(insertedSlice.bounds(slice,precisionUnit)){while(subRows.length<=j+1)
-subRows.push([]);subRows[j+1].push(slice);if(insertedSlice.subSlices)
-insertedSlice.subSlices.push(slice);inserted=true;break;}}
-if(inserted)
-continue;subRows[0].push(slice);}
-return subRows;}};return{SliceGroupTrack:SliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ThreadTrack=tr.ui.b.define('thread-track',tr.ui.tracks.ContainerTrack);ThreadTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('thread-track');},get thread(){return this.thread_;},set thread(thread){this.thread_=thread;this.updateContents_();},get hasVisibleContent(){return this.tracks_.length>0;},get eventContainer(){return this.thread;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.thread,this);},updateContents_:function(){this.detach();if(!this.thread_)
-return;this.heading=this.thread_.userFriendlyName+': ';this.tooltip=this.thread_.userFriendlyDetails;if(this.thread_.asyncSliceGroup.length)
-this.appendAsyncSliceTracks_();this.appendThreadSamplesTracks_();if(this.thread_.timeSlices){var timeSlicesTrack=new tr.ui.tracks.SliceTrack(this.viewport);timeSlicesTrack.heading='';timeSlicesTrack.height=tr.ui.b.THIN_SLICE_HEIGHT+'px';timeSlicesTrack.slices=this.thread_.timeSlices;if(timeSlicesTrack.hasVisibleContent)
-this.appendChild(timeSlicesTrack);}
-if(this.thread_.sliceGroup.length){var track=new tr.ui.tracks.SliceGroupTrack(this.viewport);track.heading=this.thread_.userFriendlyName;track.tooltip=this.thread_.userFriendlyDetails;track.group=this.thread_.sliceGroup;if(track.hasVisibleContent)
-this.appendChild(track);}},appendAsyncSliceTracks_:function(){var subGroups=this.thread_.asyncSliceGroup.viewSubGroups;subGroups.forEach(function(subGroup){var asyncTrack=new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport);var title=subGroup.slices[0].viewSubGroupTitle;asyncTrack.group=subGroup;asyncTrack.heading=title;if(asyncTrack.hasVisibleContent)
-this.appendChild(asyncTrack);},this);},appendThreadSamplesTracks_:function(){var threadSamples=this.thread_.samples;if(threadSamples===undefined||threadSamples.length===0)
-return;var samplesByTitle={};threadSamples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
-samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SampleTrack(this.viewport);samplesTrack.group=this.thread_;samplesTrack.samples=samples;samplesTrack.heading=this.thread_.userFriendlyName+': '+
-sampleTitle;samplesTrack.tooltip=this.thread_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.samples.length;i++){selection.push(samplesTrack.samples[i]);}
-return selection;};this.appendChild(samplesTrack);},this);},collapsedDidChange:function(collapsed){if(collapsed){var h=parseInt(this.tracks[0].height);for(var i=0;i<this.tracks.length;++i){if(h>2){this.tracks[i].height=Math.floor(h)+'px';}else{this.tracks[i].style.display='none';}
-h=h*0.5;}}else{for(var i=0;i<this.tracks.length;++i){this.tracks[i].height=this.tracks[0].height;this.tracks[i].style.display='';}}}};return{ThreadTrack:ThreadTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectSnapshotView=tr.ui.analysis.ObjectSnapshotView;var ObjectInstanceView=tr.ui.analysis.ObjectInstanceView;var SpacingTrack=tr.ui.tracks.SpacingTrack;var ProcessTrackBase=tr.ui.b.define('process-track-base',tr.ui.tracks.ContainerTrack);ProcessTrackBase.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.processBase_=undefined;this.classList.add('process-track-base');this.classList.add('expanded');this.processNameEl_=tr.ui.b.createSpan();this.processNameEl_.classList.add('process-track-name');this.headerEl_=tr.ui.b.createDiv({className:'process-track-header'});this.headerEl_.appendChild(this.processNameEl_);this.headerEl_.addEventListener('click',this.onHeaderClick_.bind(this));this.appendChild(this.headerEl_);},get processBase(){return this.processBase_;},set processBase(processBase){this.processBase_=processBase;if(this.processBase_){var modelSettings=new tr.model.ModelSettings(this.processBase_.model);var defaultValue=this.processBase_.important;this.expanded=modelSettings.getSettingFor(this.processBase_,'expanded',defaultValue);}
-this.updateContents_();},get expanded(){return this.classList.contains('expanded');},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)
-return;this.classList.toggle('expanded');this.viewport_.dispatchChangeEvent();if(!this.processBase_)
-return;var modelSettings=new tr.model.ModelSettings(this.processBase_.model);modelSettings.setSettingFor(this.processBase_,'expanded',expanded);this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},get hasVisibleContent(){if(this.expanded)
-return this.children.length>1;return true;},onHeaderClick_:function(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},updateContents_:function(){this.clearTracks_();if(!this.processBase_)
-return;this.processNameEl_.textContent=this.processBase_.userFriendlyName;this.headerEl_.title=this.processBase_.userFriendlyDetails;this.willAppendTracks_();if(this.expanded){this.appendMemoryDumpTrack_();this.appendObjectInstanceTracks_();this.appendCounterTracks_();this.appendFrameTrack_();this.appendThreadTracks_();}else{this.appendSummaryTrack_();}
-this.didAppendTracks_();},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},willAppendTracks_:function(){},didAppendTracks_:function(){},appendMemoryDumpTrack_:function(){},appendSummaryTrack_:function(){var track=new tr.ui.tracks.ProcessSummaryTrack(this.viewport);track.process=this.process;if(!track.hasVisibleContent)
-return;this.appendChild(track);},appendFrameTrack_:function(){var frames=this.process?this.process.frames:undefined;if(!frames||!frames.length)
-return;var track=new tr.ui.tracks.FrameTrack(this.viewport);track.frames=frames;this.appendChild(track);this.backgroundProvider=track;},appendObjectInstanceTracks_:function(){var instancesByTypeName=this.processBase_.objects.getAllInstancesByTypeName();var instanceTypeNames=tr.b.dictionaryKeys(instancesByTypeName);instanceTypeNames.sort();var didAppendAtLeastOneTrack=false;instanceTypeNames.forEach(function(typeName){var allInstances=instancesByTypeName[typeName];var instanceViewInfo=ObjectInstanceView.getTypeInfo(undefined,typeName);var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(instanceViewInfo&&!instanceViewInfo.metadata.showInTrackView)
-instanceViewInfo=undefined;if(snapshotViewInfo&&!snapshotViewInfo.metadata.showInTrackView)
-snapshotViewInfo=undefined;var hasViewInfo=instanceViewInfo||snapshotViewInfo;var visibleInstances=[];for(var i=0;i<allInstances.length;i++){var instance=allInstances[i];if(instance.snapshots.length===0)
-continue;if(instance.hasImplicitSnapshots&&!hasViewInfo)
-continue;visibleInstances.push(instance);}
-if(visibleInstances.length===0)
-return;var trackConstructor=tr.ui.tracks.ObjectInstanceTrack.getConstructor(undefined,typeName);if(!trackConstructor){var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(snapshotViewInfo&&snapshotViewInfo.metadata.showInstances){trackConstructor=tr.ui.tracks.ObjectInstanceGroupTrack;}else{trackConstructor=tr.ui.tracks.ObjectInstanceTrack;}}
-var track=new trackConstructor(this.viewport);track.objectInstances=visibleInstances;this.appendChild(track);didAppendAtLeastOneTrack=true;},this);if(didAppendAtLeastOneTrack)
-this.appendChild(new SpacingTrack(this.viewport));},appendCounterTracks_:function(){var counters=tr.b.dictionaryValues(this.processBase.counters);counters.sort(tr.model.Counter.compare);counters.forEach(function(counter){var track=new tr.ui.tracks.CounterTrack(this.viewport);track.counter=counter;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));},appendThreadTracks_:function(){var threads=tr.b.dictionaryValues(this.processBase.threads);threads.sort(tr.model.Thread.compare);threads.forEach(function(thread){var track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)
-return;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));}};return{ProcessTrackBase:ProcessTrackBase};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CpuTrack=tr.ui.b.define('cpu-track',tr.ui.tracks.ContainerTrack);CpuTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('cpu-track');this.detailedMode_=true;},get cpu(){return this.cpu_;},set cpu(cpu){this.cpu_=cpu;this.updateContents_();},get detailedMode(){return this.detailedMode_;},set detailedMode(detailedMode){this.detailedMode_=detailedMode;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(value){this.tooltip_=value;this.updateContents_();},get hasVisibleContent(){if(this.cpu_===undefined)
-return false;var cpu=this.cpu_;if(cpu.slices.length)
-return true;if(cpu.samples&&cpu.samples.length)
-return true;if(tr.b.dictionaryLength(cpu.counters)>0)
-return true;return false;},updateContents_:function(){this.detach();if(!this.cpu_)
-return;var slices=this.cpu_.slices;if(slices.length){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;track.heading=this.cpu_.userFriendlyName+':';this.appendChild(track);}
-if(this.detailedMode_){this.appendSamplesTracks_();for(var counterName in this.cpu_.counters){var counter=this.cpu_.counters[counterName];track=new tr.ui.tracks.CounterTrack(this.viewport);track.heading=this.cpu_.userFriendlyName+' '+
-counter.name+':';track.counter=counter;this.appendChild(track);}}},appendSamplesTracks_:function(){var samples=this.cpu_.samples;if(samples===undefined||samples.length===0)
-return;var samplesByTitle={};samples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
-samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SliceTrack(this.viewport);samplesTrack.group=this.cpu_;samplesTrack.slices=samples;samplesTrack.heading=this.cpu_.userFriendlyName+': '+
-sampleTitle;samplesTrack.tooltip=this.cpu_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.slices.length;i++){selection.push(samplesTrack.slices[i]);}
-return selection;};this.appendChild(samplesTrack);},this);}};return{CpuTrack:CpuTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Cpu=tr.model.Cpu;var CpuTrack=tr.ui.tracks.cpu_track;var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var SpacingTrack=tr.ui.tracks.SpacingTrack;var KernelTrack=tr.ui.b.define('kernel-track',ProcessTrackBase);KernelTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){ProcessTrackBase.prototype.decorate.call(this,viewport);},set kernel(kernel){this.processBase=kernel;},get kernel(){return this.processBase;},get eventContainer(){return this.kernel;},get hasVisibleContent(){return this.children.length>1;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.kernel,this);},willAppendTracks_:function(){var cpus=tr.b.dictionaryValues(this.kernel.cpus);cpus.sort(tr.model.Cpu.compare);var didAppendAtLeastOneTrack=false;for(var i=0;i<cpus.length;++i){var cpu=cpus[i];var track=new tr.ui.tracks.CpuTrack(this.viewport);track.detailedMode=this.expanded;track.cpu=cpu;if(!track.hasVisibleContent)
-continue;this.appendChild(track);didAppendAtLeastOneTrack=true;}
-if(didAppendAtLeastOneTrack)
-this.appendChild(new SpacingTrack(this.viewport));}};return{KernelTrack:KernelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var InteractionTrack=tr.ui.b.define('interaction-track',tr.ui.tracks.MultiRowTrack);InteractionTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.heading='Interactions';this.subRows_=[];},set model(model){this.setItemsToGroup(model.interactionRecords,{guid:tr.b.GUID.allocate(),model:model,getSettingsKey:function(){return undefined;}});},buildSubRows_:function(slices){if(this.subRows_.length)
-return this.subRows_;this.subRows_.push.apply(this.subRows_,tr.ui.tracks.AsyncSliceGroupTrack.prototype.buildSubRows_.call({},slices,true));return this.subRows_;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;}};return{InteractionTrack:InteractionTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
-return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
-return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{ProcessMemoryDumpTrack:ProcessMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack:function(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0)
-break;var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
-tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_:function(){var ctx=this.context();var canvasBounds=ctx.canvas.getBoundingClientRect();var pixelRatio=window.devicePixelRatio||1;var draw=false;ctx.fillStyle='#eee';for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack))
-continue;draw=!draw;if(!draw)
-continue;var bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_:function(){var processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){var pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;this.appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
-var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack:ProcessTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('model-track');var typeInfos=tr.ui.tracks.Highlighter.getAllRegisteredTypeInfos();this.highlighters_=typeInfos.map(function(typeInfo){return new typeInfo.constructor(viewport);});this.upperMode_=false;this.annotationViews_=[];},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach:function(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_:function(){this.textContent='';if(!this.model_)
-return;if(this.upperMode_)
-this.updateContentsForUpperMode_();else
-this.updateContentsForLowerMode_();},updateContentsForUpperMode_:function(){},updateContentsForLowerMode_:function(){if(this.model_.interactionRecords.length){var mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;this.appendChild(mrt);}
-if(this.model_.alerts.length){var at=new tr.ui.tracks.AlertTrack(this.viewport_);at.alerts=this.model_.alerts;this.appendChild(at);}
-if(this.model_.globalMemoryDumps.length){var gmdt=new tr.ui.tracks.GlobalMemoryDumpTrack(this.viewport_);gmdt.memoryDumps=this.model_.globalMemoryDumps;this.appendChild(gmdt);}
-this.appendDeviceTrack_();this.appendKernelTrack_();var processes=this.model_.getAllProcesses();processes.sort(tr.model.Process.compare);for(var i=0;i<processes.length;++i){var process=processes[i];var track=new tr.ui.tracks.ProcessTrack(this.viewport);track.process=process;if(!track.hasVisibleContent)
-continue;this.appendChild(track);}
-this.viewport_.rebuildEventToTrackMap();this.viewport_.rebuildContainerToTrackMap();for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].processModel(this.model_);}
-this.updateAnnotations_();},updateAnnotations_:function(){this.annotationViews_=[];var annotations=this.model_.getAllAnnotations();for(var i=0;i<annotations.length;i++){this.annotationViews_.push(annotations[i].getOrCreateView(this.viewport_));}
-this.invalidateDrawingContainer();},addEventsToTrackMap:function(eventToTrackMap){if(!this.model_)
-return;var tracks=this.children;for(var i=0;i<tracks.length;++i)
-tracks[i].addEventsToTrackMap(eventToTrackMap);if(this.instantEvents===undefined)
-return;var vp=this.viewport_;this.instantEvents.forEach(function(ev){eventToTrackMap.addEvent(ev,this);}.bind(this));},appendDeviceTrack_:function(){var device=this.model.device;var track=new tr.ui.tracks.DeviceTrack(this.viewport);track.device=this.model.device;if(!track.hasVisibleContent)
-return;this.appendChild(track);},appendKernelTrack_:function(){var kernel=this.model.kernel;var track=new tr.ui.tracks.KernelTrack(this.viewport);track.kernel=this.model.kernel;if(!track.hasVisibleContent)
-return;this.appendChild(track);},drawTrack:function(type){var ctx=this.context();if(!this.model_)
-return;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);switch(type){case tr.ui.tracks.DrawType.GRID:this.viewport.drawMajorMarkLines(ctx);ctx.restore();return;case tr.ui.tracks.DrawType.FLOW_ARROWS:if(this.model_.flowIntervalTree.size===0){ctx.restore();return;}
-this.drawFlowArrows_(viewLWorld,viewRWorld);ctx.restore();return;case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.model_.instantEvents||this.model_.instantEvents.length===0)
-break;tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.model_.instantEvents,4);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(ctx,viewLWorld,viewRWorld);this.viewport.interestRange.drawIndicators(ctx,viewLWorld,viewRWorld);}
-ctx.restore();return;case tr.ui.tracks.DrawType.HIGHLIGHTS:for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].drawHighlight(ctx,dt,viewLWorld,viewRWorld,bounds.height);}
-ctx.restore();return;case tr.ui.tracks.DrawType.ANNOTATIONS:for(var i=0;i<this.annotationViews_.length;i++){this.annotationViews_[i].draw(ctx);}
-ctx.restore();return;}
-ctx.restore();tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawFlowArrows_:function(viewLWorld,viewRWorld){var ctx=this.context();var dt=this.viewport.currentDisplayTransform;dt.applyTransformToCanvas(ctx);var pixWidth=dt.xViewVectorToWorld(1);ctx.strokeStyle='rgba(0, 0, 0, 0.4)';ctx.fillStyle='rgba(0, 0, 0, 0.4)';ctx.lineWidth=pixWidth>1.0?1:pixWidth;var events=this.model_.flowIntervalTree.findIntersection(viewLWorld,viewRWorld);var onlyHighlighted=!this.viewport.showFlowEvents;var canvasBounds=ctx.canvas.getBoundingClientRect();for(var i=0;i<events.length;++i){if(onlyHighlighted&&events[i].selectionState!==SelectionState.SELECTED&&events[i].selectionState!==SelectionState.HIGHLIGHTED)
-continue;this.drawFlowArrow_(ctx,events[i],canvasBounds,pixWidth);}},drawFlowArrow_:function(ctx,flowEvent,canvasBounds,pixWidth){var pixelRatio=window.devicePixelRatio||1;var startTrack=this.viewport.trackForEvent(flowEvent.startSlice);var endTrack=this.viewport.trackForEvent(flowEvent.endSlice);if(startTrack===undefined||endTrack===undefined)
-return;var startBounds=startTrack.getBoundingClientRect();var endBounds=endTrack.getBoundingClientRect();if(flowEvent.selectionState==SelectionState.SELECTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.HIGHLIGHTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.DIMMED){ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.2)';}else{var hasBoost=false;var startSlice=flowEvent.startSlice;hasBoost|=startSlice.selectionState===SelectionState.SELECTED;hasBoost|=startSlice.selectionState===SelectionState.HIGHLIGHTED;var endSlice=flowEvent.endSlice;hasBoost|=endSlice.selectionState===SelectionState.SELECTED;hasBoost|=endSlice.selectionState===SelectionState.HIGHLIGHTED;if(hasBoost){ctx.shadowBlur=1;ctx.shadowColor='rgba(255, 0, 0, 0.4)';ctx.shadowOffsety=2;ctx.strokeStyle='rgba(255, 0, 0, 0.4)';}else{ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.4)';}}
-var startSize=startBounds.left+startBounds.top+
-startBounds.bottom+startBounds.right;var endSize=endBounds.left+endBounds.top+
-endBounds.bottom+endBounds.right;if(startSize===0&&endSize===0)
-return;var startY=this.calculateTrackY_(startTrack,canvasBounds);var endY=this.calculateTrackY_(endTrack,canvasBounds);var pixelStartY=pixelRatio*startY;var pixelEndY=pixelRatio*endY;var half=(flowEvent.end-flowEvent.start)/2;ctx.beginPath();ctx.moveTo(flowEvent.start,pixelStartY);ctx.bezierCurveTo(flowEvent.start+half,pixelStartY,flowEvent.start+half,pixelEndY,flowEvent.end,pixelEndY);ctx.stroke();var arrowWidth=5*pixWidth*pixelRatio;var distance=flowEvent.end-flowEvent.start;if(distance<=(2*arrowWidth))
-return;var tipX=flowEvent.end;var tipY=pixelEndY;var arrowHeight=(endBounds.height/4)*pixelRatio;tr.ui.b.drawTriangle(ctx,tipX,tipY,tipX-arrowWidth,tipY-arrowHeight,tipX-arrowWidth,tipY+arrowHeight);ctx.fill();},calculateTrackY_:function(track,canvasBounds){var bounds=track.getBoundingClientRect();var size=bounds.left+bounds.top+bounds.bottom+bounds.right;if(size===0)
-return this.calculateTrackY_(track.parentNode,canvasBounds);return bounds.top-canvasBounds.top+(bounds.height/2);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
-var instantEventWidth=3*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.model_.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.model_.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ModelTrack:ModelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RulerTrack=tr.ui.b.define('ruler-track',tr.ui.tracks.Track);var logOf10=Math.log(10);function log10(x){return Math.log(x)/logOf10;}
-RulerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('ruler-track');this.strings_secs_=[];this.strings_msecs_=[];this.strings_usecs_=[];this.strings_nsecs_=[];this.viewportChange_=this.viewportChange_.bind(this);viewport.addEventListener('change',this.viewportChange_);var heading=document.createElement('tr-ui-heading');heading.arrowVisible=false;this.appendChild(heading);},detach:function(){tr.ui.tracks.Track.prototype.detach.call(this);this.viewport.removeEventListener('change',this.viewportChange_);},viewportChange_:function(){if(this.viewport.interestRange.isEmpty)
-this.classList.remove('tall-mode');else
-this.classList.add('tall-mode');},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GRID:this.drawGrid_(viewLWorld,viewRWorld);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty)
-this.viewport.interestRange.draw(this.context(),viewLWorld,viewRWorld);break;}},drawGrid_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var canvasBounds=ctx.canvas.getBoundingClientRect();var trackBounds=this.getBoundingClientRect();var width=canvasBounds.width*pixelRatio;var height=trackBounds.height*pixelRatio;var hasInterestRange=!this.viewport.interestRange.isEmpty;var rulerHeight=hasInterestRange?(height*2)/5:height;var vp=this.viewport;var dt=vp.currentDisplayTransform;var idealMajorMarkDistancePix=150*pixelRatio;var idealMajorMarkDistanceWorld=dt.xViewVectorToWorld(idealMajorMarkDistancePix);var majorMarkDistanceWorld;var conservativeGuess=Math.pow(10,Math.ceil(log10(idealMajorMarkDistanceWorld)));var divisors=[10,5,2,1];for(var i=0;i<divisors.length;++i){var tightenedGuess=conservativeGuess/divisors[i];if(dt.xWorldVectorToView(tightenedGuess)<idealMajorMarkDistancePix)
-continue;majorMarkDistanceWorld=conservativeGuess/divisors[i-1];break;}
-var unit;var unitDivisor;var tickLabels=undefined;if(majorMarkDistanceWorld<0.0001){unit='ns';unitDivisor=0.000001;tickLabels=this.strings_nsecs_;}else if(majorMarkDistanceWorld<0.1){unit='us';unitDivisor=0.001;tickLabels=this.strings_usecs_;}else if(majorMarkDistanceWorld<100){unit='ms';unitDivisor=1;tickLabels=this.strings_msecs_;}else{unit='s';unitDivisor=1000;tickLabels=this.strings_secs_;}
-var numTicksPerMajor=5;var minorMarkDistanceWorld=majorMarkDistanceWorld/numTicksPerMajor;var minorMarkDistancePx=dt.xWorldVectorToView(minorMarkDistanceWorld);var firstMajorMark=Math.floor(viewLWorld/majorMarkDistanceWorld)*majorMarkDistanceWorld;var minorTickH=Math.floor(rulerHeight*0.25);ctx.save();var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);var crispLineCorrection=(ctx.lineWidth%2)/2;ctx.translate(crispLineCorrection,-crispLineCorrection);ctx.fillStyle='rgb(0, 0, 0)';ctx.strokeStyle='rgb(0, 0, 0)';ctx.textAlign='left';ctx.textBaseline='top';ctx.font=(9*pixelRatio)+'px sans-serif';vp.majorMarkPositions=[];ctx.beginPath();for(var curX=firstMajorMark;curX<viewRWorld;curX+=majorMarkDistanceWorld){var curXView=Math.floor(dt.xWorldToView(curX));var unitValue=curX/unitDivisor;var roundedUnitValue=Math.round(unitValue*100000)/100000;if(!tickLabels[roundedUnitValue])
-tickLabels[roundedUnitValue]=roundedUnitValue+' '+unit;ctx.fillText(tickLabels[roundedUnitValue],curXView+(2*pixelRatio),0);vp.majorMarkPositions.push(curXView);tr.ui.b.drawLine(ctx,curXView,0,curXView,rulerHeight);for(var i=1;i<numTicksPerMajor;++i){var xView=Math.floor(curXView+minorMarkDistancePx*i);tr.ui.b.drawLine(ctx,xView,rulerHeight-minorTickH,xView,rulerHeight);}}
-ctx.strokeStyle='rgb(0, 0, 0)';tr.ui.b.drawLine(ctx,0,height,width,height);ctx.stroke();if(!hasInterestRange)
-return;tr.ui.b.drawLine(ctx,0,rulerHeight,width,rulerHeight);ctx.stroke();var displayDistance;var displayTextColor='rgb(0,0,0)';var arrowSpacing=10*pixelRatio;var arrowColor='rgb(128,121,121)';var arrowPosY=rulerHeight*1.75;var arrowWidthView=3*pixelRatio;var arrowLengthView=10*pixelRatio;var spaceForArrowsView=2*(arrowWidthView+arrowSpacing);ctx.textBaseline='middle';ctx.font=(14*pixelRatio)+'px sans-serif';var textPosY=arrowPosY;var interestRange=vp.interestRange;if(interestRange.range===0){var markerWorld=interestRange.min;var markerView=dt.xWorldToView(markerWorld);var displayValue=markerWorld/unitDivisor;displayValue=Math.abs((Math.round(displayValue*1000)/1000));var textToDraw=displayValue+' '+unit;var textLeftView=markerView+4*pixelRatio;var textWidthView=ctx.measureText(textToDraw).width;if(textLeftView+textWidthView>width)
-textLeftView=markerView-4*pixelRatio-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);return;}
-var leftMarker=interestRange.min;var rightMarker=interestRange.max;var leftMarkerView=dt.xWorldToView(leftMarker);var rightMarkerView=dt.xWorldToView(rightMarker);var distanceBetweenMarkers=interestRange.range;var distanceBetweenMarkersView=dt.xWorldVectorToView(distanceBetweenMarkers);var positionInMiddleOfMarkersView=leftMarkerView+(distanceBetweenMarkersView/2);if(distanceBetweenMarkers<0.0001){unit='ns';unitDivisor=0.000001;}else if(distanceBetweenMarkers<0.1){unit='us';unitDivisor=0.001;}else if(distanceBetweenMarkers<100){unit='ms';unitDivisor=1;}else{unit='s';unitDivisor=1000;}
-displayDistance=distanceBetweenMarkers/unitDivisor;var roundedDisplayDistance=Math.abs((Math.round(displayDistance*1000)/1000));var textToDraw=roundedDisplayDistance+' '+unit;var textWidthView=ctx.measureText(textToDraw).width;var spaceForArrowsAndTextView=textWidthView+spaceForArrowsView+arrowSpacing;var textLeftView=positionInMiddleOfMarkersView-textWidthView/2;var textRightView=textLeftView+textWidthView;if(spaceForArrowsAndTextView>distanceBetweenMarkersView){textLeftView=rightMarkerView+2*arrowSpacing;if(textLeftView+textWidthView>width)
-textLeftView=leftMarkerView-2*arrowSpacing-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);ctx.strokeStyle=arrowColor;ctx.beginPath();tr.ui.b.drawLine(ctx,leftMarkerView,arrowPosY,rightMarkerView,arrowPosY);ctx.stroke();ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftMarkerView-1.5*arrowSpacing,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightMarkerView+1.5*arrowSpacing,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}else if(spaceForArrowsView<=distanceBetweenMarkersView){var leftArrowStart;var rightArrowStart;if(spaceForArrowsAndTextView<=distanceBetweenMarkersView){ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);leftArrowStart=textLeftView-arrowSpacing;rightArrowStart=textRightView+arrowSpacing;}else{leftArrowStart=positionInMiddleOfMarkersView;rightArrowStart=positionInMiddleOfMarkersView;}
-ctx.strokeStyle=arrowColor;ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftArrowStart,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightArrowStart,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}
-ctx.restore();},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{RulerTrack:RulerTrack};});'use strict';Polymer('tr-ui-timeline-track-view',{ready:function(){this.displayTransform_=new tr.ui.TimelineDisplayTransform();this.model_=undefined;this.timelineView_=undefined;this.viewport_=new tr.ui.TimelineViewport(this);this.viewportDisplayTransformAtMouseDown_=undefined;this.brushingStateController_=undefined;this.rulerTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.rulerTrackContainer_);this.rulerTrackContainer_.invalidate();this.rulerTrack_=new tr.ui.tracks.RulerTrack(this.viewport_);this.rulerTrackContainer_.appendChild(this.rulerTrack_);this.upperModelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.upperModelTrack_.upperMode=true;this.rulerTrackContainer_.appendChild(this.upperModelTrack_);this.modelTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.modelTrackContainer_);this.modelTrackContainer_.style.display='block';this.modelTrackContainer_.invalidate();this.viewport_.modelTrackContainer=this.modelTrackContainer_;this.modelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.modelTrackContainer_.appendChild(this.modelTrack_);this.timingTool_=new tr.ui.b.TimingTool(this.viewport_,this);this.initMouseModeSelector();this.hideDragBox_();this.initHintText_();this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.addEventListener('dblclick',this.onDblClick_);this.onMouseWheel_=this.onMouseWheel_.bind(this);this.addEventListener('mousewheel',this.onMouseWheel_);this.onMouseDown_=this.onMouseDown_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.onMouseMove_=this.onMouseMove_.bind(this);this.addEventListener('mousemove',this.onMouseMove_);this.onTouchStart_=this.onTouchStart_.bind(this);this.addEventListener('touchstart',this.onTouchStart_);this.onTouchMove_=this.onTouchMove_.bind(this);this.addEventListener('touchmove',this.onTouchMove_);this.onTouchEnd_=this.onTouchEnd_.bind(this);this.addEventListener('touchend',this.onTouchEnd_);this.addHotKeys_();this.mouseViewPosAtMouseDown_={x:0,y:0};this.lastMouseViewPos_={x:0,y:0};this.lastTouchViewPositions_=[];this.alert_=undefined;this.isPanningAndScanning_=false;this.isZooming_=false;},initMouseModeSelector:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this;this.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.addEventListener('beginpan',this.onBeginPanScan_.bind(this));this.mouseModeSelector_.addEventListener('updatepan',this.onUpdatePanScan_.bind(this));this.mouseModeSelector_.addEventListener('endpan',this.onEndPanScan_.bind(this));this.mouseModeSelector_.addEventListener('beginselection',this.onBeginSelection_.bind(this));this.mouseModeSelector_.addEventListener('updateselection',this.onUpdateSelection_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onEndSelection_.bind(this));this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));this.mouseModeSelector_.addEventListener('entertiming',this.timingTool_.onEnterTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('begintiming',this.timingTool_.onBeginTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('updatetiming',this.timingTool_.onUpdateTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('endtiming',this.timingTool_.onEndTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('exittiming',this.timingTool_.onExitTiming.bind(this.timingTool_));var m=tr.ui.b.MOUSE_SELECTOR_MODE;this.mouseModeSelector_.supportedModeMask=m.SELECTION|m.PANSCAN|m.ZOOM|m.TIMING;this.mouseModeSelector_.settingsKey='timelineTrackView.mouseModeSelector';this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN,'2'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION,'1'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM,'3'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.TIMING,'4'.charCodeAt(0));this.mouseModeSelector_.setModifierForAlternateMode(m.SELECTION,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(m.PANSCAN,tr.ui.b.MODIFIER.SPACE);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController_){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}},set timelineView(view){this.timelineView_=view;},onSelectionChanged_:function(){this.showHintText_('Press \'m\' to mark current selection');this.viewport_.dispatchChangeEvent();},set selection(selection){throw new Error('DO NOT CALL THIS');},set highlight(highlight){throw new Error('DO NOT CALL THIS');},detach:function(){this.modelTrack_.detach();this.upperModelTrack_.detach();this.viewport_.detach();},get viewport(){return this.viewport_;},get model(){return this.model_;},set model(model){if(!model)
-throw new Error('Model cannot be undefined');var modelInstanceChanged=this.model_!==model;this.model_=model;this.modelTrack_.model=model;this.upperModelTrack_.model=model;if(modelInstanceChanged)
-this.viewport_.setWhenPossible(this.setInitialViewport_.bind(this));},get hasVisibleContent(){return this.modelTrack_.hasVisibleContent||this.upperModelTrack_.hasVisibleContent;},setInitialViewport_:function(){this.modelTrackContainer_.updateCanvasSizeIfNeeded_();var w=this.modelTrackContainer_.canvas.width;var min;var range;if(this.model_.bounds.isEmpty){min=0;range=1000;}else if(this.model_.bounds.range===0){min=this.model_.bounds.min;range=1000;}else{min=this.model_.bounds.min;range=this.model_.bounds.range;}
-var boost=range*0.15;this.displayTransform_.set(this.viewport_.currentDisplayTransform);this.displayTransform_.xSetWorldBounds(min-boost,min+range+boost,w);this.viewport_.setDisplayTransformImmediately(this.displayTransform_);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var modelTrack=this.modelTrack_;var firstT=modelTrack.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);var lastT=firstT.after(function(){this.upperModelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);},this);return firstT;},onMouseMove_:function(e){if(this.isZooming_)
-return;this.storeLastMousePos_(e);},onTouchStart_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},onTouchMove_:function(e){e.preventDefault();this.onUpdateTransformForTouch_(e);},onTouchEnd_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},addHotKeys_:function(){this.addKeyDownHotKeys_();this.addKeyPressHotKeys_();},addKeyPressHotKeys_:function(){var addBinding=function(dict){dict.eventType='keypress';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCodes:['w'.charCodeAt(0),','.charCodeAt(0)],callback:function(e){this.zoomBy_(1.5,true);e.stopPropagation();}});addBinding({keyCodes:['s'.charCodeAt(0),'o'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/1.5,true);e.stopPropagation();}});addBinding({keyCode:'g'.charCodeAt(0),callback:function(e){this.onGridToggle_(true);e.stopPropagation();}});addBinding({keyCode:'G'.charCodeAt(0),callback:function(e){this.onGridToggle_(false);e.stopPropagation();}});addBinding({keyCodes:['W'.charCodeAt(0),'<'.charCodeAt(0)],callback:function(e){this.zoomBy_(10,true);e.stopPropagation();}});addBinding({keyCodes:['S'.charCodeAt(0),'O'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/10,true);e.stopPropagation();}});addBinding({keyCode:'a'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(this.viewWidth_*0.3,0);e.stopPropagation();}});addBinding({keyCodes:['d'.charCodeAt(0),'e'.charCodeAt(0)],callback:function(e){this.queueSmoothPan_(this.viewWidth_*-0.3,0);e.stopPropagation();}});addBinding({keyCode:'A'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*0.5,0);e.stopPropagation();}});addBinding({keyCode:'D'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*-0.5,0);e.stopPropagation();}});addBinding({keyCode:'0'.charCodeAt(0),callback:function(e){this.setInitialViewport_();e.stopPropagation();}});addBinding({keyCode:'f'.charCodeAt(0),callback:function(e){this.zoomToSelection();e.stopPropagation();}});addBinding({keyCode:'m'.charCodeAt(0),callback:function(e){this.setCurrentSelectionAsInterestRange_();e.stopPropagation();}});addBinding({keyCode:'h'.charCodeAt(0),callback:function(e){this.toggleHighDetails_();e.stopPropagation();}});},get viewWidth_(){return this.modelTrackContainer_.canvas.clientWidth;},addKeyDownHotKeys_:function(){var addBinding=function(dict){dict.eventType='keydown';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCode:37,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,-1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(this.viewWidth_*0.3,0);}
-e.preventDefault();e.stopPropagation();}});addBinding({keyCode:39,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(-this.viewWidth_*0.3,0);}
-e.preventDefault();e.stopPropagation();}});},onDblClick_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
-return;var curSelection=this.brushingStateController_.selection;if(!curSelection.length||!curSelection[0].title)
-return;var selection=new tr.model.EventSet();var filter=new tr.c.ExactTitleFilter(curSelection[0].title);this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);this.brushingStateController.changeSelectionFromTimeline(selection);},onMouseWheel_:function(e){if(!e.altKey)
-return;var delta=e.wheelDelta/120;var zoomScale=Math.pow(1.5,delta);this.zoomBy_(zoomScale);e.preventDefault();},onMouseDown_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
-return;if(e.target!==this.rulerTrack_)
-return;this.dragBeginEvent_=undefined;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
-var dt=this.viewport_.currentDisplayTransform;tr.ui.b.trackMouseMovesUntilMouseUp(function(e){if(e.target===this.rulerTrack_)
-return;var relativePosition=this.extractRelativeMousePosition_(e);var loc=tr.model.Location.fromViewCoordinates(this.viewport_,relativePosition.x,relativePosition.y);if(!loc)
-return;if(this.guideLineAnnotation_===undefined){this.guideLineAnnotation_=new tr.model.XMarkerAnnotation(loc.xWorld);this.model.addAnnotation(this.guideLineAnnotation_);}else{this.guideLineAnnotation_.timestamp=loc.xWorld;this.modelTrackContainer_.invalidate();}
-var state=new tr.ui.b.UIState(loc,this.viewport_.currentDisplayTransform.scaleX);this.timelineView_.setFindCtlText(state.toUserFriendlyString(this.viewport_));}.bind(this),undefined,function onKeyUpDuringDrag(){if(this.dragBeginEvent_){this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);}}.bind(this));},queueSmoothPan_:function(viewDeltaX,deltaY){var deltaX=this.viewport_.currentDisplayTransform.xViewVectorToWorld(viewDeltaX);var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,deltaY);this.viewport_.queueDisplayTransformAnimation(animation);},zoomBy_:function(scale,smooth){if(scale<=0){return;}
-smooth=!!smooth;var vp=this.viewport_;var pixelRatio=window.devicePixelRatio||1;var goalFocalPointXView=this.lastMouseViewPos_.x*pixelRatio;var goalFocalPointXWorld=vp.currentDisplayTransform.xViewToWorld(goalFocalPointXView);if(smooth){var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,vp.currentDisplayTransform.panY,scale);vp.queueDisplayTransformAnimation(animation);}else{this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=scale;this.displayTransform_.xPanWorldPosToViewPos(goalFocalPointXWorld,goalFocalPointXView,this.viewWidth_);vp.setDisplayTransformImmediately(this.displayTransform_);}},zoomToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
-return;var bounds=this.brushingStateController.selectionOfInterest.bounds;if(!bounds.range)
-return;var worldCenter=bounds.center;var viewCenter=this.modelTrackContainer_.canvas.width/2;var adjustedWorldRange=bounds.range*1.25;var newScale=this.modelTrackContainer_.canvas.width/adjustedWorldRange;var zoomInRatio=newScale/this.viewport_.currentDisplayTransform.scaleX;var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);},panToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
-return;var bounds=this.brushingStateController.selectionOfInterest.bounds;var worldCenter=bounds.center;var viewWidth=this.viewWidth_;var dt=this.viewport_.currentDisplayTransform;if(false&&!bounds.range){if(dt.xWorldToView(bounds.center)<0||dt.xWorldToView(bounds.center)>viewWidth){this.displayTransform_.set(dt);this.displayTransform_.xPanWorldPosToViewPos(worldCenter,'center',viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);}
-return;}
-this.displayTransform_.set(dt);this.displayTransform_.xPanWorldBoundsIntoView(bounds.min,bounds.max,viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);},navToPosition:function(uiState,showNavLine){var location=uiState.location;var scaleX=uiState.scaleX;var track=location.getContainingTrack(this.viewport_);var worldCenter=location.xWorld;var viewCenter=this.modelTrackContainer_.canvas.width/5;var zoomInRatio=scaleX/this.viewport_.currentDisplayTransform.scaleX;track.scrollIntoViewIfNeeded();var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);if(!showNavLine)
-return;if(this.xNavStringMarker_)
-this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=new tr.model.XMarkerAnnotation(worldCenter);this.model.addAnnotation(this.xNavStringMarker_);},setCurrentSelectionAsInterestRange_:function(){var selectionBounds=this.brushingStateController_.selection.bounds;if(selectionBounds.empty){this.viewport_.interestRange.reset();return;}
-if(this.viewport_.interestRange.min==selectionBounds.min&&this.viewport_.interestRange.max==selectionBounds.max)
-this.viewport_.interestRange.reset();else
-this.viewport_.interestRange.set(selectionBounds);},toggleHighDetails_:function(){this.viewport_.highDetails=!this.viewport_.highDetails;},hideDragBox_:function(){this.$.drag_box.style.left='-1000px';this.$.drag_box.style.top='-1000px';this.$.drag_box.style.width=0;this.$.drag_box.style.height=0;},setDragBoxPosition_:function(xStart,yStart,xEnd,yEnd){var loY=Math.min(yStart,yEnd);var hiY=Math.max(yStart,yEnd);var loX=Math.min(xStart,xEnd);var hiX=Math.max(xStart,xEnd);var modelTrackRect=this.modelTrack_.getBoundingClientRect();var dragRect={left:loX,top:loY,width:hiX-loX,height:hiY-loY};dragRect.right=dragRect.left+dragRect.width;dragRect.bottom=dragRect.top+dragRect.height;var modelTrackContainerRect=this.modelTrackContainer_.getBoundingClientRect();var clipRect={left:modelTrackContainerRect.left,top:modelTrackContainerRect.top,right:modelTrackContainerRect.right,bottom:modelTrackContainerRect.bottom};var headingWidth=window.getComputedStyle(this.querySelector('tr-ui-heading')).width;var trackTitleWidth=parseInt(headingWidth);clipRect.left=clipRect.left+trackTitleWidth;var intersectRect_=function(r1,r2){if(r2.left>r1.right||r2.right<r1.left||r2.top>r1.bottom||r2.bottom<r1.top)
-return false;var results={};results.left=Math.max(r1.left,r2.left);results.top=Math.max(r1.top,r2.top);results.right=Math.min(r1.right,r2.right);results.bottom=Math.min(r1.bottom,r2.bottom);results.width=results.right-results.left;results.height=results.bottom-results.top;return results;}
-var finalDragBox=intersectRect_(clipRect,dragRect);this.$.drag_box.style.left=finalDragBox.left+'px';this.$.drag_box.style.width=finalDragBox.width+'px';this.$.drag_box.style.top=finalDragBox.top+'px';this.$.drag_box.style.height=finalDragBox.height+'px';this.$.drag_box.style.whiteSpace='nowrap';var pixelRatio=window.devicePixelRatio||1;var canv=this.modelTrackContainer_.canvas;var dt=this.viewport_.currentDisplayTransform;var loWX=dt.xViewToWorld((loX-canv.offsetLeft)*pixelRatio);var hiWX=dt.xViewToWorld((hiX-canv.offsetLeft)*pixelRatio);this.$.drag_box.textContent=tr.b.u.TimeDuration.format(hiWX-loWX);var e=new tr.b.Event('selectionChanging');e.loWX=loWX;e.hiWX=hiWX;this.dispatchEvent(e);},onGridToggle_:function(left){var selection=this.brushingStateController_.selection;var tb=left?selection.bounds.min:selection.bounds.max;if(this.viewport_.gridEnabled&&this.viewport_.gridSide===left&&this.viewport_.gridInitialTimebase===tb){this.viewport_.gridside=undefined;this.viewport_.gridEnabled=false;this.viewport_.gridInitialTimebase=undefined;return;}
-var numIntervalsSinceStart=Math.ceil((tb-this.model_.bounds.min)/this.viewport_.gridStep_);this.viewport_.gridEnabled=true;this.viewport_.gridSide=left;this.viewport_.gridInitialTimebase=tb;this.viewport_.gridTimebase=tb-
-(numIntervalsSinceStart+1)*this.viewport_.gridStep_;},storeLastMousePos_:function(e){this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);},storeLastTouchPositions_:function(e){this.lastTouchViewPositions_=this.extractRelativeTouchPositions_(e);},extractRelativeMousePosition_:function(e){var canv=this.modelTrackContainer_.canvas;return{x:e.clientX-canv.offsetLeft,y:e.clientY-canv.offsetTop};},extractRelativeTouchPositions_:function(e){var canv=this.modelTrackContainer_.canvas;var touches=[];for(var i=0;i<e.touches.length;++i){touches.push({x:e.touches[i].clientX-canv.offsetLeft,y:e.touches[i].clientY-canv.offsetTop});}
-return touches;},storeInitialMouseDownPos_:function(e){var position=this.extractRelativeMousePosition_(e);this.mouseViewPosAtMouseDown_.x=position.x;this.mouseViewPosAtMouseDown_.y=position.y;},focusElements_:function(){this.$.hotkey_controller.childRequestsGeneralFocus(this);},storeInitialInteractionPositionsAndFocus_:function(e){this.storeInitialMouseDownPos_(e);this.storeLastMousePos_(e);this.focusElements_();},onBeginPanScan_:function(e){var vp=this.viewport_;this.viewportDisplayTransformAtMouseDown_=vp.currentDisplayTransform.clone();this.isPanningAndScanning_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdatePanScan_:function(e){if(!this.isPanningAndScanning_)
-return;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDeltaView=pixelRatio*(this.lastMouseViewPos_.x-
-this.mouseViewPosAtMouseDown_.x);var yDelta=this.lastMouseViewPos_.y-
-this.mouseViewPosAtMouseDown_.y;this.displayTransform_.set(this.viewportDisplayTransformAtMouseDown_);this.displayTransform_.incrementPanXInViewUnits(xDeltaView);this.displayTransform_.panY-=yDelta;this.viewport_.setDisplayTransformImmediately(this.displayTransform_);e.preventDefault();e.stopPropagation();this.storeLastMousePos_(e);},onEndPanScan_:function(e){this.isPanningAndScanning_=false;this.storeLastMousePos_(e);if(!e.isClick)
-e.preventDefault();},onBeginSelection_:function(e){var canv=this.modelTrackContainer_.canvas;var rect=this.modelTrack_.getBoundingClientRect();var canvRect=canv.getBoundingClientRect();var inside=rect&&e.clientX>=rect.left&&e.clientX<rect.right&&e.clientY>=rect.top&&e.clientY<rect.bottom&&e.clientX>=canvRect.left&&e.clientX<canvRect.right;if(!inside)
-return;this.dragBeginEvent_=e;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateSelection_:function(e){if(!this.dragBeginEvent_)
-return;this.dragBoxXStart_=this.dragBeginEvent_.clientX;this.dragBoxXEnd_=e.clientX;this.dragBoxYStart_=this.dragBeginEvent_.clientY;this.dragBoxYEnd_=e.clientY;this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);},onEndSelection_:function(e){e.preventDefault();if(!this.dragBeginEvent_)
-return;this.hideDragBox_();var eDown=this.dragBeginEvent_;this.dragBeginEvent_=undefined;var loY=Math.min(eDown.clientY,e.clientY);var hiY=Math.max(eDown.clientY,e.clientY);var loX=Math.min(eDown.clientX,e.clientX);var hiX=Math.max(eDown.clientX,e.clientX);var canv=this.modelTrackContainer_.canvas;var worldOffset=canv.getBoundingClientRect().left;var loVX=loX-worldOffset;var hiVX=hiX-worldOffset;var selection=new tr.model.EventSet();if(eDown.appendSelection){var previousSelection=this.brushingStateController_.selection;if(previousSelection!==undefined)
-selection.addEventSet(previousSelection);}
-this.modelTrack_.addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);this.brushingStateController_.changeSelectionFromTimeline(selection);},onBeginZoom_:function(e){this.isZooming_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
-return;var newPosition=this.extractRelativeMousePosition_(e);var zoomScaleValue=1+(this.lastMouseViewPos_.y-
-newPosition.y)*0.01;this.zoomBy_(zoomScaleValue,false);this.storeLastMousePos_(e);},onEndZoom_:function(e){this.isZooming_=false;if(!e.isClick)
-e.preventDefault();},computeTouchCenter_:function(positions){var xSum=0;var ySum=0;for(var i=0;i<positions.length;++i){xSum+=positions[i].x;ySum+=positions[i].y;}
-return{x:xSum/positions.length,y:ySum/positions.length};},computeTouchSpan_:function(positions){var xMin=Number.MAX_VALUE;var yMin=Number.MAX_VALUE;var xMax=Number.MIN_VALUE;var yMax=Number.MIN_VALUE;for(var i=0;i<positions.length;++i){xMin=Math.min(xMin,positions[i].x);yMin=Math.min(yMin,positions[i].y);xMax=Math.max(xMax,positions[i].x);yMax=Math.max(yMax,positions[i].y);}
-return Math.sqrt((xMin-xMax)*(xMin-xMax)+
-(yMin-yMax)*(yMin-yMax));},onUpdateTransformForTouch_:function(e){var newPositions=this.extractRelativeTouchPositions_(e);var currentPositions=this.lastTouchViewPositions_;var newCenter=this.computeTouchCenter_(newPositions);var currentCenter=this.computeTouchCenter_(currentPositions);var newSpan=this.computeTouchSpan_(newPositions);var currentSpan=this.computeTouchSpan_(currentPositions);var vp=this.viewport_;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDelta=pixelRatio*(newCenter.x-currentCenter.x);var yDelta=newCenter.y-currentCenter.y;var zoomScaleValue=currentSpan>10?newSpan/currentSpan:1;var viewFocus=pixelRatio*newCenter.x;var worldFocus=vp.currentDisplayTransform.xViewToWorld(viewFocus);this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=zoomScaleValue;this.displayTransform_.xPanWorldPosToViewPos(worldFocus,viewFocus,viewWidth);this.displayTransform_.incrementPanXInViewUnits(xDelta);this.displayTransform_.panY-=yDelta;vp.setDisplayTransformImmediately(this.displayTransform_);this.storeLastTouchPositions_(e);},initHintText_:function(){this.$.hint_text.style.display='none';this.pendingHintTextClearTimeout_=undefined;},showHintText_:function(text){if(this.pendingHintTextClearTimeout_){window.clearTimeout(this.pendingHintTextClearTimeout_);this.pendingHintTextClearTimeout_=undefined;}
-this.pendingHintTextClearTimeout_=setTimeout(this.hideHintText_.bind(this),1000);this.$.hint_text.textContent=text;this.$.hint_text.style.display='';},hideHintText_:function(){this.pendingHintTextClearTimeout_=undefined;this.$.hint_text.style.display='none';}});'use strict';Polymer('tr-ui-find-control',{filterKeyDown:function(e){if(e.keyCode===27){var hkc=tr.b.getHotkeyControllerForElement(this);if(hkc){hkc.childRequestsBlur(this);}else{this.blur();}
-e.preventDefault();e.stopPropagation();return;}else if(e.keyCode===13){if(e.shiftKey)
-this.findPrevious();else
-this.findNext();}},filterBlur:function(e){this.updateHitCountEl();},filterFocus:function(e){this.$.filter.select();},filterMouseUp:function(e){e.preventDefault();},get controller(){return this.controller_;},set controller(c){this.controller_=c;this.updateHitCountEl();},focus:function(){this.$.filter.focus();},get hasFocus(){return this===document.activeElement;},filterTextChanged:function(){this.$.hitCount.textContent='';this.$.spinner.style.visibility='visible';this.controller.startFiltering(this.$.filter.value).then(function(){this.$.spinner.style.visibility='hidden';this.updateHitCountEl();}.bind(this));},findNext:function(){if(this.controller)
-this.controller.findNext();this.updateHitCountEl();},findPrevious:function(){if(this.controller)
-this.controller.findPrevious();this.updateHitCountEl();},updateHitCountEl:function(){if(!this.controller||!this.hasFocus){this.$.hitCount.textContent='';return;}
-var n=this.controller.filterHits.length;var i=n===0?-1:this.controller.currentHitIndex;this.$.hitCount.textContent=(i+1)+' of '+n;},setText:function(string){this.$.filter.value=string;}});'use strict';tr.exportTo('tr.e.tquery',function(){function Context(){this.event=undefined;this.ancestors=[];}
-Context.prototype={push:function(event){var ctx=new Context();ctx.ancestors=this.ancestors.slice();ctx.ancestors.push(event);return ctx;},pop:function(event){var ctx=new Context();ctx.event=this.ancestors[this.ancestors.length-1];ctx.ancestors=this.ancestors.slice(0,this.ancestors.length-1);return ctx;}};return{Context:Context};});'use strict';tr.exportTo('tr.e.tquery',function(){function Filter(){tr.c.ScriptingObject.call(this);}
-Filter.normalizeFilterExpression=function(filterExpression){if(filterExpression instanceof String||typeof(filterExpression)=='string'||filterExpression instanceof RegExp){var filter=new tr.e.tquery.FilterHasTitle(filterExpression);return filter;}
-return filterExpression;};Filter.prototype={__proto__:tr.c.ScriptingObject.prototype,evaluate:function(context){throw new Error('Not implemented');},matchValue_:function(value,expected){if(expected instanceof RegExp)
-return expected.test(value);else if(expected instanceof Function)
-return expected(value);return value===expected;}};return{Filter:Filter};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAllOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
-FilterAllOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
-return true;for(var i=0;i<this.subExpressions.length;i++){if(!this.subExpressions[i].evaluate(context))
-return false;}
-return true;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=[];for(var i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
-return new FilterAllOf(exprs);},{name:'allOf'});return{FilterAllOf:FilterAllOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAnyOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];};FilterAnyOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
-return true;for(var i=0;i<this.subExpressions.length;i++){if(this.subExpressions[i].evaluate(context))
-return true;}
-return false;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=[];for(var i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
-return new FilterAnyOf(exprs);},{name:'anyOf'});return{FilterAnyOf:FilterAnyOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasAncestor(opt_subExpression){this.subExpression=opt_subExpression;};FilterHasAncestor.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(!this.subExpression)
-return context.ancestors.length>0;while(context.ancestors.length){context=context.pop();if(this.subExpression.evaluate(context))
-return true;}
-return false;}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterHasAncestor(subExpression);},{name:'hasAncestor'});return{FilterHasAncestor:FilterHasAncestor};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasDuration(minValueOrExpected,opt_maxValue){if(minValueOrExpected!==undefined&&opt_maxValue!==undefined){this.minValue=minValueOrExpected;this.maxValue=opt_maxValue;}else{this.expected=minValueOrExpected;}};FilterHasDuration.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){if(context.event.duration===undefined)
-return false;if(this.minValue!==undefined&&this.maxValue!==undefined){return context.event.duration>=this.minValue&&context.event.duration<=this.maxValue;}
-return this.matchValue_(context.event.duration,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(minValueOrExpected,opt_maxValue){return new FilterHasDuration(minValueOrExpected,opt_maxValue);},{name:'hasDuration'});return{FilterHasDuration:FilterHasDuration};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasTitle(expected){tr.e.tquery.Filter.call(this);this.expected=expected;}
-FilterHasTitle.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){return this.matchValue_(context.event.title,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(expected){var filter=new tr.e.tquery.FilterHasTitle(expected);return filter;},{name:'hasTitle'});return{FilterHasTitle:FilterHasTitle};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterIsTopLevel(opt_subExpression){this.subExpression=opt_subExpression;}
-FilterIsTopLevel.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(context.ancestors.length>0)
-return false;if(!this.subExpression)
-return true;return this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterIsTopLevel(subExpression);},{name:'isTopLevel'});return{FilterIsTopLevel:FilterIsTopLevel};});'use strict';tr.exportTo('tr.e.tquery',function(){function addEventTreeToSelection(selection,event){selection.push(event);if(!event.subSlices)
-return;event.subSlices.forEach(addEventTreeToSelection.bind(undefined,selection));}
-function TQuery(model){tr.c.ScriptingObject.call(this);this.model_=model;this.parent_=undefined;this.filterExpression_=undefined;this.selection_=undefined;};TQuery.prototype={__proto__:tr.c.ScriptingObject.prototype,onModelChanged:function(model){this.model_=model;this.selection_=undefined;},get brushingStateController(){return this.brushingStateController_;},filter:function(filterExpression){var result=new TQuery(this.model_);result.parent_=this;result.filterExpression_=tr.e.tquery.Filter.normalizeFilterExpression(filterExpression);return result;},createFilterTaskGraph_:function(){var nodes=[];var node=this;while(node!==undefined){nodes.push(node);node=node.parent_;}
-var rootTask=new tr.b.Task();var lastTask=rootTask;for(var i=nodes.length-1;i>=0;i--){var node=nodes[i];if(node.selection_!==undefined)
-continue;node.selection_=new tr.model.EventSet();if(node.parent_===undefined){lastTask=lastTask.after(this.selectEverythingAsTask_(node.selection_));}else{var prevNode=nodes[i+1];lastTask=this.createFilterTaskForNode_(lastTask,node,prevNode);}}
-return{rootTask:rootTask,lastTask:lastTask,lastNode:node};},createFilterTaskForNode_:function(lastTask,node,prevNode){return lastTask.after(function(){node.evaluateFilterExpression_(prevNode.selection_,node.selection_);},this);},evaluateFilterExpression_:function(inputSelection,outputSelection){var seenEvents={};inputSelection.forEach(function(event){var context=new tr.e.tquery.Context();context.event=event;this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}.bind(this));},evaluateFilterExpressionForEvent_:function(context,inputSelection,outputSelection,seenEvents){var event=context.event;if(inputSelection.contains(event)&&!seenEvents[event.guid]){seenEvents[event.guid]=true;if(!this.filterExpression_||this.filterExpression_.evaluate(context))
-outputSelection.push(event);}
-if(!event.subSlices)
-return;context=context.push(event);for(var i=0;i<event.subSlices.length;i++){context.event=event.subSlices[i];this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}},selectEverythingAsTask_:function(selection){var filterTask=new tr.b.Task();this.model_.iterateAllEventContainers(function(container){filterTask.subTask(function(){container.iterateAllEventsInThisContainer(function(){return true;},addEventTreeToSelection.bind(undefined,selection));},this);},this);return filterTask;},ready:function(){return new Promise(function(resolve,reject){var graph=this.createFilterTaskGraph_();graph.lastTask=graph.lastTask.after(function(){resolve(this.selection_);},this);tr.b.Task.RunWhenIdle(graph.rootTask);}.bind(this));},get selection(){if(this.selection_===undefined){var graph=this.createFilterTaskGraph_();tr.b.Task.RunSynchronously(graph.rootTask);}
-return this.selection_;}};tr.c.ScriptingObjectRegistry.register(new TQuery(),{name:'$t'});return{TQuery:TQuery};});'use strict';Polymer('tr-ui-scripting-control',{_isEnterKey:function(event){return event.keyCode!==229&&event.keyIdentifier==='Enter';},_setFocused:function(focused){var promptEl=this.$.prompt;if(focused){promptEl.focus();this.$.root.classList.add('focused');if(promptEl.innerText.length>0){var sel=window.getSelection();sel.collapse(promptEl.firstChild,promptEl.innerText.length);}}else{promptEl.blur();this.$.root.classList.remove('focused');var parent=promptEl.parentElement;var nextEl=promptEl.nextSibling;promptEl.remove();parent.insertBefore(promptEl,nextEl);}},onConsoleFocus:function(e){e.stopPropagation();this._setFocused(true);},onConsoleBlur:function(e){e.stopPropagation();this._setFocused(false);},promptKeyDown:function(e){e.stopPropagation();if(!this._isEnterKey(e))
-return;var promptEl=this.$.prompt;var command=promptEl.innerText;if(command.length===0)
-return;promptEl.innerText='';this.addLine_(String.fromCharCode(187)+' '+command);try{var result=this.controller_.executeCommand(command);}catch(e){result=e.stack||e.stackTrace;}
-if(result instanceof tr.e.tquery.TQuery){result.ready().then(function(selection){this.addLine_(selection.length+' matches');this.controller_.brushingStateController.showScriptControlSelection(selection);}.bind(this));}else{this.addLine_(result);}},addLine_:function(line){var historyEl=this.$.history;if(historyEl.innerText.length!==0)
-historyEl.innerText+='\n';historyEl.innerText+=line;},promptKeyPress:function(e){e.stopPropagation();},toggleVisibility:function(){var root=this.$.root;if(!this.visible){root.classList.remove('hidden');this._setFocused(true);}else{root.classList.add('hidden');this._setFocused(false);}},get hasFocus(){return this===document.activeElement;},get visible(){var root=this.$.root;return!root.classList.contains('hidden');},get controller(){return this.controller_;},set controller(c){this.controller_=c;}});'use strict';Polymer('tr-ui-side-panel',{ready:function(){},get rangeOfInterest(){throw new Error('Not implemented');},set rangeOfInterest(rangeOfInterest){throw new Error('Not implemented');},get selection(){throw new Error('Not implemented');},set selection(selection){throw new Error('Not implemented');},get model(){throw new Error('Not implemented');},set model(model){throw new Error('Not implemented');},get listeningToKeys(){throw new Error('Not implemented');},supportsModel:function(m){throw new Error('Not implemented');}});'use strict';Polymer('tr-ui-side-panel-container',{ready:function(){this.activePanelContainer_=this.$.active_panel_container;this.tabStrip_=this.$.tab_strip;this.rangeOfInterest_=new tr.b.Range();this.brushingStateController_=undefined;this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onModelChanged_=this.onModelChanged_.bind(this);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);this.brushingStateController_.removeEventListener('model-changed',this.onModelChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);this.brushingStateController_.addEventListener('model-changed',this.onModelChanged_);}},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(){if(this.activePanel)
-this.activePanel.selection=this.selection;},get model(){return this.brushingStateController_.model;},onModelChanged_:function(){this.activePanelType_=undefined;this.updateContents_();},get expanded(){this.hasAttribute('expanded');},get activePanel(){if(this.activePanelContainer_.children.length===0)
-return undefined;return this.activePanelContainer_.children[0];},get activePanelType(){return this.activePanelType_;},set activePanelType(panelType){if(this.model===undefined)
-throw new Error('Cannot activate panel without a model');var panel=undefined;if(panelType)
-panel=document.createElement(panelType);if(panel!==undefined&&!panel.supportsModel(this.model))
-throw new Error('Cannot activate panel: does not support this model');if(this.activePanelType){this.getLabelElementForPanelType_(this.activePanelType).removeAttribute('selected');}
-this.activePanelContainer_.textContent='';if(panelType===undefined){this.removeAttribute('expanded');this.activePanelType_=undefined;return;}
-this.getLabelElementForPanelType_(panelType).setAttribute('selected',true);this.setAttribute('expanded',true);this.activePanelContainer_.appendChild(panel);panel.rangeOfInterest=this.rangeOfInterest_;panel.selection=this.selection_;panel.model=this.model;this.activePanelType_=panelType;},getPanelTypeForConstructor_:function(constructor){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType.constructor==constructor)
-return this.tabStrip_.children[i].panelType;}},getLabelElementForPanelType_:function(panelType){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType==panelType)
-return this.tabStrip_.children[i];}
-return undefined;},updateContents_:function(){var previouslyActivePanelType=this.activePanelType;this.tabStrip_.textContent='';var supportedPanelTypes=[];var panelTypes=tr.ui.b.getPolymerElementsThatSubclass('tr-ui-side-panel');panelTypes.forEach(function(panelType){var labelEl=document.createElement('tab-strip-label');var panel=document.createElement(panelType);labelEl.textContent=panel.textLabel;labelEl.panelType=panelType;var supported=panel.supportsModel(this.model);if(this.model&&supported.supported){supportedPanelTypes.push(panelType);labelEl.setAttribute('enabled',true);labelEl.addEventListener('click',function(){this.activePanelType=this.activePanelType===panelType?undefined:panelType;}.bind(this));}else{labelEl.title='Not supported for the current trace: '+
-supported.reason;labelEl.style.display='none';}
-this.tabStrip_.appendChild(labelEl);},this);if(previouslyActivePanelType&&supportedPanelTypes.indexOf(previouslyActivePanelType)!=-1){this.activePanelType=previouslyActivePanelType;this.setAttribute('expanded',true);}else{this.activePanelContainer_.textContent='';this.removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range==undefined)
-throw new Error('Must not be undefined');this.rangeOfInterest_=range;if(this.activePanel)
-this.activePanel.rangeOfInterest=range;}});'use strict';Polymer('tr-ui-timeline-view-help-overlay',{ready:function(){var mod=tr.isMac?'cmd ':'ctrl';var spans=this.shadowRoot.querySelectorAll('span.mod');for(var i=0;i<spans.length;i++){spans[i].textContent=mod;}}});'use strict';tr.exportTo('tr.b.u',function(){function GenericTable(items){if(items!==undefined)
-this.items=items;else
-this.items=[];};GenericTable.prototype={};return{GenericTable:GenericTable};});'use strict';tr.exportTo('tr.ui.units',function(){var ArrayOfNumbersSummaryModes={AVERAGE_MODE:'average-mode',TOTAL_MODE:'total-mode'};return{ArrayOfNumbersSummaryModes:ArrayOfNumbersSummaryModes};});'use strict';Polymer('tr-ui-u-array-of-numbers-span',{created:function(){this.numbers_=undefined;this.summaryMode_=tr.ui.units.ArrayOfNumbersSummaryModes.AVERAGE_MODE;},get summaryMode(){return this.summaryMode_;},set summaryMode(summaryMode){this.summaryMode_=summaryMode;this.updateContents_();},get numbers(){return this.numbers_;},set numbers(numbers){if(numbers===undefined){this.numbers_=undefined;this.updateContents_();return;}
-if(!(numbers instanceof Array))
-throw new Error('Must provide an array');this.numbers_=numbers;this.updateContents_();},updateContents_:function(){if(this.numbers_===undefined){this.shadowRoot.textContent='-';return;}
-var ArrayOfNumbersSummaryModes=tr.ui.units.ArrayOfNumbersSummaryModes;var value;if(this.summaryMode_===ArrayOfNumbersSummaryModes.AVERAGE_MODE)
-value=tr.b.Statistics.mean(this.numbers_);else
-value=tr.b.Statistics.sum(this.numbers_);var valueRounded=Math.round(value*1000.0)/1000.0;this.shadowRoot.textContent=valueRounded;}});'use strict';tr.exportTo('tr.ui.units',function(){var TEXT_COLUMN_MODE=1;var NUMERIC_COLUMN_MODE=2;var ELEMENT_COLUMN_MODE=3;function isNumeric(value){if((typeof value)==='number')
-return true;else if(value instanceof Number)
-return true;return false;}
-function GenericTableViewTotalsItem(opt_values){if(opt_values!==undefined)
-this.values=opt_values;else
-this.values=[];}
-function GenericTableViewColumnDescriptor(fieldName,firstFieldValue){this.title=fieldName;this.fieldName=fieldName;this.updateModeGivenValue(firstFieldValue);}
-GenericTableViewColumnDescriptor.prototype={get columnMode(){return this.columnMode_;},get isInNumericMode(){return this.columnMode_===NUMERIC_COLUMN_MODE;},cmp:function(a,b){if(this.columnMode_===ELEMENT_COLUMN_MODE)
-return 0;return tr.b.comparePossiblyUndefinedValues(a,b,function(a,b){var vA=a[this.fieldName];var vB=b[this.fieldName];return tr.b.comparePossiblyUndefinedValues(vA,vB,function(vA,vB){if(vA.localeCompare)
-return vA.localeCompare(vB);return vA-vB;},this);},this);},updateModeGivenValue:function(fieldValue){if(this.columnMode_===undefined){if(fieldValue===undefined||fieldValue===null)
-return;if(isNumeric(fieldValue)){this.columnMode_=NUMERIC_COLUMN_MODE;return;}
-if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
-this.columnMode_=TEXT_COLUMN_MODE;return;}
-if(fieldValue===undefined||fieldValue===null)
-return;if(isNumeric(fieldValue))
-return;if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
-if(this.columnMode_===NUMERIC_COLUMN_MODE)
-this.columnMode_=TEXT_COLUMN_MODE;},value:function(item){var fieldValue=item[this.fieldName];if(fieldValue instanceof GenericTableViewTotalsItem){var span=document.createElement('tr-ui-u-array-of-numbers-span');span.summaryMode=tr.ui.units.ArrayOfNumbersSummaryModes.TOTAL_MODE;span.numbers=fieldValue.values;return span;}
-if(fieldValue===undefined)
-return'-';if(fieldValue instanceof HTMLElement)
-return fieldValue;if(fieldValue instanceof Object){var gov=document.createElement('tr-ui-a-generic-object-view');gov.object=fieldValue;return gov;}
-return fieldValue;}};Polymer('tr-ui-u-generic-table-view',{created:function(){this.items_=undefined;this.importantColumNames_=[];},get items(){return this.items_;},set items(itemsOrGenericTable){if(itemsOrGenericTable===undefined){this.items_=undefined;}else if(itemsOrGenericTable instanceof Array){this.items_=itemsOrGenericTable;}else if(itemsOrGenericTable instanceof tr.b.u.GenericTable){this.items_=itemsOrGenericTable.items;}
-this.updateContents_();},get importantColumNames(){return this.importantColumNames_;},set importantColumNames(importantColumNames){this.importantColumNames_=importantColumNames;this.updateContents_();},createColumns_:function(){var columnsByName={};this.items_.forEach(function(item){tr.b.iterItems(item,function(itemFieldName,itemFieldValue){var colDesc=columnsByName[itemFieldName];if(colDesc!==undefined){colDesc.updateModeGivenValue(itemFieldValue);return;}
-colDesc=new GenericTableViewColumnDescriptor(itemFieldName,itemFieldValue);columnsByName[itemFieldName]=colDesc;},this);},this);var columns=tr.b.dictionaryValues(columnsByName);if(columns.length===0)
-return undefined;var isColumnNameImportant={};var importantColumNames=this.importantColumNames||[];importantColumNames.forEach(function(icn){isColumnNameImportant[icn]=true;});columns.sort(function(a,b){var iA=isColumnNameImportant[a.title]?1:0;var iB=isColumnNameImportant[b.title]?1:0;if((iB-iA)!==0)
-return iB-iA;return a.title.localeCompare(b.title);});var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';columns[0].width='250px';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;return columns;},createFooterRowsIfNeeded_:function(columns){var hasColumnThatIsNumeric=columns.some(function(column){return column.isInNumericMode;});if(!hasColumnThatIsNumeric)
-return[];var totalsItems={};columns.forEach(function(column){if(!column.isInNumericMode)
-return;var totalsItem=new GenericTableViewTotalsItem();this.items_.forEach(function(item){var fieldValue=item[column.fieldName];if(fieldValue===undefined||fieldValue===null)
-return;totalsItem.values.push(fieldValue);});totalsItems[column.fieldName]=totalsItem;},this);return[totalsItems];},updateContents_:function(){var columns;if(this.items_!==undefined)
-columns=this.createColumns_();if(!columns){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.footerRows=[];return;}
-this.$.table.tableColumns=columns;this.$.table.tableRows=this.items_;this.$.table.footerRows=this.createFooterRowsIfNeeded_(columns);this.$.table.rebuild();},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;}});return{GenericTableViewTotalsItem:GenericTableViewTotalsItem,GenericTableViewColumnDescriptor:GenericTableViewColumnDescriptor};});'use strict';Polymer('tr-ui-timeline-view-metadata-overlay',{created:function(){this.metadata_=undefined;},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.gtv.items=this.metadata_;}});'use strict';Polymer('tr-ui-u-preferred-display-unit',{ready:function(){this.preferredTimeDisplayMode_=undefined;},attached:function(){tr.b.u.Units.didPreferredTimeDisplayUnitChange();},detached:function(){tr.b.u.Units.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)
-return;this.preferredTimeDisplayMode_=v;tr.b.u.Units.didPreferredTimeDisplayUnitChange();}});'use strict';Polymer('tr-ui-timeline-view',{ready:function(){this.tabIndex=0;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.e&&window.tr.e.rail&&window.tr.e.rail.RAILScore){this.railScoreSpan_=document.createElement('tr-ui-e-rail-rail-score-span');this.rightControls.appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
-this.optionsDropdown_=this.$.view_options_dropdown;this.optionsDropdown_.iconElement.textContent='View Options';this.showFlowEvents_=false;this.optionsDropdown_.appendChild(tr.ui.b.createCheckBox(this,'showFlowEvents','tr.ui.TimelineView.showFlowEvents',false,'Flow events'));this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');this.optionsDropdown_.appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();this.collapsingControls.appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;tr.ui.b.decorate(this.dragEl_,tr.ui.b.DragHandle);this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){var sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},domReady:function(){this.trackViewContainer_=this.querySelector('#track_view_container');},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},updateDocumentFavicon:function(){var hue;if(!this.model)
-hue='blue';else
-hue=this.model.faviconHue;var faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined)
-faviconData=tr.ui.b.FaviconsByHue['blue'];var link=document.head.querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';document.head.appendChild(link);}
-link.href=faviconData;},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;if(!this.trackView_)
-return;this.trackView_.viewport.showFlowEvents=showFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)
-return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_:function(){var helpButtonEl=this.$.view_help_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));dlg.visible=true;e.stopPropagation();}
-helpButtonEl.addEventListener('click',onClick.bind(this));},initConsoleButton_:function(){var toggleEl=this.$.view_console_button;function onClick(e){this.scriptingCtl_.toggleVisibility();e.stopPropagation();return false;}
-toggleEl.addEventListener('click',onClick.bind(this));},initMetadataButton_:function(){var showEl=this.$.view_metadata_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Metadata for trace';var metadataOverlay=document.createElement('tr-ui-timeline-view-metadata-overlay');metadataOverlay.metadata=this.model.metadata;dlg.appendChild(metadataOverlay);dlg.visible=true;e.stopPropagation();return false;}
-showEl.addEventListener('click',onClick.bind(this));this.updateMetadataButtonVisibility_();},updateMetadataButtonVisibility_:function(){var showEl=this.$.view_metadata_button;showEl.style.display=(this.model&&this.model.metadata.length)?'':'none';},get leftControls(){return this.leftControlsEl_;},get rightControls(){return this.rightControlsEl_;},get collapsingControls(){return this.collapsingControlsEl_;},get viewTitle(){return this.titleEl_.textContent.substring(this.titleEl_.textContent.length-2);},set viewTitle(text){if(text===undefined){this.titleEl_.textContent='';this.titleEl_.hidden=true;return;}
-this.titleEl_.hidden=false;this.titleEl_.textContent=text;},get model(){if(this.trackView_)
-return this.trackView_.model;return undefined;},set model(model){var modelInstanceChanged=model!=this.model;var modelValid=model&&!model.bounds.isEmpty;var importWarningsEl=this.shadowRoot.querySelector('#import-warnings');importWarningsEl.textContent='';if(modelInstanceChanged){if(this.railScoreSpan_)
-this.railScoreSpan_.railScore=undefined;this.trackViewContainer_.textContent='';if(this.trackView_){this.trackView_.viewport.removeEventListener('change',this.onViewportChanged_);this.trackView_.brushingStateController=undefined;this.trackView_.detach();this.trackView_=undefined;}
-this.brushingStateController_.modelWillChange();}
-if(modelValid&&!this.trackView_){this.trackView_=document.createElement('tr-ui-timeline-track-view');this.trackView_.timelineView=this;this.trackView.brushingStateController=this.brushingStateController_;this.trackViewContainer_.appendChild(this.trackView_);this.trackView_.viewport.addEventListener('change',this.onViewportChanged_);}
-if(modelValid){this.trackView_.model=model;this.trackView_.viewport.showFlowEvents=this.showFlowEvents;this.trackView_.viewport.highlightVSync=this.highlightVSync;if(this.railScoreSpan_){var railScore=tr.e.rail.RAILScore.fromModel(model);this.railScoreSpan_.railScore=railScore;}
-this.$.display_unit.preferredTimeDisplayMode=model.intrinsicTimeUnit;}
-if(model){model.importWarningsThatShouldBeShownToUser.forEach(function(importWarning){importWarningsEl.addMessage('Import Warning: '+importWarning.type+': '+
-importWarning.message);},this);}
-if(modelInstanceChanged){this.updateMetadataButtonVisibility_();this.brushingStateController_.modelDidChange();this.onViewportChanged_();}},get brushingStateController(){return this.brushingStateController_;},get trackView(){return this.trackView_;},get settings(){if(!this.settings_)
-this.settings_=new tr.b.Settings();return this.settings_;},set focusElement(value){throw new Error('This is deprecated. Please set globalMode to true.');},bindKeyListeners_:function(){var hkc=this.hotkeyController;hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'`'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){this.scriptingCtl_.toggleVisibility();if(!this.scriptingCtl_.hasFocus)
-this.focus();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'/'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){if(this.scriptingCtl_.hasFocus)
-return;if(this.findCtl_.hasFocus)
-this.focus();else
-this.findCtl_.focus();e.preventDefault();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'?'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.$.view_help_button.click();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'v'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.toggleHighlightVSync_();e.stopPropagation();}}));},onViewportChanged_:function(e){var spc=this.sidePanelContainer_;if(!this.trackView_){spc.rangeOfInterest.reset();return;}
-var vr=this.trackView_.viewport.interestRange.asRangeObject();if(!spc.rangeOfInterest.equals(vr))
-spc.rangeOfInterest=vr;},toggleHighlightVSync_:function(){this.highlightVSyncCheckbox_.checked=!this.highlightVSyncCheckbox_.checked;},setFindCtlText:function(string){this.findCtl_.setText(string);}});'use strict';tr.exportTo('tr.e.cc',function(){function PictureAsImageData(picture,errorOrImageData){this.picture_=picture;if(errorOrImageData instanceof ImageData){this.error_=undefined;this.imageData_=errorOrImageData;}else{this.error_=errorOrImageData;this.imageData_=undefined;}};PictureAsImageData.Pending=function(picture){return new PictureAsImageData(picture,undefined);};PictureAsImageData.prototype={get picture(){return this.picture_;},get error(){return this.error_;},get imageData(){return this.imageData_;},isPending:function(){return this.error_===undefined&&this.imageData_===undefined;},asCanvas:function(){if(!this.imageData_)
-return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.imageData_.width;canvas.height=this.imageData_.height;ctx.putImageData(this.imageData_,0,0);return canvas;}};return{PictureAsImageData:PictureAsImageData};});'use strict';tr.exportTo('tr.e.cc',function(){var convertedNameCache={};function convertNameToJSConvention(name){if(name in convertedNameCache)
-return convertedNameCache[name];if(name[0]=='_'||name[name.length-1]=='_'){convertedNameCache[name]=name;return name;}
-var words=name.split('_');if(words.length==1){convertedNameCache[name]=words[0];return words[0];}
-for(var i=1;i<words.length;i++)
-words[i]=words[i][0].toUpperCase()+words[i].substring(1);convertedNameCache[name]=words.join('');return convertedNameCache[name];}
-function convertObjectFieldNamesToJSConventions(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){delete object[fieldName];object[newFieldName]=fieldValue;return newFieldName;});}
-function convertQuadSuffixedTypesToQuads(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){});}
-function convertObject(object){convertObjectFieldNamesToJSConventions(object);convertQuadSuffixedTypesToQuads(object);}
-function moveRequiredFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
-throw Error('Expected field '+key+' not found in args');if(object[key]!==undefined)
-throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
-function moveOptionalFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
-continue;if(object[key]!==undefined)
-throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
-function preInitializeObject(object){preInitializeObjectInner(object.args,false);}
-function preInitializeObjectInner(object,hasRecursed){if(!(object instanceof Object))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++)
-preInitializeObjectInner(object[i],true);return;}
-if(hasRecursed&&(object instanceof tr.model.ObjectSnapshot||object instanceof tr.model.ObjectInstance))
-return;for(var key in object){var newKey=convertNameToJSConvention(key);if(newKey!=key){var value=object[key];delete object[key];object[newKey]=value;key=newKey;}
-if(/Quad$/.test(key)&&!(object[key]instanceof tr.b.Quad)){var q;try{q=tr.b.Quad.from8Array(object[key]);}catch(e){console.log(e);}
-object[key]=q;continue;}
-if(/Rect$/.test(key)&&!(object[key]instanceof tr.b.Rect)){var r;try{r=tr.b.Rect.fromArray(object[key]);}catch(e){console.log(e);}
-object[key]=r;}
-preInitializeObjectInner(object[key],true);}}
-function bytesToRoundedMegabytes(bytes){return Math.round(bytes/100000.0)/10.0;}
-return{preInitializeObject:preInitializeObject,convertNameToJSConvention:convertNameToJSConvention,moveRequiredFieldsFromArgsToToplevel:moveRequiredFieldsFromArgsToToplevel,moveOptionalFieldsFromArgsToToplevel:moveOptionalFieldsFromArgsToToplevel,bytesToRoundedMegabytes:bytesToRoundedMegabytes};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var PictureCount=0;var OPS_TIMING_ITERATIONS=3;function Picture(skp64,layerRect){this.skp64_=skp64;this.layerRect_=layerRect;this.guid_=tr.b.GUID.allocate();}
-Picture.prototype={get canSave(){return true;},get layerRect(){return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){return this.skp64_;},getOps:function(){if(!PictureSnapshot.CanGetOps()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
-var ops=window.chrome.skiaBenchmarking.getOps({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!ops)
-console.error('Failed to get picture ops.');return ops;},getOpTimings:function(){if(!PictureSnapshot.CanGetOpTimings()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
-var opTimings=window.chrome.skiaBenchmarking.getOpTimings({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!opTimings)
-console.error('Failed to get picture op timings.');return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
-return ops;if(opTimings[iteration].cmd_times.length!=ops.length)
-return ops;}
-for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
-min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
-return ops;},rasterize:function(params,rasterCompleteCallback){if(!PictureSnapshot.CanRasterize()||!PictureSnapshot.CanGetOps()){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,tr.e.cc.PictureSnapshot.HowToEnablePictureDebugging()));return;}
-var raster=window.chrome.skiaBenchmarking.rasterize({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}},{stop:params.stopIndex===undefined?-1:params.stopIndex,overdraw:!!params.showOverdraw,params:{}});if(raster){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=raster.width;canvas.height=raster.height;var imageData=ctx.createImageData(raster.width,raster.height);imageData.data.set(new Uint8ClampedArray(raster.data));rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,imageData));}else{var error='Failed to rasterize picture. '+'Your recording may be from an old Chrome version. '+'The SkPicture format is not backward compatible.';rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,error));}}};function LayeredPicture(pictures){this.guid_=tr.b.GUID.allocate();this.pictures_=pictures;this.layerRect_=undefined;}
-LayeredPicture.prototype={__proto__:Picture.prototype,get canSave(){return false;},get typeName(){return'cc::LayeredPicture';},get layerRect(){if(this.layerRect_!==undefined)
-return this.layerRect_;this.layerRect_={x:0,y:0,width:0,height:0};for(var i=0;i<this.pictures_.length;++i){var rect=this.pictures_[i].layerRect;this.layerRect_.x=Math.min(this.layerRect_.x,rect.x);this.layerRect_.y=Math.min(this.layerRect_.y,rect.y);this.layerRect_.width=Math.max(this.layerRect_.width,rect.x+rect.width);this.layerRect_.height=Math.max(this.layerRect_.height,rect.y+rect.height);}
-return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){throw new Error('Not available with a LayeredPicture.');},getOps:function(){var ops=[];for(var i=0;i<this.pictures_.length;++i)
-ops=ops.concat(this.pictures_[i].getOps());return ops;},getOpTimings:function(){var opTimings=this.pictures_[0].getOpTimings();for(var i=1;i<this.pictures_.length;++i){var timings=this.pictures_[i].getOpTimings();opTimings.cmd_times=opTimings.cmd_times.concat(timings.cmd_times);opTimings.total_time+=timings.total_time;}
-return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
-return ops;}
-for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
-min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
-return ops;},rasterize:function(params,rasterCompleteCallback){this.picturesAsImageData_=[];var rasterCallback=function(pictureAsImageData){this.picturesAsImageData_.push(pictureAsImageData);if(this.picturesAsImageData_.length!==this.pictures_.length)
-return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.layerRect.width;canvas.height=this.layerRect.height;for(var i=0;i<this.picturesAsImageData_.length;++i){ctx.putImageData(this.picturesAsImageData_[i].imageData,this.pictures_[i].layerRect.x,this.pictures_[i].layerRect.y);}
-this.picturesAsImageData_=[];rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,ctx.getImageData(this.layerRect.x,this.layerRect.y,this.layerRect.width,this.layerRect.height)));}.bind(this);for(var i=0;i<this.pictures_.length;++i)
-this.pictures_[i].rasterize(params,rasterCallback);}};function PictureSnapshot(){ObjectSnapshot.apply(this,arguments);}
-PictureSnapshot.HasSkiaBenchmarking=function(){return tr.isExported('chrome.skiaBenchmarking');}
-PictureSnapshot.CanRasterize=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.rasterize)
-return false;return true;}
-PictureSnapshot.CanGetOps=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.getOps)
-return false;return true;}
-PictureSnapshot.CanGetOpTimings=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.getOpTimings)
-return false;return true;}
-PictureSnapshot.CanGetInfo=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.getInfo)
-return false;return true;}
-PictureSnapshot.HowToEnablePictureDebugging=function(){if(tr.isHeadless)
-return'Pictures only work in chrome';var usualReason=['For pictures to show up, you need to have Chrome running with ','--enable-skia-benchmarking. Please restart chrome with this flag ','and try again.'].join('');if(!tr.isExported('global.chrome.skiaBenchmarking'))
-return usualReason;if(!global.chrome.skiaBenchmarking.rasterize)
-return'Your chrome is old';if(!global.chrome.skiaBenchmarking.getOps)
-return'Your chrome is old: skiaBenchmarking.getOps not found';if(!global.chrome.skiaBenchmarking.getOpTimings)
-return'Your chrome is old: skiaBenchmarking.getOpTimings not found';if(!global.chrome.skiaBenchmarking.getInfo)
-return'Your chrome is old: skiaBenchmarking.getInfo not found';return'Rasterizing is on';}
-PictureSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.rasterResult_=undefined;},initialize:function(){if(this.args.alias)
-this.args=this.args.alias.args;if(!this.args.params.layerRect)
-throw new Error('Missing layer rect');this.layerRect_=this.args.params.layerRect;this.picture_=new Picture(this.args.skp64,this.args.params.layerRect);},set picture(picture){this.picture_=picture;},get canSave(){return this.picture_.canSave;},get layerRect(){return this.layerRect_?this.layerRect_:this.picture_.layerRect;},get guid(){return this.picture_.guid;},getBase64SkpData:function(){return this.picture_.getBase64SkpData();},getOps:function(){return this.picture_.getOps();},getOpTimings:function(){return this.picture_.getOpTimings();},tagOpsWithTimings:function(ops){return this.picture_.tagOpsWithTimings(ops);},rasterize:function(params,rasterCompleteCallback){this.picture_.rasterize(params,rasterCompleteCallback);}};ObjectSnapshot.register(PictureSnapshot,{typeNames:['cc::Picture']});return{PictureSnapshot:PictureSnapshot,Picture:Picture,LayeredPicture:LayeredPicture};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function DisplayItemList(skp64,layerRect){tr.e.cc.Picture.apply(this,arguments);}
-DisplayItemList.prototype={__proto__:tr.e.cc.Picture.prototype};function DisplayItemListSnapshot(){tr.e.cc.PictureSnapshot.apply(this,arguments);}
-DisplayItemListSnapshot.prototype={__proto__:tr.e.cc.PictureSnapshot.prototype,initialize:function(){tr.e.cc.PictureSnapshot.prototype.initialize.call(this);this.displayItems_=this.args.params.items;},get items(){return this.displayItems_;}};ObjectSnapshot.register(DisplayItemListSnapshot,{typeNames:['cc::DisplayItemList']});return{DisplayItemListSnapshot:DisplayItemListSnapshot,DisplayItemList:DisplayItemList};});'use strict';tr.exportTo('tr.e.cc',function(){var constants={};constants.ACTIVE_TREE=0;constants.PENDING_TREE=1;constants.HIGH_PRIORITY_BIN=0;constants.LOW_PRIORITY_BIN=1;constants.SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';constants.BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';return{constants:constants};});'use strict';tr.exportTo('tr.e.cc',function(){function Region(){this.rects=[];}
-Region.fromArray=function(array){if(array.length%4!=0)
-throw new Error('Array must consist be a multiple of 4 in length');var r=new Region();for(var i=0;i<array.length;i+=4){r.rects.push(tr.b.Rect.fromXYWH(array[i],array[i+1],array[i+2],array[i+3]));}
-return r;}
-Region.fromArrayOrUndefined=function(array){if(array===undefined)
-return new Region();return Region.fromArray(array);};Region.prototype={__proto__:Region.prototype,rectIntersects:function(r){for(var i=0;i<this.rects.length;i++){if(this.rects[i].intersects(r))
-return true;}
-return false;},addRect:function(r){this.rects.push(r);}};return{Region:Region};});'use strict';tr.exportTo('tr.e.cc',function(){function TileCoverageRect(rect,tile){this.geometryRect=rect;this.tile=tile;}
-return{TileCoverageRect:TileCoverageRect};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeImpl_=undefined;this.parentLayer=undefined;},initialize:function(){this.invalidation=new tr.e.cc.Region();this.annotatedInvalidation=new tr.e.cc.Region();this.unrecordedRegion=new tr.e.cc.Region();this.pictures=[];tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['layerId','children','layerQuad']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['maskLayer','replicaLayer','idealContentsScale','geometryContentsScale','layoutRects','usingGpuRasterization']);this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;this.bounds=tr.b.Rect.fromXYWH(0,0,this.args.bounds.width,this.args.bounds.height);if(this.args.animationBounds){this.animationBoundsRect=tr.b.Rect.fromXYWH(this.args.animationBounds[0],this.args.animationBounds[1],this.args.animationBounds[3],this.args.animationBounds[4]);}
-for(var i=0;i<this.children.length;i++)
-this.children[i].parentLayer=this;if(this.maskLayer)
-this.maskLayer.parentLayer=this;if(this.replicaLayer)
-this.replicaLayer.parentLayer=this;if(!this.geometryContentsScale)
-this.geometryContentsScale=1.0;if(!this.idealContentsScale)
-this.idealContentsScale=1.0;this.touchEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.touchEventHandlerRegion);this.wheelEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.wheelEventHandlerRegion);this.nonFastScrollableRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.nonFastScrollableRegion);},get layerTreeImpl(){if(this.layerTreeImpl_)
-return this.layerTreeImpl_;if(this.parentLayer)
-return this.parentLayer.layerTreeImpl;return undefined;},set layerTreeImpl(layerTreeImpl){this.layerTreeImpl_=layerTreeImpl;},get activeLayer(){if(this.layerTreeImpl.whichTree==constants.ACTIVE_TREE)
-return this;var activeTree=this.layerTreeImpl.layerTreeHostImpl.activeTree;return activeTree.findLayerWithId(this.layerId);},get pendingLayer(){if(this.layerTreeImpl.whichTree==constants.PENDING_TREE)
-return this;var pendingTree=this.layerTreeImpl.layerTreeHostImpl.pendingTree;return pendingTree.findLayerWithId(this.layerId);}};function PictureLayerImplSnapshot(){LayerImplSnapshot.apply(this,arguments);}
-PictureLayerImplSnapshot.prototype={__proto__:LayerImplSnapshot.prototype,initialize:function(){LayerImplSnapshot.prototype.initialize.call(this);if(this.args.invalidation){this.invalidation=tr.e.cc.Region.fromArray(this.args.invalidation);delete this.args.invalidation;}
-if(this.args.annotatedInvalidationRects){this.annotatedInvalidation=new tr.e.cc.Region();for(var i=0;i<this.args.annotatedInvalidationRects.length;++i){var annotatedRect=this.args.annotatedInvalidationRects[i];var rect=annotatedRect.geometryRect;rect.reason=annotatedRect.reason;this.annotatedInvalidation.addRect(rect);}
-delete this.args.annotatedInvalidationRects;}
-if(this.args.unrecordedRegion){this.unrecordedRegion=tr.e.cc.Region.fromArray(this.args.unrecordedRegion);delete this.args.unrecordedRegion;}
-if(this.args.pictures){this.pictures=this.args.pictures;this.pictures.sort(function(a,b){return a.ts-b.ts;});}
-this.tileCoverageRects=[];if(this.args.coverageTiles){for(var i=0;i<this.args.coverageTiles.length;++i){var rect=this.args.coverageTiles[i].geometryRect.scale(this.idealContentsScale);var tile=this.args.coverageTiles[i].tile;this.tileCoverageRects.push(new tr.e.cc.TileCoverageRect(rect,tile));}
-delete this.args.coverageTiles;}}};ObjectSnapshot.register(PictureLayerImplSnapshot,{typeName:'cc::PictureLayerImpl'});ObjectSnapshot.register(LayerImplSnapshot,{typeNames:['cc::LayerImpl','cc::DelegatedRendererLayerImpl','cc::HeadsUpDisplayLayerImpl','cc::IOSurfaceLayerImpl','cc::NinePatchLayerImpl','cc::PictureImageLayerImpl','cc::ScrollbarLayerImpl','cc::SolidColorLayerImpl','cc::SurfaceLayerImpl','cc::TextureLayerImpl','cc::TiledLayerImpl','cc::VideoLayerImpl','cc::PaintedScrollbarLayerImpl','ClankPatchLayer','TabBorderLayer','CounterLayer']});return{LayerImplSnapshot:LayerImplSnapshot,PictureLayerImplSnapshot:PictureLayerImplSnapshot};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerTreeImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerTreeImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeHostImpl=undefined;this.whichTree=undefined;this.sourceFrameNumber=undefined;},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['rootLayer','renderSurfaceLayerList']);if(this.args.sourceFrameNumber)
-this.sourceFrameNumber=this.args.sourceFrameNumber;this.rootLayer.layerTreeImpl=this;if(this.args.swapPromiseTraceIds&&this.args.swapPromiseTraceIds.length){this.tracedInputLatencies=[];var ownProcess=this.objectInstance.parent;var model=ownProcess.model;if(tr.e.audits.ChromeModelHelper.supportsModel(model))
-this._initializeTracedInputLatencies(model);}},_initializeTracedInputLatencies:function(model){var modelHelper=new tr.e.audits.ChromeModelHelper(model);if(!modelHelper.browserHelper)
-return;var latencyEvents=modelHelper.browserHelper.getLatencyEventsInRange(model.bounds);latencyEvents.forEach(function(event){for(var i=0;i<this.args.swapPromiseTraceIds.length;i++){if(!event.args.data||!event.args.data.trace_id)
-continue;if(parseInt(event.args.data.trace_id)===this.args.swapPromiseTraceIds[i])
-this.tracedInputLatencies.push(event);}},this);},get hasSourceFrameBeenDrawnBefore(){if(this.whichTree==tr.e.cc.constants.PENDING_TREE)
-return false;if(this.sourceFrameNumber===undefined)
-return;var thisLTHI=this.layerTreeHostImpl;var thisLTHIIndex=thisLTHI.objectInstance.snapshots.indexOf(thisLTHI);var prevLTHIIndex=thisLTHIIndex-1;if(prevLTHIIndex<0||prevLTHIIndex>=thisLTHI.objectInstance.snapshots.length)
-return false;var prevLTHI=thisLTHI.objectInstance.snapshots[prevLTHIIndex];if(!prevLTHI.activeTree)
-return false;if(prevLTHI.activeTree.sourceFrameNumber===undefined)
-return;return prevLTHI.activeTree.sourceFrameNumber==this.sourceFrameNumber;},get otherTree(){var other=this.whichTree==constants.ACTIVE_TREE?constants.PENDING_TREE:constants.ACTIVE_TREE;return this.layerTreeHostImpl.getTree(other);},get gpuMemoryUsageInBytes(){var totalBytes=0;this.iterLayers(function(layer){if(layer.gpuMemoryUsageInBytes!==undefined)
-totalBytes+=layer.gpuMemoryUsageInBytes;});return totalBytes;},iterLayers:function(func,thisArg){var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])
-return;visitedLayers[layer.layerId]=true;func.call(thisArg,layer,depth,isMask,isReplica);if(layer.children){for(var i=0;i<layer.children.length;i++)
-visitLayer(layer.children[i],depth+1);}
-if(layer.maskLayer)
-visitLayer(layer.maskLayer,depth+1,true,false);if(layer.replicaLayer)
-visitLayer(layer.replicaLayer,depth+1,false,true);}
-visitLayer(this.rootLayer,0,false,false);},findLayerWithId:function(id){var foundLayer=undefined;function visitLayer(layer){if(layer.layerId==id)
-foundLayer=layer;}
-this.iterLayers(visitLayer);return foundLayer;}};ObjectSnapshot.register(LayerTreeImplSnapshot,{typeName:'cc::LayerTreeImpl'});return{LayerTreeImplSnapshot:LayerTreeImplSnapshot};});'use strict';tr.exportTo('tr.b',function(){function BBox2(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};BBox2.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addBBox2:function(bbox2){if(bbox2.isEmpty)
-return;this.addVec2(bbox2.min_);this.addVec2(bbox2.max_);},clone:function(){var bbox=new BBox2();bbox.addBBox2(this);return bbox;},addXY:function(x,y){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,x,y);vec2.set(this.min_,x,y);this.isEmpty_=false;return;}
-this.max_[0]=Math.max(this.max_[0],x);this.max_[1]=Math.max(this.max_[1],y);this.min_[0]=Math.min(this.min_[0],x);this.min_[1]=Math.min(this.min_[1],y);},addVec2:function(value){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,value[0],value[1]);vec2.set(this.min_,value[0],value[1]);this.isEmpty_=false;return;}
-this.max_[0]=Math.max(this.max_[0],value[0]);this.max_[1]=Math.max(this.max_[1],value[1]);this.min_[0]=Math.min(this.min_[0],value[0]);this.min_[1]=Math.min(this.min_[1],value[1]);},addQuad:function(quad){this.addVec2(quad.p1);this.addVec2(quad.p2);this.addVec2(quad.p3);this.addVec2(quad.p4);},get minVec2(){if(this.isEmpty_)
-return undefined;return this.min_;},get maxVec2(){if(this.isEmpty_)
-return undefined;return this.max_;},get sizeAsVec2(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no size');var size=vec2.create();vec2.subtract(size,this.max_,this.min_);return size;},get size(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no size');return{width:this.max_[0]-this.min_[0],height:this.max_[1]-this.min_[1]};},get width(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no width');return this.max_[0]-this.min_[0];},get height(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no width');return this.max_[1]-this.min_[1];},toString:function(){if(this.isEmpty_)
-return'empty';return'min=('+this.min_[0]+','+this.min_[1]+') '+'max=('+this.max_[0]+','+this.max_[1]+')';},asRect:function(){return tr.b.Rect.fromXYWH(this.min_[0],this.min_[1],this.max_[0]-this.min_[0],this.max_[1]-this.min_[1]);}};return{BBox2:BBox2};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayerTreeHostImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerTreeHostImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['deviceViewportSize','activeTree']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['pendingTree']);if(this.args.activeTiles!==undefined){this.activeTiles=this.args.activeTiles;delete this.args.activeTiles;}else if(this.args.tiles!==undefined){this.activeTiles=this.args.tiles;delete this.args.tiles;}
-if(!this.activeTiles)
-this.activeTiles=[];this.activeTree.layerTreeHostImpl=this;this.activeTree.whichTree=constants.ACTIVE_TREE;if(this.pendingTree){this.pendingTree.layerTreeHostImpl=this;this.pendingTree.whichTree=constants.PENDING_TREE;}},getContentsScaleNames:function(){var scales={};for(var i=0;i<this.activeTiles.length;++i){var tile=this.activeTiles[i];scales[tile.contentsScale]=tile.resolution;}
-return scales;},getTree:function(whichTree){if(whichTree==constants.ACTIVE_TREE)
-return this.activeTree;if(whichTree==constants.PENDING_TREE)
-return this.pendingTree;throw new Exception('Unknown tree type + '+whichTree);},get tilesHaveGpuMemoryUsageInfo(){if(this.tilesHaveGpuMemoryUsageInfo_!==undefined)
-return this.tilesHaveGpuMemoryUsageInfo_;for(var i=0;i<this.activeTiles.length;i++){if(this.activeTiles[i].gpuMemoryUsageInBytes===undefined)
-continue;this.tilesHaveGpuMemoryUsageInfo_=true;return true;}
-this.tilesHaveGpuMemoryUsageInfo_=false;return false;},get gpuMemoryUsageInBytes(){if(!this.tilesHaveGpuMemoryUsageInfo)
-return;var usage=0;for(var i=0;i<this.activeTiles.length;i++){var u=this.activeTiles[i].gpuMemoryUsageInBytes;if(u!==undefined)
-usage+=u;}
-return usage;},get userFriendlyName(){var frameNumber;if(!this.activeTree){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{if(this.activeTree.sourceFrameNumber===undefined)
-frameNumber=this.objectInstance.snapshots.indexOf(this);else
-frameNumber=this.activeTree.sourceFrameNumber;}
-return'cc::LayerTreeHostImpl frame '+frameNumber;}};ObjectSnapshot.register(LayerTreeHostImplSnapshot,{typeName:'cc::LayerTreeHostImpl'});function LayerTreeHostImplInstance(){ObjectInstance.apply(this,arguments);this.allLayersBBox_=undefined;}
-LayerTreeHostImplInstance.prototype={__proto__:ObjectInstance.prototype,get allContentsScales(){if(this.allContentsScales_)
-return this.allContentsScales_;var scales={};for(var tileID in this.allTileHistories_){var tileHistory=this.allTileHistories_[tileID];scales[tileHistory.contentsScale]=true;}
-this.allContentsScales_=tr.b.dictionaryKeys(scales);return this.allContentsScales_;},get allLayersBBox(){if(this.allLayersBBox_)
-return this.allLayersBBox_;var bbox=new tr.b.BBox2();function handleTree(tree){tree.renderSurfaceLayerList.forEach(function(layer){bbox.addQuad(layer.layerQuad);});}
-this.snapshots.forEach(function(lthi){handleTree(lthi.activeTree);if(lthi.pendingTree)
-handleTree(lthi.pendingTree);});this.allLayersBBox_=bbox;return this.allLayersBBox_;}};ObjectInstance.register(LayerTreeHostImplInstance,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshot:LayerTreeHostImplSnapshot,LayerTreeHostImplInstance:LayerTreeHostImplInstance};});'use strict';tr.exportTo('tr.e.cc',function(){var tileTypes={highRes:'highRes',lowRes:'lowRes',extraHighRes:'extraHighRes',extraLowRes:'extraLowRes',missing:'missing',culled:'culled',solidColor:'solidColor',picture:'picture',directPicture:'directPicture',unknown:'unknown'};var tileBorder={highRes:{color:'rgba(80, 200, 200, 0.7)',width:1},lowRes:{color:'rgba(212, 83, 192, 0.7)',width:2},extraHighRes:{color:'rgba(239, 231, 20, 0.7)',width:2},extraLowRes:{color:'rgba(93, 186, 18, 0.7)',width:2},missing:{color:'rgba(255, 0, 0, 0.7)',width:1},culled:{color:'rgba(160, 100, 0, 0.8)',width:1},solidColor:{color:'rgba(128, 128, 128, 0.7)',width:1},picture:{color:'rgba(64, 64, 64, 0.7)',width:1},directPicture:{color:'rgba(127, 255, 0, 1.0)',width:1},unknown:{color:'rgba(0, 0, 0, 1.0)',width:2}};return{tileTypes:tileTypes,tileBorder:tileBorder};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function TileSnapshot(){ObjectSnapshot.apply(this,arguments);}
-TileSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['layerId','contentsScale','contentRect']);if(this.args.managedState){this.resolution=this.args.managedState.resolution;this.isSolidColor=this.args.managedState.isSolidColor;this.isUsingGpuMemory=this.args.managedState.isUsingGpuMemory;this.hasResource=this.args.managedState.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}else{this.resolution=this.args.resolution;this.isSolidColor=this.args.drawInfo.isSolidColor;this.isUsingGpuMemory=this.args.isUsingGpuMemory;this.hasResource=this.args.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}
-if(this.contentRect)
-this.layerRect=this.contentRect.scale(1.0/this.contentsScale);if(this.isSolidColor)
-this.type_=tr.e.cc.tileTypes.solidColor;else if(!this.hasResource)
-this.type_=tr.e.cc.tileTypes.missing;else if(this.resolution==='HIGH_RESOLUTION')
-this.type_=tr.e.cc.tileTypes.highRes;else if(this.resolution==='LOW_RESOLUTION')
-this.type_=tr.e.cc.tileTypes.lowRes;else
-this.type_=tr.e.cc.tileTypes.unknown;},getTypeForLayer:function(layer){var type=this.type_;if(type==tr.e.cc.tileTypes.unknown){if(this.contentsScale<layer.idealContentsScale)
-type=tr.e.cc.tileTypes.extraLowRes;else if(this.contentsScale>layer.idealContentsScale)
-type=tr.e.cc.tileTypes.extraHighRes;}
-return type;}};ObjectSnapshot.register(TileSnapshot,{typeName:'cc::Tile'});return{TileSnapshot:TileSnapshot};});'use strict';tr.exportTo('tr.ui.b',function(){var ListView=tr.ui.b.define('x-list-view',tr.ui.b.ContainerThatDecoratesItsChildren);ListView.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);this.classList.add('x-list-view');this.onItemClicked_=this.onItemClicked_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.tabIndex=0;this.addEventListener('keydown',this.onKeyDown_);this.selectionChanged_=false;},decorateChild_:function(item){item.classList.add('list-item');item.addEventListener('click',this.onItemClicked_,true);var listView=this;Object.defineProperty(item,'selected',{configurable:true,set:function(value){var oldSelection=listView.selectedElement;if(oldSelection&&oldSelection!=this&&value)
-listView.selectedElement.removeAttribute('selected');if(value)
-this.setAttribute('selected','selected');else
-this.removeAttribute('selected');var newSelection=listView.selectedElement;if(newSelection!=oldSelection)
-tr.b.dispatchSimpleEvent(listView,'selection-changed',false);},get:function(){return this.hasAttribute('selected');}});},undecorateChild_:function(item){this.selectionChanged_|=item.selected;item.classList.remove('list-item');item.removeEventListener('click',this.onItemClicked_);delete item.selected;},beginDecorating_:function(){this.selectionChanged_=false;},doneDecoratingForNow_:function(){if(this.selectionChanged_)
-tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get selectedElement(){var el=this.querySelector('.list-item[selected]');if(!el)
-return undefined;return el;},set selectedElement(el){if(!el){if(this.selectedElement)
-this.selectedElement.selected=false;return;}
-if(el.parentElement!=this)
-throw new Error('Can only select elements that are children of this list view');el.selected=true;},getElementByIndex:function(index){return this.querySelector('.list-item:nth-child('+index+')');},clear:function(){var changed=this.selectedElement!==undefined;tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);if(changed)
-tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onItemClicked_:function(e){var currentSelectedElement=this.selectedElement;if(currentSelectedElement)
-currentSelectedElement.removeAttribute('selected');var element=e.target;while(element.parentElement!=this)
-element=element.parentElement;if(element!==currentSelectedElement)
-element.setAttribute('selected','selected');tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onKeyDown_:function(e){if(this.selectedElement===undefined)
-return;if(e.keyCode==38){var prev=this.selectedElement.previousSibling;if(prev){prev.selected=true;tr.ui.b.scrollIntoViewIfNeeded(prev);e.preventDefault();return true;}}else if(e.keyCode==40){var next=this.selectedElement.nextSibling;if(next){next.selected=true;tr.ui.b.scrollIntoViewIfNeeded(next);e.preventDefault();return true;}}},addItem:function(textContent){var item=document.createElement('div');item.textContent=textContent;this.appendChild(item);return item;}};return{ListView:ListView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function Selection(){this.selectionToSetIfClicked=undefined;};Selection.prototype={get specicifity(){throw new Error('Not implemented');},get associatedLayerId(){throw new Error('Not implemented');},get associatedRenderPassId(){throw new Error('Not implemented');},get highlightsByLayerId(){return{};},createAnalysis:function(){throw new Error('Not implemented');},findEquivalent:function(lthi){throw new Error('Not implemented');}};function RenderPassSelection(renderPass,renderPassId){if(!renderPass||(renderPassId===undefined))
+return;var modeInfo=MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION];var eventNames=modeInfo.eventNames;var mouseEvent=this.createEvent_(eventNames.begin);mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);mouseEvent=this.createEvent_(eventNames.end);this.dispatchEvent(mouseEvent);}});return{MIN_MOUSE_SELECTION_DISTANCE:MIN_MOUSE_SELECTION_DISTANCE,MODIFIER:MODIFIER};});'use strict';(function(){var DETAILS_SPLIT_REGEX=/^(\S*)\s*([\S\s]*)$/;Polymer('tr-ui-e-chrome-cc-display-item-list-item',{created:function(){this.name='';this.rawDetails='';this.richDetails=undefined;this.data_=undefined;},get data(){return this.data_;},set data(data){this.data_=data;if(!data){this.name='DATA MISSING';this.rawDetails='';this.richDetails=undefined;}else if(typeof data==='string'){var match=data.match(DETAILS_SPLIT_REGEX);this.name=match[1];this.rawDetails=match[2];this.richDetails=undefined;}else{this.name=data.name;this.rawDetails='';this.richDetails=data;}},stopPropagation:function(e){e.stopPropagation();}});})();'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function Selection(){this.selectionToSetIfClicked=undefined;};Selection.prototype={get specicifity(){throw new Error('Not implemented');},get associatedLayerId(){throw new Error('Not implemented');},get associatedRenderPassId(){throw new Error('Not implemented');},get highlightsByLayerId(){return{};},createAnalysis:function(){throw new Error('Not implemented');},findEquivalent:function(lthi){throw new Error('Not implemented');}};function RenderPassSelection(renderPass,renderPassId){if(!renderPass||(renderPassId===undefined))
 throw new Error('Render pass (with id) is required');this.renderPass_=renderPass;this.renderPassId_=renderPassId;}
 RenderPassSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return undefined;},get associatedRenderPassId(){return this.renderPassId_;},get renderPass(){return this.renderPass_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='RenderPass '+this.renderPassId_;dataView.object=this.renderPass_.args;return dataView;},get title(){return this.renderPass_.objectInstance.typeName;}};function LayerSelection(layer){if(!layer)
 throw new Error('Layer is required');this.layer_=layer;}
@@ -6604,7 +5988,7 @@
 ANNOTATION_ID.length);else if(info.indexOf(ANNOTATION_CLASS)!=-1)
 elementInfo.class=info.substring(info.indexOf(ANNOTATION_CLASS)+
 ANNOTATION_CLASS.length);annotations.push(info);});});});op.annotations=annotations;op.elementInfo=elementInfo;opsWithoutAnnotations.push(op);}}
-return opsWithoutAnnotations;}};return{PictureOpsListView:PictureOpsListView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var DisplayItemDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-debugger');DisplayItemDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-display-item-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.trackMouse_();this.displayItemInfo_=this.querySelector('display-item-info');this.displayItemInfo_.addEventListener('click',this.onDisplayItemInfoClick_.bind(this),false);this.displayItemListView_=new tr.ui.b.ListView();this.displayItemListView_.addEventListener('selection-changed',this.onDisplayItemListSelection_.bind(this));this.displayItemInfo_.appendChild(this.displayItemListView_);this.displayListFilename_=this.querySelector('.dlfilename');this.displayListExportButton_=this.querySelector('.dlexport');this.displayListExportButton_.addEventListener('click',this.onExportDisplayListClicked_.bind(this));this.skpFilename_=this.querySelector('.skpfilename');this.skpExportButton_=this.querySelector('.skpexport');this.skpExportButton_.addEventListener('click',this.onExportSkPictureClicked_.bind(this));var leftPanel=this.querySelector('left-panel');var middleDragHandle=new tr.ui.b.DragHandle();middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.insertBefore(this.infoBar_,this.rasterCanvas_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;this.pictureOpsListView_=new tr.ui.e.chrome.cc.PictureOpsListView();rightPanel.insertBefore(this.pictureOpsListView_,this.rasterArea_);this.pictureOpsListDragHandle_=new tr.ui.b.DragHandle();this.pictureOpsListDragHandle_.horizontal=false;this.pictureOpsListDragHandle_.target=this.pictureOpsListView_;rightPanel.insertBefore(this.pictureOpsListDragHandle_,this.rasterArea_);},get picture(){return this.picture_;},set displayItemList(displayItemList){this.displayItemList_=displayItemList;this.picture=this.displayItemList_;this.displayItemListView_.clear();this.displayItemList_.items.forEach(function(item){var newListItem=document.createElement('div');newListItem.innerText=item;var text=item.skp64?item.name:item;this.displayItemListView_.addItem(text);}.bind(this));},set picture(picture){this.picture_=picture;var showOpsList=picture&&picture!==this.displayItemList_;this.updateDrawOpsList_(showOpsList);if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+return opsWithoutAnnotations;}};return{PictureOpsListView:PictureOpsListView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var DisplayItemDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-debugger');DisplayItemDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-display-item-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.trackMouse_();this.displayItemInfo_=this.querySelector('display-item-info');this.displayItemInfo_.addEventListener('click',this.onDisplayItemInfoClick_.bind(this),false);this.displayItemListView_=new tr.ui.b.ListView();this.displayItemListView_.addEventListener('selection-changed',this.onDisplayItemListSelection_.bind(this));this.displayItemInfo_.appendChild(this.displayItemListView_);this.displayListFilename_=this.querySelector('.dlfilename');this.displayListExportButton_=this.querySelector('.dlexport');this.displayListExportButton_.addEventListener('click',this.onExportDisplayListClicked_.bind(this));this.skpFilename_=this.querySelector('.skpfilename');this.skpExportButton_=this.querySelector('.skpexport');this.skpExportButton_.addEventListener('click',this.onExportSkPictureClicked_.bind(this));var leftPanel=this.querySelector('left-panel');var middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.insertBefore(this.infoBar_,this.rasterCanvas_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;this.pictureOpsListView_=new tr.ui.e.chrome.cc.PictureOpsListView();rightPanel.insertBefore(this.pictureOpsListView_,this.rasterArea_);this.pictureOpsListDragHandle_=document.createElement('tr-ui-b-drag-handle');this.pictureOpsListDragHandle_.horizontal=false;this.pictureOpsListDragHandle_.target=this.pictureOpsListView_;rightPanel.insertBefore(this.pictureOpsListDragHandle_,this.rasterArea_);},get picture(){return this.picture_;},set displayItemList(displayItemList){this.displayItemList_=displayItemList;this.picture=this.displayItemList_;this.displayItemListView_.clear();this.displayItemList_.items.forEach(function(item){var listItem=document.createElement('tr-ui-e-chrome-cc-display-item-list-item');listItem.data=item;this.displayItemListView_.appendChild(listItem);}.bind(this));},set picture(picture){this.picture_=picture;var showOpsList=picture&&picture!==this.displayItemList_;this.updateDrawOpsList_(showOpsList);if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
 var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=parseInt(style.width);var height=parseInt(style.height);if(this.picture_){width=Math.max(width,this.picture_.layerRect.width);height=Math.max(height,this.picture_.layerRect.height);}
 return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
 return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){this.sizeInfo_.textContent='('+
@@ -6621,7 +6005,7 @@
 this.picture=undefined;},onDisplayItemInfoClick_:function(e){if(e&&e.target==this.displayItemInfo_){this.displayItemListView_.selectedElement=undefined;}},updateDrawOpsList_:function(showOpsList){if(showOpsList){this.pictureOpsListView_.picture=this.picture_;if(this.pictureOpsListView_.numOps>0){this.pictureOpsListView_.classList.add('hasPictureOps');this.pictureOpsListDragHandle_.classList.add('hasPictureOps');}}else{this.pictureOpsListView_.classList.remove('hasPictureOps');this.pictureOpsListDragHandle_.classList.remove('hasPictureOps');}},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;this.rasterArea_.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
 return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};},saveFile_:function(filename,rawData){if(!rawData)
 return;var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
-uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.URL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=filename;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},onExportDisplayListClicked_:function(){var rawData=JSON.stringify(this.displayItemList_.items);this.saveFile_(this.displayListFilename_.value,rawData);},onExportSkPictureClicked_:function(){var rawData=atob(this.picture_.getBase64SkpData());this.saveFile_(this.skpFilename_.value,rawData);}};return{DisplayItemDebugger:DisplayItemDebugger};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var DisplayItemSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-list-view',tr.ui.analysis.ObjectSnapshotView);DisplayItemSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-display-item-list-view');this.displayItemDebugger_=new tr.ui.e.chrome.cc.DisplayItemDebugger();this.appendChild(this.displayItemDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.displayItemDebugger_)
+uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.URL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=filename;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},onExportDisplayListClicked_:function(){var rawData=JSON.stringify(this.displayItemList_.items);this.saveFile_(this.displayListFilename_.value,rawData);},onExportSkPictureClicked_:function(){var rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());this.saveFile_(this.skpFilename_.value,rawData);}};return{DisplayItemDebugger:DisplayItemDebugger};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var DisplayItemSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-list-view',tr.ui.analysis.ObjectSnapshotView);DisplayItemSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-display-item-list-view');this.displayItemDebugger_=new tr.ui.e.chrome.cc.DisplayItemDebugger();this.appendChild(this.displayItemDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.displayItemDebugger_)
 this.displayItemDebugger_.displayItemList=this.objectSnapshot_;}};tr.ui.analysis.ObjectSnapshotView.register(DisplayItemSnapshotView,{typeNames:['cc::DisplayItemList'],showInstances:false});return{DisplayItemSnapshotView:DisplayItemSnapshotView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var bytesToRoundedMegabytes=tr.e.cc.bytesToRoundedMegabytes;var RENDER_PASS_QUADS=Math.max(constants.ACTIVE_TREE,constants.PENDING_TREE)+1;var LayerPicker=tr.ui.b.define('tr-ui-e-chrome-cc-layer-picker');LayerPicker.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.lthi_=undefined;this.controls_=document.createElement('top-controls');this.renderPassQuads_=false;this.itemList_=new tr.ui.b.ListView();this.appendChild(this.controls_);this.appendChild(this.itemList_);this.itemList_.addEventListener('selection-changed',this.onItemSelectionChanged_.bind(this));this.controls_.appendChild(tr.ui.b.createSelector(this,'whichTree','layerPicker.whichTree',constants.ACTIVE_TREE,[{label:'Active tree',value:constants.ACTIVE_TREE},{label:'Pending tree',value:constants.PENDING_TREE},{label:'Render pass quads',value:RENDER_PASS_QUADS}]));this.showPureTransformLayers_=false;var showPureTransformLayers=tr.ui.b.createCheckBox(this,'showPureTransformLayers','layerPicker.showPureTransformLayers',false,'Transform layers');showPureTransformLayers.classList.add('show-transform-layers');showPureTransformLayers.title='When checked, pure transform layers are shown';this.controls_.appendChild(showPureTransformLayers);},get lthiSnapshot(){return this.lthiSnapshot_;},set lthiSnapshot(lthiSnapshot){this.lthiSnapshot_=lthiSnapshot;this.updateContents_();},get whichTree(){return this.renderPassQuads_?constants.ACTIVE_TREE:this.whichTree_;},set whichTree(whichTree){this.whichTree_=whichTree;this.renderPassQuads_=(whichTree==RENDER_PASS_QUADS);this.updateContents_();tr.b.dispatchSimpleEvent(this,'selection-change',false);},get layerTreeImpl(){if(this.lthiSnapshot===undefined)
 return undefined;return this.lthiSnapshot.getTree(this.whichTree);},get isRenderPassQuads(){return this.renderPassQuads_;},get showPureTransformLayers(){return this.showPureTransformLayers_;},set showPureTransformLayers(show){if(this.showPureTransformLayers_===show)
 return;this.showPureTransformLayers_=show;this.updateContents_();},getRenderPassInfos_:function(){if(!this.lthiSnapshot_)
@@ -6697,7 +6081,7 @@
 return;this.deviceRect_=rect;this.camera_.deviceRect=rect;this.chromeQuad_=undefined;},resize:function(){if(!this.offsetParent)
 return true;var width=parseInt(window.getComputedStyle(this.offsetParent).width);var height=parseInt(window.getComputedStyle(this.offsetParent).height);var rect=tr.b.Rect.fromXYWH(0,0,width,height);if(rect.equalTo(this.viewportRect_))
 return false;this.viewportRect_=rect;this.style.width=width+'px';this.style.height=height+'px';this.canvas_.style.width=width+'px';this.canvas_.style.height=height+'px';this.canvas_.width=this.pixelRatio_*width;this.canvas_.height=this.pixelRatio_*height;if(!this.cameraWasReset_){this.camera_.resetCamera();this.cameraWasReset_=true;}
-return true;},readyToDraw:function(){if(!this.chromeImages_.left.src){var leftContent=window.getComputedStyle(this.chromeImages_.left).content;leftContent=leftContent.replace(/url\((.*)\)/,'$1');var midContent=window.getComputedStyle(this.chromeImages_.mid).content;midContent=midContent.replace(/url\((.*)\)/,'$1');var rightContent=window.getComputedStyle(this.chromeImages_.right).content;rightContent=rightContent.replace(/url\((.*)\)/,'$1');this.chromeImages_.left.src=leftContent;this.chromeImages_.mid.src=midContent;this.chromeImages_.right.src=rightContent;}
+return true;},readyToDraw:function(){if(!this.chromeImages_.left.src){var leftContent=window.getComputedStyle(this.chromeImages_.left).content;leftContent=tr.ui.b.extractUrlString(leftContent);var midContent=window.getComputedStyle(this.chromeImages_.mid).content;midContent=tr.ui.b.extractUrlString(midContent);var rightContent=window.getComputedStyle(this.chromeImages_.right).content;rightContent=tr.ui.b.extractUrlString(rightContent);this.chromeImages_.left.src=leftContent;this.chromeImages_.mid.src=midContent;this.chromeImages_.right.src=rightContent;}
 return(this.chromeImages_.left.height>0)&&(this.chromeImages_.mid.height>0)&&(this.chromeImages_.right.height>0);},get chromeQuad(){if(this.chromeQuad_)
 return this.chromeQuad_;var chromeCanvas=document.createElement('canvas');var offsetY=this.chromeImages_.left.height;chromeCanvas.width=this.deviceRect_.width;chromeCanvas.height=this.deviceRect_.height+offsetY;var leftWidth=this.chromeImages_.left.width;var midWidth=this.chromeImages_.mid.width;var rightWidth=this.chromeImages_.right.width;var chromeCtx=chromeCanvas.getContext('2d');chromeCtx.drawImage(this.chromeImages_.left,0,0);chromeCtx.save();chromeCtx.translate(leftWidth,0);var s=(this.deviceRect_.width-leftWidth-rightWidth)/midWidth;chromeCtx.scale(s,1);chromeCtx.drawImage(this.chromeImages_.mid,0,0);chromeCtx.restore();chromeCtx.drawImage(this.chromeImages_.right,leftWidth+s*midWidth,0);var chromeRect=tr.b.Rect.fromXYWH(this.deviceRect_.x,this.deviceRect_.y-offsetY,this.deviceRect_.width,this.deviceRect_.height+offsetY);var chromeQuad=tr.b.Quad.fromRect(chromeRect);chromeQuad.stackingGroupId=this.maxStackingGroupId_+1;chromeQuad.imageData=chromeCtx.getImageData(0,0,chromeCanvas.width,chromeCanvas.height);chromeQuad.shadowOffset=[0,0];chromeQuad.shadowBlur=5;chromeQuad.borderWidth=3;this.chromeQuad_=chromeQuad;return this.chromeQuad_;},scheduleRender:function(){if(this.redrawScheduled_)
 return false;this.redrawScheduled_=true;tr.b.requestAnimationFrame(this.render,this);},onRenderRequired_:function(e){this.scheduleRender();},stackTransformAndProcessQuads_:function(numPasses,handleQuadFunc,includeChromeQuad,opt_arg1,opt_arg2){var mv=this.camera_.modelViewMatrix;var p=this.camera_.projectionMatrix;var viewport=tr.b.Rect.fromXYWH(0,0,this.canvas_.width,this.canvas_.height);var quadStacks=[];for(var i=0;i<this.quads_.length;++i){var quad=this.quads_[i];var stackingId=quad.stackingGroupId||0;while(stackingId>=quadStacks.length)
@@ -6711,7 +6095,7 @@
 this.stackTransformAndProcessQuads_(1,handleQuad,false);var e=new tr.b.Event('selectionchange');e.quads=res;this.dispatchEvent(e);}};return{QuadStackView:QuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var ColorScheme=tr.b.ColorScheme;var THIS_DOC=document.currentScript.ownerDocument;var TILE_HEATMAP_TYPE={};TILE_HEATMAP_TYPE.NONE='none';TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY='scheduledPriority';TILE_HEATMAP_TYPE.USING_GPU_MEMORY='usingGpuMemory';var cc=tr.ui.e.chrome.cc;function createTileRectsSelectorBaseOptions(){return[{label:'None',value:'none'},{label:'Coverage Rects',value:'coverage'}];}
 var bytesToRoundedMegabytes=tr.e.cc.bytesToRoundedMegabytes;var LayerTreeQuadStackView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-quad-stack-view');LayerTreeQuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.isRenderPassQuads_=false;this.pictureAsImageData_={};this.messages_=[];this.controls_=document.createElement('top-controls');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.quadStackView_=new tr.ui.b.QuadStackView();this.quadStackView_.addEventListener('selectionchange',this.onQuadStackViewSelectionChange_.bind(this));this.extraHighlightsByLayerId_=undefined;this.inputEventImageData_=undefined;var m=tr.ui.b.MOUSE_SELECTOR_MODE;var mms=this.quadStackView_.mouseModeSelector;mms.settingsKey='tr.e.cc.layerTreeQuadStackView.mouseModeSelector';mms.setKeyCodeForMode(m.SELECTION,'Z'.charCodeAt(0));mms.setKeyCodeForMode(m.PANSCAN,'X'.charCodeAt(0));mms.setKeyCodeForMode(m.ZOOM,'C'.charCodeAt(0));mms.setKeyCodeForMode(m.ROTATE,'V'.charCodeAt(0));var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template',THIS_DOC);this.appendChild(node);this.appendChild(this.controls_);this.appendChild(this.infoBar_);this.appendChild(this.quadStackView_);this.tileRectsSelector_=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',createTileRectsSelectorBaseOptions());this.controls_.appendChild(this.tileRectsSelector_);var tileHeatmapText=tr.ui.b.createSpan({textContent:'Tile heatmap:'});this.controls_.appendChild(tileHeatmapText);var tileHeatmapSelector=tr.ui.b.createSelector(this,'tileHeatmapType','layerView.tileHeatmapType',TILE_HEATMAP_TYPE.NONE,[{label:'None',value:TILE_HEATMAP_TYPE.NONE},{label:'Scheduled Priority',value:TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY},{label:'Is using GPU memory',value:TILE_HEATMAP_TYPE.USING_GPU_MEMORY}]);this.controls_.appendChild(tileHeatmapSelector);var showOtherLayersCheckbox=tr.ui.b.createCheckBox(this,'showOtherLayers','layerView.showOtherLayers',true,'Other layers/passes');showOtherLayersCheckbox.title='When checked, show all layers, selected or not.';this.controls_.appendChild(showOtherLayersCheckbox);var showInvalidationsCheckbox=tr.ui.b.createCheckBox(this,'showInvalidations','layerView.showInvalidations',true,'Invalidations');showInvalidationsCheckbox.title='When checked, compositing invalidations are highlighted in red';this.controls_.appendChild(showInvalidationsCheckbox);var showUnrecordedRegionCheckbox=tr.ui.b.createCheckBox(this,'showUnrecordedRegion','layerView.showUnrecordedRegion',true,'Unrecorded area');showUnrecordedRegionCheckbox.title='When checked, unrecorded areas are highlighted in yellow';this.controls_.appendChild(showUnrecordedRegionCheckbox);var showBottlenecksCheckbox=tr.ui.b.createCheckBox(this,'showBottlenecks','layerView.showBottlenecks',true,'Bottlenecks');showBottlenecksCheckbox.title='When checked, scroll bottlenecks are highlighted';this.controls_.appendChild(showBottlenecksCheckbox);var showLayoutRectsCheckbox=tr.ui.b.createCheckBox(this,'showLayoutRects','layerView.showLayoutRects',false,'Layout rects');showLayoutRectsCheckbox.title='When checked, shows rects for regions where layout happened';this.controls_.appendChild(showLayoutRectsCheckbox);var showContentsCheckbox=tr.ui.b.createCheckBox(this,'showContents','layerView.showContents',true,'Contents');showContentsCheckbox.title='When checked, show the rendered contents inside the layer outlines';this.controls_.appendChild(showContentsCheckbox);var showAnimationBoundsCheckbox=tr.ui.b.createCheckBox(this,'showAnimationBounds','layerView.showAnimationBounds',false,'Animation Bounds');showAnimationBoundsCheckbox.title='When checked, show a border around'+' a layer showing the extent of its animation.';this.controls_.appendChild(showAnimationBoundsCheckbox);var showInputEventsCheckbox=tr.ui.b.createCheckBox(this,'showInputEvents','layerView.showInputEvents',true,'Input events');showInputEventsCheckbox.title='When checked, input events are '+'displayed as circles.';this.controls_.appendChild(showInputEventsCheckbox);this.whatRasterizedLink_=document.createElement('a');this.whatRasterizedLink_.classList.add('what-rasterized');this.whatRasterizedLink_.textContent='What rasterized?';this.whatRasterizedLink_.addEventListener('click',this.onWhatRasterizedLinkClicked_.bind(this));this.appendChild(this.whatRasterizedLink_);},get layerTreeImpl(){return this.layerTreeImpl_;},set isRenderPassQuads(newValue){this.isRenderPassQuads_=newValue;},set layerTreeImpl(layerTreeImpl){if(this.layerTreeImpl_===layerTreeImpl)
 return;this.layerTreeImpl_=layerTreeImpl;this.selection=undefined;},get extraHighlightsByLayerId(){return this.extraHighlightsByLayerId_;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.extraHighlightsByLayerId_=extraHighlightsByLayerId;this.scheduleUpdateContents_();},get showOtherLayers(){return this.showOtherLayers_;},set showOtherLayers(show){this.showOtherLayers_=show;this.updateContents_();},get showAnimationBounds(){return this.showAnimationBounds_;},set showAnimationBounds(show){this.showAnimationBounds_=show;this.updateContents_();},get showInputEvents(){return this.showInputEvents_;},set showInputEvents(show){this.showInputEvents_=show;this.updateContents_();},get showContents(){return this.showContents_;},set showContents(show){this.showContents_=show;this.updateContents_();},get showInvalidations(){return this.showInvalidations_;},set showInvalidations(show){this.showInvalidations_=show;this.updateContents_();},get showUnrecordedRegion(){return this.showUnrecordedRegion_;},set showUnrecordedRegion(show){this.showUnrecordedRegion_=show;this.updateContents_();},get showBottlenecks(){return this.showBottlenecks_;},set showBottlenecks(show){this.showBottlenecks_=show;this.updateContents_();},get showLayoutRects(){return this.showLayoutRects_;},set showLayoutRects(show){this.showLayoutRects_=show;this.updateContents_();},get howToShowTiles(){return this.howToShowTiles_;},set howToShowTiles(val){console.assert((val==='none')||(val==='coverage')||!isNaN(parseFloat(val)));this.howToShowTiles_=val;this.updateContents_();},get tileHeatmapType(){return this.tileHeatmapType_;},set tileHeatmapType(val){this.tileHeatmapType_=val;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){if(this.selection===selection)
-return;this.selection_=selection;tr.b.dispatchSimpleEvent(this,'selection-change');this.updateContents_();},regenerateContent:function(){this.updateTilesSelector_();this.updateContents_();},loadDataForImageElement_:function(image,callback){var imageContent=window.getComputedStyle(image).content;image.src=imageContent.replace(/url\((.*)\)/,'$1');image.onload=function(){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=image.width;canvas.height=image.height;ctx.drawImage(image,0,0);var imageData=ctx.getImageData(0,0,canvas.width,canvas.height);callback(imageData);}},onQuadStackViewSelectionChange_:function(e){var selectableQuads=e.quads.filter(function(q){return q.selectionToSetIfClicked!==undefined;});if(selectableQuads.length==0){this.selection=undefined;return;}
+return;this.selection_=selection;tr.b.dispatchSimpleEvent(this,'selection-change');this.updateContents_();},regenerateContent:function(){this.updateTilesSelector_();this.updateContents_();},loadDataForImageElement_:function(image,callback){var imageContent=window.getComputedStyle(image).content;image.src=tr.ui.b.extractUrlString(imageContent);image.onload=function(){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=image.width;canvas.height=image.height;ctx.drawImage(image,0,0);var imageData=ctx.getImageData(0,0,canvas.width,canvas.height);callback(imageData);}},onQuadStackViewSelectionChange_:function(e){var selectableQuads=e.quads.filter(function(q){return q.selectionToSetIfClicked!==undefined;});if(selectableQuads.length==0){this.selection=undefined;return;}
 selectableQuads.sort(function(x,y){var z=x.stackingGroupId-y.stackingGroupId;if(z!=0)
 return z;return x.selectionToSetIfClicked.specicifity-
 y.selectionToSetIfClicked.specicifity;});var quadToSelect=selectableQuads[selectableQuads.length-1];this.selection=quadToSelect.selectionToSetIfClicked;},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
@@ -6802,12 +6186,12 @@
 return quads;},updateInfoBar_:function(infoBarMessages){if(infoBarMessages.length){this.infoBar_.removeAllButtons();this.infoBar_.message='Some problems were encountered...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent='';infoBarMessages.forEach(function(message){var title=document.createElement('h3');title.textContent=message.header;var details=document.createElement('div');details.textContent=message.details;overlay.appendChild(title);overlay.appendChild(details);});overlay.visible=true;e.stopPropagation();return false;});this.infoBar_.visible=true;}else{this.infoBar_.removeAllButtons();this.infoBar_.message='';this.infoBar_.visible=false;}},getWhatRasterized_:function(){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var renderProcess=lthi.objectInstance.parent;var tasks=[];renderProcess.iterateAllEvents(function(event){if(!(event instanceof tr.model.Slice))
 return;var tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined)
 return false;if(tile.containingSnapshot==lthi)
-tasks.push(event);},this);return tasks;},updateWhatRasterizedLinkState_:function(){var tasks=this.getWhatRasterized_();if(tasks.length){this.whatRasterizedLink_.textContent=tasks.length+' raster tasks';this.whatRasterizedLink_.style.display='';}else{this.whatRasterizedLink_.textContent='';this.whatRasterizedLink_.style.display='none';}},onWhatRasterizedLinkClicked_:function(){var tasks=this.getWhatRasterized_();var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(tasks);this.dispatchEvent(event);}};return{LayerTreeQuadStackView:LayerTreeQuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var LayerView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-view');LayerView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.layerTreeQuadStackView_=new tr.ui.e.chrome.cc.LayerTreeQuadStackView();this.dragBar_=new tr.ui.b.DragHandle();this.analysisEl_=document.createElement('tr-ui-e-chrome-cc-layer-view-analysis');this.analysisEl_.addEventListener('requestSelectionChange',this.onRequestSelectionChangeFromAnalysisEl_.bind(this));this.dragBar_.target=this.analysisEl_;this.appendChild(this.layerTreeQuadStackView_);this.appendChild(this.dragBar_);this.appendChild(this.analysisEl_);this.layerTreeQuadStackView_.addEventListener('selection-change',function(){this.layerTreeQuadStackViewSelectionChanged_();}.bind(this));this.layerTreeQuadStackViewSelectionChanged_();},get layerTreeImpl(){return this.layerTreeQuadStackView_.layerTreeImpl;},set layerTreeImpl(newValue){return this.layerTreeQuadStackView_.layerTreeImpl=newValue;},set isRenderPassQuads(newValue){return this.layerTreeQuadStackView_.isRenderPassQuads=newValue;},get selection(){return this.layerTreeQuadStackView_.selection;},set selection(newValue){this.layerTreeQuadStackView_.selection=newValue;},regenerateContent:function(){this.layerTreeQuadStackView_.regenerateContent();},layerTreeQuadStackViewSelectionChanged_:function(){var selection=this.layerTreeQuadStackView_.selection;if(selection){this.dragBar_.style.display='';this.analysisEl_.style.display='';this.analysisEl_.textContent='';var layer=selection.layer;if(layer&&layer.args&&layer.args.pictures){this.analysisEl_.appendChild(this.createPictureBtn_(layer.args.pictures));}
+tasks.push(event);},this);return tasks;},updateWhatRasterizedLinkState_:function(){var tasks=this.getWhatRasterized_();if(tasks.length){this.whatRasterizedLink_.textContent=tasks.length+' raster tasks';this.whatRasterizedLink_.style.display='';}else{this.whatRasterizedLink_.textContent='';this.whatRasterizedLink_.style.display='none';}},onWhatRasterizedLinkClicked_:function(){var tasks=this.getWhatRasterized_();var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(tasks);this.dispatchEvent(event);}};return{LayerTreeQuadStackView:LayerTreeQuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var LayerView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-view');LayerView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.layerTreeQuadStackView_=new tr.ui.e.chrome.cc.LayerTreeQuadStackView();this.dragBar_=document.createElement('tr-ui-b-drag-handle');this.analysisEl_=document.createElement('tr-ui-e-chrome-cc-layer-view-analysis');this.analysisEl_.addEventListener('requestSelectionChange',this.onRequestSelectionChangeFromAnalysisEl_.bind(this));this.dragBar_.target=this.analysisEl_;this.appendChild(this.layerTreeQuadStackView_);this.appendChild(this.dragBar_);this.appendChild(this.analysisEl_);this.layerTreeQuadStackView_.addEventListener('selection-change',function(){this.layerTreeQuadStackViewSelectionChanged_();}.bind(this));this.layerTreeQuadStackViewSelectionChanged_();},get layerTreeImpl(){return this.layerTreeQuadStackView_.layerTreeImpl;},set layerTreeImpl(newValue){return this.layerTreeQuadStackView_.layerTreeImpl=newValue;},set isRenderPassQuads(newValue){return this.layerTreeQuadStackView_.isRenderPassQuads=newValue;},get selection(){return this.layerTreeQuadStackView_.selection;},set selection(newValue){this.layerTreeQuadStackView_.selection=newValue;},regenerateContent:function(){this.layerTreeQuadStackView_.regenerateContent();},layerTreeQuadStackViewSelectionChanged_:function(){var selection=this.layerTreeQuadStackView_.selection;if(selection){this.dragBar_.style.display='';this.analysisEl_.style.display='';this.analysisEl_.textContent='';var layer=selection.layer;if(layer&&layer.args&&layer.args.pictures){this.analysisEl_.appendChild(this.createPictureBtn_(layer.args.pictures));}
 var analysis=selection.createAnalysis();this.analysisEl_.appendChild(analysis);}else{this.dragBar_.style.display='none';this.analysisEl_.style.display='none';var analysis=this.analysisEl_.firstChild;if(analysis)
 this.analysisEl_.removeChild(analysis);this.layerTreeQuadStackView_.style.height=window.getComputedStyle(this).height;}
 tr.b.dispatchSimpleEvent(this,'selection-change');},createPictureBtn_:function(pictures){if(!(pictures instanceof Array))
 pictures=[pictures];var link=document.createElement('tr-ui-a-analysis-link');link.selection=function(){var layeredPicture=new tr.e.cc.LayeredPicture(pictures);var snapshot=new tr.e.cc.PictureSnapshot(layeredPicture);snapshot.picture=layeredPicture;var selection=new tr.model.EventSet();selection.push(snapshot);return selection;};link.textContent='View in Picture Debugger';return link;},onRequestSelectionChangeFromAnalysisEl_:function(e){if(!(e.selection instanceof tr.ui.e.chrome.cc.Selection))
-return;e.stopPropagation();this.selection=e.selection;},get extraHighlightsByLayerId(){return this.layerTreeQuadStackView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerTreeQuadStackView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};return{LayerView:LayerView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var LayerTreeHostImplSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-host-impl-snapshot-view',tr.ui.analysis.ObjectSnapshotView);LayerTreeHostImplSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-lthi-s-view');this.selection_=undefined;this.layerPicker_=new tr.ui.e.chrome.cc.LayerPicker();this.layerPicker_.addEventListener('selection-change',this.onLayerPickerSelectionChanged_.bind(this));this.layerView_=new tr.ui.e.chrome.cc.LayerView();this.layerView_.addEventListener('selection-change',this.onLayerViewSelectionChanged_.bind(this));this.dragHandle_=new tr.ui.b.DragHandle();this.dragHandle_.horizontal=false;this.dragHandle_.target=this.layerView_;this.appendChild(this.layerPicker_);this.appendChild(this.dragHandle_);this.appendChild(this.layerView_);this.onLayerViewSelectionChanged_();this.onLayerPickerSelectionChanged_();},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(objectSnapshot){this.objectSnapshot_=objectSnapshot;var lthi=this.objectSnapshot;var layerTreeImpl;if(lthi)
+return;e.stopPropagation();this.selection=e.selection;},get extraHighlightsByLayerId(){return this.layerTreeQuadStackView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerTreeQuadStackView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};return{LayerView:LayerView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var LayerTreeHostImplSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-host-impl-snapshot-view',tr.ui.analysis.ObjectSnapshotView);LayerTreeHostImplSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-lthi-s-view');this.selection_=undefined;this.layerPicker_=new tr.ui.e.chrome.cc.LayerPicker();this.layerPicker_.addEventListener('selection-change',this.onLayerPickerSelectionChanged_.bind(this));this.layerView_=new tr.ui.e.chrome.cc.LayerView();this.layerView_.addEventListener('selection-change',this.onLayerViewSelectionChanged_.bind(this));this.dragHandle_=document.createElement('tr-ui-b-drag-handle');this.dragHandle_.horizontal=false;this.dragHandle_.target=this.layerView_;this.appendChild(this.layerPicker_);this.appendChild(this.dragHandle_);this.appendChild(this.layerView_);this.onLayerViewSelectionChanged_();this.onLayerPickerSelectionChanged_();},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(objectSnapshot){this.objectSnapshot_=objectSnapshot;var lthi=this.objectSnapshot;var layerTreeImpl;if(lthi)
 layerTreeImpl=lthi.getTree(this.layerPicker_.whichTree);this.layerPicker_.lthiSnapshot=lthi;this.layerView_.layerTreeImpl=layerTreeImpl;this.layerView_.regenerateContent();if(!this.selection_)
 return;this.selection=this.selection_.findEquivalent(lthi);},get selection(){return this.selection_;},set selection(selection){if(this.selection_==selection)
 return;this.selection_=selection;this.layerPicker_.selection=selection;this.layerView_.selection=selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerPickerSelectionChanged_:function(){this.selection_=this.layerPicker_.selection;this.layerView_.selection=this.selection;this.layerView_.layerTreeImpl=this.layerPicker_.layerTreeImpl;this.layerView_.isRenderPassQuads=this.layerPicker_.isRenderPassQuads;this.layerView_.regenerateContent();tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerViewSelectionChanged_:function(){this.selection_=this.layerView_.selection;this.layerPicker_.selection=this.selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},get extraHighlightsByLayerId(){return this.layerView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};tr.ui.analysis.ObjectSnapshotView.register(LayerTreeHostImplSnapshotView,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshotView:LayerTreeHostImplSnapshotView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=40;var AXIS_PADDING_LEFT=60;var AXIS_PADDING_RIGHT=35;var AXIS_PADDING_TOP=25;var AXIS_PADDING_BOTTOM=45;var AXIS_LABEL_PADDING=5;var AXIS_TICK_SIZE=10;var LABEL_PADDING=5;var LABEL_INTERLEAVE_OFFSET=15;var BAR_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartSummaryView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-summary-view');PictureOpsChartSummaryView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.picture_=undefined;this.pictureDataProcessed_=false;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');this.appendChild(this.chart_);this.opsTimingData_=[];this.chartWidth_=0;this.chartHeight_=0;this.requiresRedraw_=true;this.currentBarMouseOverTarget_=null;this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));},get requiresRedraw(){return this.requiresRedraw_;},set requiresRedraw(requiresRedraw){this.requiresRedraw_=requiresRedraw;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureDataProcessed_=false;if(this.classList.contains('hidden'))
@@ -6856,7 +6240,7 @@
 maxValue=this.ninetyFifthPercentileCost_;else
 maxValue=this.maxCost_;for(var b=0;b<this.pictureOps_.length;b++){op=this.pictureOps_[b];opHeight=Math.round((op.cmd_time/maxValue)*maxHeight);opHeight=Math.max(opHeight,1);opHover=(b===this.currentBarMouseOverTarget_);opColor=this.getOpColor_(op.cmd_string,opHover);if(b===this.selectedOpIndex)
 this.chartCtx_.fillStyle='#FFFF00';else
-this.chartCtx_.fillStyle=opColor;this.chartCtx_.fillRect(CHART_PADDING_LEFT+b*opWidth,bottom-opHeight,BAR_WIDTH,opHeight);}},getOpColor_:function(opName,hover){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;var saturation=30;var lightness=hover?'75%':'50%';return'hsl('+hue+', '+saturation+'%, '+lightness+'%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);}};return{PictureOpsChartView:PictureOpsChartView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var PictureDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-picture-debugger');PictureDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-picture-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.showOverdraw_=false;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.filename_=this.querySelector('.filename');this.drawOpsChartSummaryView_=new tr.ui.e.chrome.cc.PictureOpsChartSummaryView();this.drawOpsChartView_=new tr.ui.e.chrome.cc.PictureOpsChartView();this.drawOpsChartView_.addEventListener('selection-changed',this.onChartBarClicked_.bind(this));this.exportButton_=this.querySelector('.export');this.exportButton_.addEventListener('click',this.onSaveAsSkPictureClicked_.bind(this));this.trackMouse_();var overdrawCheckbox=tr.ui.b.createCheckBox(this,'showOverdraw','pictureView.showOverdraw',false,'Show overdraw');var chartCheckbox=tr.ui.b.createCheckBox(this,'showSummaryChart','pictureView.showSummaryChart',false,'Show timing summary');var pictureInfo=this.querySelector('picture-info');pictureInfo.appendChild(overdrawCheckbox);pictureInfo.appendChild(chartCheckbox);this.drawOpsView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.drawOpsView_.addEventListener('selection-changed',this.onChangeDrawOps_.bind(this));var leftPanel=this.querySelector('left-panel');leftPanel.appendChild(this.drawOpsChartSummaryView_);leftPanel.appendChild(this.drawOpsView_);var middleDragHandle=new tr.ui.b.DragHandle();middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');rightPanel.replaceChild(this.drawOpsChartView_,rightPanel.querySelector('tr-ui-e-chrome-cc-picture-ops-chart-view'));this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.appendChild(this.infoBar_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;var hkc=document.createElement('tv-ui-b-hotkey-controller');hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'h'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(-1);e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'l'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(1);e.stopPropagation();}}));this.appendChild(hkc);this.mutationObserver_=new MutationObserver(this.onMutation_.bind(this));this.mutationObserver_.observe(leftPanel,{attributes:true});},onMutation_:function(mutations){for(var m=0;m<mutations.length;m++){if(mutations[m].attributeName==='style'){this.drawOpsChartSummaryView_.requiresRedraw=true;this.drawOpsChartSummaryView_.updateChartContents();this.drawOpsChartView_.dimensionsHaveChanged=true;this.drawOpsChartView_.updateChartContents();break;}}},onSaveAsSkPictureClicked_:function(){var rawData=atob(this.picture_.getBase64SkpData());var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
+this.chartCtx_.fillStyle=opColor;this.chartCtx_.fillRect(CHART_PADDING_LEFT+b*opWidth,bottom-opHeight,BAR_WIDTH,opHeight);}},getOpColor_:function(opName,hover){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;var saturation=30;var lightness=hover?'75%':'50%';return'hsl('+hue+', '+saturation+'%, '+lightness+'%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);}};return{PictureOpsChartView:PictureOpsChartView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var PictureDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-picture-debugger');PictureDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-picture-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.showOverdraw_=false;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.filename_=this.querySelector('.filename');this.drawOpsChartSummaryView_=new tr.ui.e.chrome.cc.PictureOpsChartSummaryView();this.drawOpsChartView_=new tr.ui.e.chrome.cc.PictureOpsChartView();this.drawOpsChartView_.addEventListener('selection-changed',this.onChartBarClicked_.bind(this));this.exportButton_=this.querySelector('.export');this.exportButton_.addEventListener('click',this.onSaveAsSkPictureClicked_.bind(this));this.trackMouse_();var overdrawCheckbox=tr.ui.b.createCheckBox(this,'showOverdraw','pictureView.showOverdraw',false,'Show overdraw');var chartCheckbox=tr.ui.b.createCheckBox(this,'showSummaryChart','pictureView.showSummaryChart',false,'Show timing summary');var pictureInfo=this.querySelector('picture-info');pictureInfo.appendChild(overdrawCheckbox);pictureInfo.appendChild(chartCheckbox);this.drawOpsView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.drawOpsView_.addEventListener('selection-changed',this.onChangeDrawOps_.bind(this));var leftPanel=this.querySelector('left-panel');leftPanel.appendChild(this.drawOpsChartSummaryView_);leftPanel.appendChild(this.drawOpsView_);var middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');rightPanel.replaceChild(this.drawOpsChartView_,rightPanel.querySelector('tr-ui-e-chrome-cc-picture-ops-chart-view'));this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.appendChild(this.infoBar_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;var hkc=document.createElement('tv-ui-b-hotkey-controller');hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'h'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(-1);e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'l'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(1);e.stopPropagation();}}));this.appendChild(hkc);this.mutationObserver_=new MutationObserver(this.onMutation_.bind(this));this.mutationObserver_.observe(leftPanel,{attributes:true});},onMutation_:function(mutations){for(var m=0;m<mutations.length;m++){if(mutations[m].attributeName==='style'){this.drawOpsChartSummaryView_.requiresRedraw=true;this.drawOpsChartSummaryView_.updateChartContents();this.drawOpsChartView_.dimensionsHaveChanged=true;this.drawOpsChartView_.updateChartContents();break;}}},onSaveAsSkPictureClicked_:function(){var rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
 uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.webkitURL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=this.filename_.value;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},get picture(){return this.picture_;},set picture(picture){this.drawOpsView_.picture=picture;this.drawOpsChartView_.picture=picture;this.drawOpsChartSummaryView_.picture=picture;this.picture_=picture;this.exportButton_.disabled=!this.picture_.canSave;if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
 var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=Math.max(parseInt(style.width),this.picture_.layerRect.width);var height=Math.max(parseInt(style.height),this.picture_.layerRect.height);return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
 return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){this.sizeInfo_.textContent='('+
@@ -6883,8 +6267,34 @@
 return true;return false;}
 function isSliceDoingAnalysis(slice){if(knownAnalysisTaskNames.indexOf(slice.title)!==-1)
 return true;return false;}
-return{getTileFromRasterTaskSlice:getTileFromRasterTaskSlice,isSliceDoingRasterization:isSliceDoingRasterization,isSliceDoingAnalysis:isSliceDoingAnalysis};});'use strict';Polymer('tr-ui-e-chrome-cc-raster-task-view',{created:function(){this.selection_=undefined;},set selection(selection){this.selection_=selection;this.updateContents_();},updateColumns_:function(hadCpuDurations){var timeSpanConfig={ownerDocument:this.ownerDocument};var columns=[{title:'Layer',value:function(row){if(row.isTotals)
-return'Totals';if(row.layer){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.ui.e.chrome.cc.LayerSelection(costs.layer);},'Layer '+row.layerId);return linkEl;}else{return'Layer '+row.layerId;}},width:'250px'},{title:'Num Tiles',value:function(row){return row.numTiles;},cmp:function(a,b){return a.numTiles-b.numTiles;}},{title:'Num Analysis Tasks',value:function(row){return row.numAnalysisTasks;},cmp:function(a,b){return a.numAnalysisTasks-b.numAnalysisTasks;}},{title:'Num Raster Tasks',value:function(row){return row.numRasterTasks;},cmp:function(a,b){return a.numRasterTasks-b.numRasterTasks;}},{title:'Wall Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,timeSpanConfig);},cmp:function(a,b){return a.duration-b.duration;}}];if(hadCpuDurations){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,timeSpanConfig);},cmp:function(a,b){return a.cpuDuration-b.cpuDuration;}});}
+return{getTileFromRasterTaskSlice:getTileFromRasterTaskSlice,isSliceDoingRasterization:isSliceDoingRasterization,isSliceDoingAnalysis:isSliceDoingAnalysis};});'use strict';Polymer('tr-ui-a-sub-view',{set tabLabel(label){return this.setAttribute('tab-label',label);},get tabLabel(){return this.getAttribute('tab-label');},get requiresTallView(){return false;},get relatedEventsToHighlight(){return undefined;},set selection(selection){throw new Error('Not implemented!');},get selection(){throw new Error('Not implemented!');}});'use strict';Polymer('tr-ui-a-stack-frame',{ready:function(){this.stackFrame_=undefined;this.$.table.tableColumns=[];this.$.table.showHeader=true;},get stackFrame(){return this.stackFrame_;},set stackFrame(stackFrame){var table=this.$.table;this.stackFrame_=stackFrame;if(stackFrame===undefined){table.tableColumns=[];table.tableRows=[];table.rebuild();return;}
+var hasName=false;var hasTitle=false;table.tableRows=stackFrame.stackTrace;table.tableRows.forEach(function(row){hasName|=row.name!==undefined;hasTitle|=row.title!==undefined;});var cols=[];if(hasName){cols.push({title:'Name',value:function(row){return row.name;}});}
+if(hasTitle){cols.push({title:'Title',value:function(row){return row.title;}});}
+table.tableColumns=cols;table.rebuild();},tableForTesting:function(){return this.$.table;}});'use strict';Polymer('tr-ui-a-single-event-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single slices');this.setSelectionWithoutErrorChecks(selection);},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},getEventRows_:function(event){var rows=[];if(event.error)
+rows.push({name:'Error',value:event.error});if(event.title)
+rows.push({name:'Title',value:event.title});if(event.category)
+rows.push({name:'Category',value:event.category});if(event.model!==undefined){var ufc=event.model.getUserFriendlyCategoryFromEvent(event);if(ufc!==undefined)
+rows.push({name:'User Friendly Category',value:ufc});}
+if(event.name)
+rows.push({name:'Name',value:event.name});rows.push({name:'Start',value:tr.v.ui.createScalarSpan(event.start,{unit:tr.v.Unit.byName.timeStampInMs})});if(event.duration){rows.push({name:'Wall Duration',value:tr.v.ui.createScalarSpan(event.duration,{unit:tr.v.Unit.byName.timeDurationInMs})});}
+if(event.cpuDuration){rows.push({name:'CPU Duration',value:tr.v.ui.createScalarSpan(event.cpuDuration,{unit:tr.v.Unit.byName.timeDurationInMs})});}
+if(event.subSlices!==undefined&&event.subSlices.length!==0){if(event.selfTime){rows.push({name:'Self Time',value:tr.v.ui.createScalarSpan(event.selfTime,{unit:tr.v.Unit.byName.timeDurationInMs})});}
+if(event.cpuSelfTime){var cpuSelfTimeEl=tr.v.ui.createScalarSpan(event.cpuSelfTime,{unit:tr.v.Unit.byName.timeDurationInMs});if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
+rows.push({name:'CPU Self Time',value:cpuSelfTimeEl});}}
+if(event.durationInUserTime){rows.push({name:'Duration (U)',value:tr.v.ui.createScalarSpan(event.durationInUserTime,{unit:tr.v.Unit.byName.timeDurationInMs})});}
+function createStackFrameEl(sf){var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sf;return sfEl;}
+if(event.startStackFrame&&event.endStackFrame){if(event.startStackFrame===event.endStackFrame){rows.push({name:'Start+End Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else{rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}}else if(event.startStackFrame){rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else if(event.endStackFrame){rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}
+if(event.info){var descriptionEl=tr.ui.b.createDiv({textContent:event.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(event.info.docLinks){event.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}}
+if(event.associatedAlerts.length){var alertSubRows=[];event.associatedAlerts.forEach(function(alert){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(alert);},alert.info.description);alertSubRows.push({name:alert.title,value:linkEl});});rows.push({name:'Alerts',value:'',isExpanded:true,subRows:alertSubRows});}
+return rows;},addArgsToRows_:function(rows,args){var n=0;for(var argName in args){n+=1;}
+if(n>0){var subRows=[];for(var argName in args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=args[argName];subRows.push({name:argName,value:argView});}
+rows.push({name:'Args',value:'',isExpanded:true,subRows:subRows});}
+return rows;},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+var event=this.currentSelection_[0];var rows=this.getEventRows_(event);if(event.argsStripped)
+rows.push({name:'Args',value:'Stripped'});else
+this.addArgsToRows_(rows,event.args);var event=new tr.b.Event('customize-rows');event.rows=rows;this.dispatchEvent(event);this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer('tr-ui-e-chrome-cc-raster-task-view',{created:function(){this.selection_=undefined;},set selection(selection){this.selection_=selection;this.updateContents_();},updateColumns_:function(hadCpuDurations){var timeSpanConfig={unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument};var columns=[{title:'Layer',value:function(row){if(row.isTotals)
+return'Totals';if(row.layer){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.ui.e.chrome.cc.LayerSelection(costs.layer);},'Layer '+row.layerId);return linkEl;}else{return'Layer '+row.layerId;}},width:'250px'},{title:'Num Tiles',value:function(row){return row.numTiles;},cmp:function(a,b){return a.numTiles-b.numTiles;}},{title:'Num Analysis Tasks',value:function(row){return row.numAnalysisTasks;},cmp:function(a,b){return a.numAnalysisTasks-b.numAnalysisTasks;}},{title:'Num Raster Tasks',value:function(row){return row.numRasterTasks;},cmp:function(a,b){return a.numRasterTasks-b.numRasterTasks;}},{title:'Wall Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.duration,timeSpanConfig);},cmp:function(a,b){return a.duration-b.duration;}}];if(hadCpuDurations){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,timeSpanConfig);},cmp:function(a,b){return a.cpuDuration-b.cpuDuration;}});}
 var colWidthPercentage;if(columns.length==1)
 colWidthPercentage='100%';else
 colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
@@ -6916,19 +6326,148 @@
 return'Device.'+this.args.channel;else
 return'Service.'+this.args.channel;}
 return this.title;}};AsyncSlice.register(GpuAsyncSlice,{categoryParts:['disabled-by-default-gpu.device','disabled-by-default-gpu.service']});return{GpuAsyncSlice:GpuAsyncSlice};});'use strict';tr.exportTo('tr.ui.e.chrome.gpu',function(){var StateSnapshotView=tr.ui.b.define('tr-ui-e-chrome-gpu-state-snapshot-view',tr.ui.analysis.ObjectSnapshotView);StateSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-gpu-state-snapshot-view');this.screenshotImage_=document.createElement('img');this.appendChild(this.screenshotImage_);},updateContents:function(){if(this.objectSnapshot_&&this.objectSnapshot_.screenshot){this.screenshotImage_.src='data:image/png;base64,'+
-this.objectSnapshot_.screenshot;}}};tr.ui.analysis.ObjectSnapshotView.register(StateSnapshotView,{typeName:'gpu::State'});return{StateSnapshotView:StateSnapshotView};});'use strict';tr.exportTo('tr.e.system_stats',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function SystemStatsSnapshot(objectInstance,ts,args){ObjectSnapshot.apply(this,arguments);this.objectInstance=objectInstance;this.ts=ts;this.args=args;this.stats=args;}
+this.objectSnapshot_.screenshot;}}};tr.ui.analysis.ObjectSnapshotView.register(StateSnapshotView,{typeName:'gpu::State'});return{StateSnapshotView:StateSnapshotView};});!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function T(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function z(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o,a=0,c=0,s=0;if(u=/([a-z]+)\((.*)\)/i.exec(n))switch(i=u[2].split(","),u[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(o=Va.get(n))?t(o.r,o.g,o.b):(null!=n&&"#"===n.charAt(0)&&(r=parseInt(n.substring(1),16),isNaN(r)||(4===n.length?(a=(3840&r)>>4,a=a>>4|a,c=240&r,c=c>>4|c,s=15&r,s=s<<4|s):7===n.length&&(a=(16711680&r)>>16,c=(65280&r)>>8,s=255&r))),t(a,c,s))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Xo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function zt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=zt;var r=new zt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=zt;var r=new zt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==zt,o=new(i?zt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=zt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=zt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);hc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Sa,k=p*x;if(hc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*ka:_,S^h>=e^m>=e){var E=fe(se(f),se(n));pe(E);var A=fe(u,E);pe(A);var C=(S^_>=0?-1:1)*X(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ze(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),Tc>t&&(Tc=t),t>zc&&(zc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||oa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function Tr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function zr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),zr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(zu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function zu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function Ti(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():zi(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=zi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=zi(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return zi(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function To(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function zo(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=zi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=zi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.3"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=Sizzle,va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={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/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=T(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=T(o);for(;f>r;++r)p[r]=T(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=z.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,Ta=Math.SQRT2,qa=2,za=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(Ta*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(Ta*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+za*f)/(2*i*qa*h),p=(c*c-i*i-za*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ta;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,T,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({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,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});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv("	","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;zt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",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"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,Te,ze,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,Tc,qc,zc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=zc=-(Lc=Tc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,Tc],[qc,zc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},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()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ti,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ti(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ti:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(To(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=zo,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),T=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",y):T.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(Math.ceil(n/e)*e,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var svgNS='http://www.w3.org/2000/svg';var ColorScheme=tr.b.ColorScheme;function getColorOfKey(key,selected){var id=ColorScheme.getColorIdForGeneralPurposeString(key);if(selected)
+id+=ColorScheme.properties.brightenedOffsets[0];return ColorScheme.colorsAsStrings[id];}
+var ChartBase=tr.ui.b.define('svg',undefined,svgNS);ChartBase.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.classList.add('chart-base');this.chartTitle_=undefined;this.seriesKeys_=undefined;this.width_=400;this.height_=300;var template=THIS_DOC.querySelector('#chart-base-template');var svgEl=template.content.querySelector('svg');for(var i=0;i<svgEl.children.length;i++)
+this.appendChild(svgEl.children[i].cloneNode(true));Object.defineProperty(this,'width',{get:function(){return this.width_;},set:function(width){this.width_=width;this.updateContents_();}});Object.defineProperty(this,'height',{get:function(){return this.height_;},set:function(height){this.height_=height;this.updateContents_();}});},get chartTitle(){return this.chartTitle_;},set chartTitle(chartTitle){this.chartTitle_=chartTitle;this.updateContents_();},get chartAreaElement(){return this.querySelector('#chart-area');},setSize:function(size){this.width_=size.width;this.height_=size.height;this.updateContents_();},getMargin_:function(){var margin={top:20,right:20,bottom:30,left:50};if(this.chartTitle_)
+margin.top+=20;return margin;},get margin(){return this.getMargin_();},get chartAreaSize(){var margin=this.margin;return{width:this.width_-margin.left-margin.right,height:this.height_-margin.top-margin.bottom};},getLegendKeys_:function(){throw new Error('Not implemented');},updateScales_:function(){throw new Error('Not implemented');},updateContents_:function(){var margin=this.margin;var thisSel=d3.select(this);thisSel.attr('width',this.width_);thisSel.attr('height',this.height_);var chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.attr('transform','translate('+margin.left+','+margin.top+')');this.updateScales_();this.updateTitle_(chartAreaSel);this.updateLegend_();},updateTitle_:function(chartAreaSel){var titleSel=chartAreaSel.select('#title');if(!this.chartTitle_){titleSel.style('display','none');return;}
+var width=this.chartAreaSize.width;titleSel.attr('transform','translate('+width*0.5+',-5)').style('display',undefined).style('text-anchor','middle').attr('class','title').attr('width',width).text(this.chartTitle_);},updateLegend_:function(){var keys=this.getLegendKeys_();if(keys===undefined)
+return;var chartAreaSel=d3.select(this.chartAreaElement);var chartAreaSize=this.chartAreaSize;var legendEntriesSel=chartAreaSel.selectAll('.legend').data(keys.slice().reverse());legendEntriesSel.enter().append('g').attr('class','legend').attr('transform',function(d,i){return'translate(0,'+i*20+')';}).append('text').text(function(key){return key;});legendEntriesSel.exit().remove();legendEntriesSel.attr('x',chartAreaSize.width-18).attr('width',18).attr('height',18).style('fill',function(key){var selected=this.currentHighlightedLegendKey===key;return getColorOfKey(key,selected);}.bind(this));legendEntriesSel.selectAll('text').attr('x',chartAreaSize.width-24).attr('y',9).attr('dy','.35em').style('text-anchor','end').text(function(d){return d;});},get highlightedLegendKey(){return this.highlightedLegendKey_;},set highlightedLegendKey(highlightedLegendKey){this.highlightedLegendKey_=highlightedLegendKey;this.updateHighlight_();},get currentHighlightedLegendKey(){if(this.tempHighlightedLegendKey_)
+return this.tempHighlightedLegendKey_;return this.highlightedLegendKey_;},pushTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_)
+throw new Error('push cannot nest');this.tempHighlightedLegendKey_=key;this.updateHighlight_();},popTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_!=key)
+throw new Error('pop cannot happen');this.tempHighlightedLegendKey_=undefined;this.updateHighlight_();},updateHighlight_:function(){var chartAreaSel=d3.select(this.chartAreaElement);var legendEntriesSel=chartAreaSel.selectAll('.legend');var that=this;legendEntriesSel.each(function(key){var highlighted=key==that.currentHighlightedLegendKey;var color=getColorOfKey(key,highlighted);this.style.fill=color;if(highlighted)
+this.style.fontWeight='bold';else
+this.style.fontWeight='';});}};return{getColorOfKey:getColorOfKey,ChartBase:ChartBase};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var ChartBase2D=tr.ui.b.define('chart-base-2d',ChartBase);ChartBase2D.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('chart-base-2d');this.xScale_=d3.scale.linear();this.yScale_=d3.scale.linear();this.isYLogScale_=false;this.yLogScaleMin_=undefined;this.dataRange_=new tr.b.Range();this.data_=[];this.seriesKeys_=[];this.leftMargin_=50;d3.select(this.chartAreaElement).append('g').attr('id','brushes');d3.select(this.chartAreaElement).append('g').attr('id','series');this.addEventListener('mousedown',this.onMouseDown_.bind(this));},get data(){return this.data_;},set data(data){if(data===undefined)
+throw new Error('data must be an Array');this.data_=data;this.updateSeriesKeys_();this.updateDataRange_();this.updateContents_();},set isYLogScale(logScale){if(logScale)
+this.yScale_=d3.scale.log(10);else
+this.yScale_=d3.scale.linear();this.isYLogScale_=logScale;},getYScaleMin_:function(){return this.isYLogScale_?this.yLogScaleMin_:0;},getYScaleDomain_:function(minValue,maxValue){if(this.isYLogScale_)
+return[this.getYScaleMin_(),maxValue];return[Math.min(minValue,this.getYScaleMin_()),maxValue];},getSampleWidth_:function(data,index,leftSide){var leftIndex,rightIndex;if(leftSide){leftIndex=Math.max(index-1,0);rightIndex=index;}else{leftIndex=index;rightIndex=Math.min(index+1,data.length-1);}
+var leftWidth=this.getXForDatum_(data[index],index)-
+this.getXForDatum_(data[leftIndex],leftIndex);var rightWidth=this.getXForDatum_(data[rightIndex],rightIndex)-
+this.getXForDatum_(data[index],index);return leftWidth*0.5+rightWidth*0.5;},getLegendKeys_:function(){if(this.seriesKeys_&&this.seriesKeys_.length>1)
+return this.seriesKeys_.slice();return[];},updateSeriesKeys_:function(){var keySet={};this.data_.forEach(function(datum){Object.keys(datum).forEach(function(key){if(this.isDatumFieldSeries_(key))
+keySet[key]=true;},this);},this);this.seriesKeys_=Object.keys(keySet);},isDatumFieldSeries_:function(fieldName){throw new Error('Not implemented');},getXForDatum_:function(datum,index){throw new Error('Not implemented');},updateScales_:function(){if(this.data_.length===0)
+return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;this.xScale_.range([0,width]);this.xScale_.domain(d3.extent(this.data_,this.getXForDatum_.bind(this)));var yRange=new tr.b.Range();this.data_.forEach(function(datum){this.seriesKeys_.forEach(function(key){if(datum[key]!==undefined)
+yRange.addValue(datum[key]);});},this);this.yScale_.range([height,0]);this.yScale_.domain([yRange.min,yRange.max]);},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();},updateXAxis_:function(xAxis){xAxis.selectAll('*').remove();xAxis[0][0].style.opacity=0;xAxis.attr('transform','translate(0,'+this.chartAreaSize.height+')').call(d3.svg.axis().scale(this.xScale_).orient('bottom'));window.requestAnimationFrame(function(){var previousRight=undefined;xAxis.selectAll('.tick')[0].forEach(function(tick){var currentLeft=tick.transform.baseVal[0].matrix.e;if((previousRight===undefined)||(currentLeft>(previousRight+3))){var currentWidth=tick.getBBox().width;previousRight=currentLeft+currentWidth;}else{tick.style.opacity=0;}});xAxis[0][0].style.opacity=1;});},getMargin_:function(){var margin=ChartBase.prototype.getMargin_.call(this);margin.left=this.leftMargin_;return margin;},updateDataRange_:function(){var dataBySeriesKey=this.getDataBySeriesKey_();this.dataRange_.reset();tr.b.iterItems(dataBySeriesKey,function(series,values){for(var i=0;i<values.length;i++){this.dataRange_.addValue(values[i][series]);}},this);this.yLogScaleMin_=undefined;if(this.dataRange_.min!==undefined){var minValue=this.dataRange_.min;if(minValue==0)
+minValue=1;var onePowerLess=Math.floor(Math.log(minValue)/Math.log(10))-1;this.yLogScaleMin_=Math.pow(10,onePowerLess);}},updateYAxis_:function(yAxis){yAxis.selectAll('*').remove();yAxis[0][0].style.opacity=0;var axisModifier=d3.svg.axis().scale(this.yScale_).orient('left');if(this.isYLogScale_){if(this.yLogScaleMin_===undefined)
+return;var minValue=this.dataRange_.min;if(minValue==0)
+minValue=1;var largestPower=Math.ceil(Math.log(this.dataRange_.max)/Math.log(10))+1;var smallestPower=Math.floor(Math.log(minValue)/Math.log(10));var tickValues=[];for(var i=smallestPower;i<largestPower;i++){tickValues.push(Math.pow(10,i));}
+axisModifier=axisModifier.tickValues(tickValues).tickFormat(function(d){return d;});}
+yAxis.call(axisModifier);window.requestAnimationFrame(function(){var previousTop=undefined;var leftMargin=0;yAxis.selectAll('.tick')[0].forEach(function(tick){var bbox=tick.getBBox();leftMargin=Math.max(leftMargin,bbox.width);var currentTop=tick.transform.baseVal[0].matrix.f;var currentBottom=currentTop+bbox.height;if((previousTop===undefined)||(previousTop>(currentBottom+3))){previousTop=currentTop;}else{tick.style.opacity=0;}});if(leftMargin>this.leftMargin_){this.leftMargin_=leftMargin;this.updateContents_();}else{yAxis[0][0].style.opacity=1;}}.bind(this));},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);var chartAreaSel=d3.select(this.chartAreaElement);this.updateXAxis_(chartAreaSel.select('.x.axis'));this.updateYAxis_(chartAreaSel.select('.y.axis'));this.updateBrushContents_(chartAreaSel.select('#brushes'));this.updateDataContents_(chartAreaSel.select('#series'));},updateDataContents_:function(seriesSel){throw new Error('Not implemented');},getDataBySeriesKey_:function(){var dataBySeriesKey={};this.seriesKeys_.forEach(function(seriesKey){dataBySeriesKey[seriesKey]=[];});this.data_.forEach(function(multiSeriesDatum,index){var x=this.getXForDatum_(multiSeriesDatum,index);d3.keys(multiSeriesDatum).forEach(function(seriesKey){if(seriesKey==='x')
+return;if(multiSeriesDatum[seriesKey]===undefined)
+return;if(!this.isDatumFieldSeries_(seriesKey))
+return;var singleSeriesDatum={x:x};singleSeriesDatum[seriesKey]=multiSeriesDatum[seriesKey];dataBySeriesKey[seriesKey].push(singleSeriesDatum);},this);},this);return dataBySeriesKey;},getDataPointAtClientPoint_:function(clientX,clientY){var rect=this.getBoundingClientRect();var margin=this.margin;var x=clientX-rect.left-margin.left;var y=clientY-rect.top-margin.top;x=this.xScale_.invert(x);y=this.yScale_.invert(y);x=tr.b.clamp(x,this.xScale_.domain()[0],this.xScale_.domain()[1]);y=tr.b.clamp(y,this.yScale_.domain()[0],this.yScale_.domain()[1]);return{x:x,y:y};},prepareDataEvent_:function(mouseEvent,dataEvent){var dataPoint=this.getDataPointAtClientPoint_(mouseEvent.clientX,mouseEvent.clientY);dataEvent.x=dataPoint.x;dataEvent.y=dataPoint.y;},onMouseDown_:function(mouseEvent){tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_.bind(this,mouseEvent.button),this.onMouseUp_.bind(this,mouseEvent.button));mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mousedown');dataEvent.button=mouseEvent.button;this.classList.add('updating-brushing-state');this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseMove_:function(button,mouseEvent){if(mouseEvent.buttons!==undefined){mouseEvent.preventDefault();mouseEvent.stopPropagation();}
+var dataEvent=new tr.b.Event('item-mousemove');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseUp_:function(button,mouseEvent){mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mouseup');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);this.classList.remove('updating-brushing-state');}};return{ChartBase2D:ChartBase2D};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2D=tr.ui.b.ChartBase2D;var ChartBase2DBrushX=tr.ui.b.define('chart-base-2d-brush-1d',ChartBase2D);ChartBase2DBrushX.prototype={__proto__:ChartBase2D.prototype,decorate:function(){ChartBase2D.prototype.decorate.call(this);this.brushedRange_=new tr.b.Range();},set brushedRange(range){this.brushedRange_.reset();this.brushedRange_.addRange(range);this.updateContents_();},computeBrushRangeFromIndices:function(indexA,indexB){indexA=tr.b.clamp(indexA,0,this.data_.length-1);indexB=tr.b.clamp(indexB,0,this.data_.length-1);var leftIndex=Math.min(indexA,indexB);var rightIndex=Math.max(indexA,indexB);var r=new tr.b.Range();r.addValue(this.getXForDatum_(this.data_[leftIndex],leftIndex)-
+this.getSampleWidth_(this.data_,leftIndex,true));r.addValue(this.getXForDatum_(this.data_[rightIndex],rightIndex)+
+this.getSampleWidth_(this.data_,rightIndex,false));return r;},getDataIndex_:function(dataX){if(!this.data_)
+return undefined;var bisect=d3.bisector(this.getXForDatum_.bind(this)).right;return bisect(this.data_,dataX)-1;},prepareDataEvent_:function(mouseEvent,dataEvent){ChartBase2D.prototype.prepareDataEvent_.call(this,mouseEvent,dataEvent);dataEvent.index=this.getDataIndex_(dataEvent.x);if(dataEvent.index!==undefined)
+dataEvent.data=this.data_[dataEvent.index];},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();var brushes=this.brushedRange_.isEmpty?[]:[this.brushedRange_];var brushRectsSel=brushSel.selectAll('rect').data(brushes);brushRectsSel.enter().append('rect');brushRectsSel.exit().remove();brushRectsSel.attr('x',function(d){return this.xScale_(d.min);}.bind(this)).attr('y',0).attr('width',function(d){return this.xScale_(d.max)-this.xScale_(d.min);}.bind(this)).attr('height',this.chartAreaSize.height);}};return{ChartBase2DBrushX:ChartBase2DBrushX};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2DBrushX=tr.ui.b.ChartBase2DBrushX;var LineChart=tr.ui.b.define('line-chart',ChartBase2DBrushX);LineChart.prototype={__proto__:ChartBase2DBrushX.prototype,decorate:function(){ChartBase2DBrushX.prototype.decorate.call(this);this.classList.add('line-chart');},isDatumFieldSeries_:function(fieldName){return fieldName!='x';},getXForDatum_:function(datum,index){return datum.x;},updateDataContents_:function(dataSel){dataSel.selectAll('*').remove();var dataBySeriesKey=this.getDataBySeriesKey_();var pathsSel=dataSel.selectAll('path').data(this.seriesKeys_);pathsSel.enter().append('path').attr('class','line').style('stroke',function(key){return tr.ui.b.getColorOfKey(key);}).attr('d',function(key){var line=d3.svg.line().x(function(d){return this.xScale_(d.x);}.bind(this)).y(function(d){return this.yScale_(d[key]);}.bind(this));return line(dataBySeriesKey[key]);}.bind(this));pathsSel.exit().remove();}};return{LineChart:LineChart};});'use strict';Polymer('tr-ui-side-panel',{ready:function(){},get rangeOfInterest(){throw new Error('Not implemented');},set rangeOfInterest(rangeOfInterest){throw new Error('Not implemented');},get selection(){throw new Error('Not implemented');},set selection(selection){throw new Error('Not implemented');},get model(){throw new Error('Not implemented');},set model(model){throw new Error('Not implemented');},supportsModel:function(m){throw new Error('Not implemented');}});'use strict';Polymer('tr-ui-e-s-input-latency-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.frametimeType_=tr.model.helpers.IMPL_FRAMETIME_TYPE;this.latencyChart_=undefined;this.frametimeChart_=undefined;this.selectedProcessId_=undefined;this.mouseDownIndex_=undefined;this.curMouseIndex_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;if(this.model_){this.modelHelper_=this.model_.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}else{this.modelHelper_=undefined;}
+this.updateToolbar_();this.updateContents_();},get frametimeType(){return this.frametimeType_;},set frametimeType(type){if(this.frametimeType_===type)
+return;this.frametimeType_=type;this.updateContents_();},get selectedProcessId(){return this.selectedProcessId_;},set selectedProcessId(process){if(this.selectedProcessId_===process)
+return;this.selectedProcessId_=process;this.updateContents_();},set selection(selection){if(this.latencyChart_===undefined)
+return;this.latencyChart_.brushedRange=selection.bounds;},setBrushedIndices:function(mouseDownIndex,curIndex){this.mouseDownIndex_=mouseDownIndex;this.curMouseIndex_=curIndex;this.updateBrushedRange_();},updateBrushedRange_:function(){if(this.latencyChart_===undefined)
+return;var r=new tr.b.Range();if(this.mouseDownIndex_===undefined){this.latencyChart_.brushedRange=r;return;}
+r=this.latencyChart_.computeBrushRangeFromIndices(this.mouseDownIndex_,this.curMouseIndex_);this.latencyChart_.brushedRange=r;var latencySlices=[];this.model_.getAllThreads().forEach(function(thread){thread.iterateAllEvents(function(event){if(event.title.indexOf('InputLatency:')===0)
+latencySlices.push(event);});});latencySlices=tr.model.helpers.getSlicesIntersectingRange(r,latencySlices);var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(latencySlices);this.latencyChart_.dispatchEvent(event);},registerMouseEventForLatencyChart_:function(){this.latencyChart_.addEventListener('item-mousedown',function(e){this.mouseDownIndex_=e.index;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mousemove',function(e){if(e.button==undefined)
+return;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mouseup',function(e){this.curMouseIndex=e.index;this.updateBrushedRange_();}.bind(this));},updateToolbar_:function(){var browserProcess=this.modelHelper_.browserProcess;var labels=[];if(browserProcess!==undefined){var label_str='Browser: '+browserProcess.pid;labels.push({label:label_str,value:browserProcess.pid});}
+tr.b.iterItems(this.modelHelper_.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;var label_str='Renderer: '+rendererProcess.userFriendlyName;labels.push({label:label_str,value:rendererProcess.userFriendlyName});},this);if(labels.length===0)
+return;this.selectedProcessId_=labels[0].value;var toolbarEl=this.$.toolbar;toolbarEl.appendChild(tr.ui.b.createSelector(this,'frametimeType','inputLatencySidePanel.frametimeType',this.frametimeType_,[{label:'Main Thread Frame Times',value:tr.model.helpers.MAIN_FRAMETIME_TYPE},{label:'Impl Thread Frame Times',value:tr.model.helpers.IMPL_FRAMETIME_TYPE}]));toolbarEl.appendChild(tr.ui.b.createSelector(this,'selectedProcessId','inputLatencySidePanel.selectedProcessId',this.selectedProcessId_,labels));},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty)
+return this.model_.bounds;else
+return this.rangeOfInterest_;},createLatencyLineChart:function(data,title){var chart=new tr.ui.b.LineChart();var width=600;if(document.body.clientWidth!=undefined)
+width=document.body.clientWidth*0.5;chart.setSize({width:width,height:chart.height});chart.chartTitle=title;chart.data=data;return chart;},updateContents_:function(){var resultArea=this.$.result_area;this.latencyChart_=undefined;this.frametimeChart_=undefined;resultArea.textContent='';if(this.modelHelper_===undefined)
+return;var rangeOfInterest=this.currentRangeOfInterest;var chromeProcess;if(this.modelHelper_.rendererHelpers[this.selectedProcessId_])
+chromeProcess=this.modelHelper_.rendererHelpers[this.selectedProcessId_];else
+chromeProcess=this.modelHelper_.browserHelper;var frameEvents=chromeProcess.getFrameEventsInRange(this.frametimeType,rangeOfInterest);var frametimeData=tr.model.helpers.getFrametimeDataFromEvents(frameEvents);var averageFrametime=tr.b.Statistics.mean(frametimeData,function(d){return d.frametime;});var latencyEvents=this.modelHelper_.browserHelper.getLatencyEventsInRange(rangeOfInterest);var latencyData=[];latencyEvents.forEach(function(event){if(event.inputLatency===undefined)
+return;latencyData.push({x:event.start,latency:event.inputLatency/1000});});var averageLatency=tr.b.Statistics.mean(latencyData,function(d){return d.latency;});var latencySummaryText=document.createElement('div');latencySummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Latency '+averageLatency+' ms',bold:true}));resultArea.appendChild(latencySummaryText);var frametimeSummaryText=document.createElement('div');frametimeSummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Frame Time '+averageFrametime+' ms',bold:true}));resultArea.appendChild(frametimeSummaryText);if(latencyData.length!==0){this.latencyChart_=this.createLatencyLineChart(latencyData,'Latency Over Time');this.registerMouseEventForLatencyChart_();resultArea.appendChild(this.latencyChart_);}
+if(frametimeData.length!=0){this.frametimeChart_=this.createLatencyLineChart(frametimeData,'Frame Times');this.frametimeChart_.style.display='block';resultArea.appendChild(this.frametimeChart_);}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}
+if(!tr.model.helpers.ChromeModelHelper.supportsModel(m)){return{supported:false,reason:'No Chrome browser or renderer process found'};}
+var modelHelper=m.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper.browserHelper&&modelHelper.browserHelper.hasLatencyEvents){return{supported:true};}
+return{supported:false,reason:'No InputLatency events trace. Consider enabling '+'benchmark" and "input" category when recording the trace'};},get textLabel(){return'Input Latency';}});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var getColorOfKey=tr.ui.b.getColorOfKey;var MIN_RADIUS=100;var PieChart=tr.ui.b.define('pie-chart',ChartBase);PieChart.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('pie-chart');this.data_=undefined;this.seriesKeys_=undefined;var chartAreaSel=d3.select(this.chartAreaElement);var pieGroupSel=chartAreaSel.append('g').attr('class','pie-group');this.pieGroup_=pieGroupSel.node();this.pathsGroup_=pieGroupSel.append('g').attr('class','paths').node();this.labelsGroup_=pieGroupSel.append('g').attr('class','labels').node();this.linesGroup_=pieGroupSel.append('g').attr('class','lines').node();},get data(){return this.data_;},set data(data){if(data!==undefined){var seriesKeys=[];var seenSeriesKeys={};data.forEach(function(d){var k=d.label;if(seenSeriesKeys[k])
+throw new Error('Label '+k+' has been used already');seriesKeys.push(k);seenSeriesKeys[k]=true;},this);this.seriesKeys_=seriesKeys;}else{this.seriesKeys_=undefined;}
+this.data_=data;this.updateContents_();},get margin(){var margin={top:0,right:0,bottom:0,left:0};if(this.chartTitle_)
+margin.top+=40;return margin;},getMinSize:function(){this.updateContents_();var labelSel=d3.select(this.labelsGroup_).selectAll('.label');var maxLabelWidth=-Number.MAX_VALUE;var leftTextHeightSum=0;var rightTextHeightSum=0;labelSel.each(function(l){var r=this.getBoundingClientRect();maxLabelWidth=Math.max(maxLabelWidth,r.width+32);if(this.style.textAnchor=='end'){leftTextHeightSum+=r.height;}else{rightTextHeightSum+=r.height;}});var titleWidth=this.querySelector('#title').getBoundingClientRect().width;var margin=this.margin;var marginWidth=margin.left+margin.right;var marginHeight=margin.top+margin.bottom;return{width:Math.max(2*MIN_RADIUS+2*maxLabelWidth,titleWidth*1.1)+marginWidth,height:marginHeight+Math.max(2*MIN_RADIUS,leftTextHeightSum,rightTextHeightSum)*1.25};},getLegendKeys_:function(){return undefined;},updateScales_:function(width,height){if(this.data_===undefined)
+return;},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);if(!this.data_)
+return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;var radius=Math.max(MIN_RADIUS,Math.min(width,height*0.95)/2);d3.select(this.pieGroup_).attr('transform','translate('+width/2+','+height/2+')');var pieLayout=d3.layout.pie().value(function(d){return d.value;}).sort(null);var piePathsSel=d3.select(this.pathsGroup_).datum(this.data_).selectAll('path').data(pieLayout);function midAngle(d){return d.startAngle+(d.endAngle-d.startAngle)/2;}
+var pathsArc=d3.svg.arc().innerRadius(0).outerRadius(radius-30);var valueLabelArc=d3.svg.arc().innerRadius(radius-100).outerRadius(radius-30);var lineBeginArc=d3.svg.arc().innerRadius(radius-50).outerRadius(radius-50);var lineEndArc=d3.svg.arc().innerRadius(radius).outerRadius(radius);piePathsSel.enter().append('path').attr('class','arc').attr('fill',function(d,i){var origData=this.data_[i];var highlighted=(origData.label===this.currentHighlightedLegendKey);return getColorOfKey(origData.label,highlighted);}.bind(this)).attr('d',pathsArc).on('click',function(d,i){var origData=this.data_[i];var event=new tr.b.Event('item-click');event.data=origData;event.index=i;this.dispatchEvent(event);d3.event.stopPropagation();}.bind(this)).on('mouseenter',function(d,i){var origData=this.data_[i];this.pushTempHighlightedLegendKey(origData.label);}.bind(this)).on('mouseleave',function(d,i){var origData=this.data_[i];this.popTempHighlightedLegendKey(origData.label);}.bind(this));piePathsSel.enter().append('text').attr('class','arc-text').attr('transform',function(d){return'translate('+valueLabelArc.centroid(d)+')';}).attr('dy','.35em').style('text-anchor','middle').text(function(d,i){var origData=this.data_[i];if(origData.valueText===undefined)
+return'';if(d.endAngle-d.startAngle<0.4)
+return'';return origData.valueText;}.bind(this));piePathsSel.exit().remove();var labelSel=d3.select(this.labelsGroup_).selectAll('.label').data(pieLayout(this.data_));labelSel.enter().append('text').attr('class','label').attr('dy','.35em');labelSel.text(function(d){if(d.data.label.length>40)
+return d.data.label.substr(0,40)+'...';return d.data.label;});labelSel.attr('transform',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*(midAngle(d)<Math.PI?1:-1);return'translate('+pos+')';});labelSel.style('text-anchor',function(d){return midAngle(d)<Math.PI?'start':'end';});var lineSel=d3.select(this.linesGroup_).selectAll('.line').data(pieLayout(this.data_));lineSel.enter().append('polyline').attr('class','line').attr('dy','.35em');lineSel.attr('points',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*0.95*(midAngle(d)<Math.PI?1:-1);return[lineBeginArc.centroid(d),lineEndArc.centroid(d),pos];});},updateHighlight_:function(){ChartBase.prototype.updateHighlight_.call(this);var pathsGroupSel=d3.select(this.pathsGroup_);var that=this;pathsGroupSel.selectAll('.arc').each(function(d,i){var origData=that.data_[i];var highlighted=origData.label==that.currentHighlightedLegendKey;var color=getColorOfKey(origData.label,highlighted);this.style.fill=color;});}};return{PieChart:PieChart};});'use strict';(function(){var GROUP_BY_PROCESS_NAME='process';var GROUP_BY_THREAD_NAME='thread';var WALL_TIME_GROUPING_UNIT='Wall time';var CPU_TIME_GROUPING_UNIT='CPU time';function ResultsForGroup(model,name){this.model=model;this.name=name;this.topLevelSlices=[];this.allSlices=[];}
+ResultsForGroup.prototype={get wallTime(){var wallSum=tr.b.Statistics.sum(this.topLevelSlices,function(x){return x.duration;});return wallSum;},get cpuTime(){var cpuDuration=0;for(var i=0;i<this.topLevelSlices.length;i++){var x=this.topLevelSlices[i];if(x.cpuDuration===undefined){if(x.duration===undefined)
+continue;return 0;}
+cpuDuration+=x.cpuDuration;}
+return cpuDuration;},appendGroupContents:function(group){if(group.model!=this.model)
+throw new Error('Models must be the same');group.allSlices.forEach(function(slice){this.allSlices.push(slice);},this);group.topLevelSlices.forEach(function(slice){this.topLevelSlices.push(slice);},this);},appendThreadSlices:function(rangeOfInterest,thread){var tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.slices);tmp.forEach(function(slice){this.allSlices.push(slice);},this);tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.topLevelSlices);tmp.forEach(function(slice){this.topLevelSlices.push(slice);},this);},getSlicesIntersectingRange:function(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end))
+slicesInFilterRange.push(slice);}
+return slicesInFilterRange;}};Polymer('tr-ui-e-s-time-summary-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;this.groupBy_=GROUP_BY_PROCESS_NAME;this.groupingUnit_=CPU_TIME_GROUPING_UNIT;this.showCpuIdleTime_=true;this.chart_=undefined;var toolbarEl=this.$.toolbar;this.groupBySelector_=tr.ui.b.createSelector(this,'groupBy','timeSummarySidePanel.groupBy',this.groupBy_,[{label:'Group by process',value:GROUP_BY_PROCESS_NAME},{label:'Group by thread',value:GROUP_BY_THREAD_NAME}]);toolbarEl.appendChild(this.groupBySelector_);this.groupingUnitSelector_=tr.ui.b.createSelector(this,'groupingUnit','timeSummarySidePanel.groupingUnit',this.groupingUnit_,[{label:'Wall time',value:WALL_TIME_GROUPING_UNIT},{label:'CPU time',value:CPU_TIME_GROUPING_UNIT}]);toolbarEl.appendChild(this.groupingUnitSelector_);this.showCpuIdleTimeCheckbox_=tr.ui.b.createCheckBox(this,'showCpuIdleTime','timeSummarySidePanel.showCpuIdleTime',this.showCpuIdleTime_,'Show CPU idle time');toolbarEl.appendChild(this.showCpuIdleTimeCheckbox_);this.updateShowCpuIdleTimeCheckboxVisibility_();},trimPieChartData:function(groups,otherGroup,getValue,opt_extraValue){groups=groups.filter(function(d){return getValue(d)!=0;});var sum=tr.b.Statistics.sum(groups,getValue);if(opt_extraValue!==undefined)
+sum+=opt_extraValue;function compareByValue(a,b){return getValue(a)-getValue(b);}
+groups.sort(compareByValue);var thresshold=0.1*sum;while(groups.length>1){var group=groups[0];if(getValue(group)>=thresshold)
+break;var v=getValue(group);if(v+getValue(otherGroup)>thresshold)
+break;groups.splice(0,1);otherGroup.appendGroupContents(group);}
+if(getValue(otherGroup)>0)
+groups.push(otherGroup);groups.sort(compareByValue);return groups;},generateResultsForGroup:function(model,name){return new ResultsForGroup(model,name);},createPieChartFromResultGroups:function(groups,title,getValue,opt_extraData){var chart=new tr.ui.b.PieChart();function pushDataForGroup(data,resultsForGroup,value){data.push({label:resultsForGroup.name,value:value,valueText:tr.v.Unit.byName.timeDurationInMs.format(value),resultsForGroup:resultsForGroup});}
+chart.addEventListener('item-click',function(clickEvent){var resultsForGroup=clickEvent.data.resultsForGroup;if(resultsForGroup===undefined)
+return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(resultsForGroup.allSlices);event.selection.timeSummaryGroupName=resultsForGroup.name;chart.dispatchEvent(event);});var data=[];groups.forEach(function(resultsForGroup){var value=getValue(resultsForGroup);if(value===0)
+return;pushDataForGroup(data,resultsForGroup,value);});if(opt_extraData)
+data.push.apply(data,opt_extraData);chart.chartTitle=title;chart.data=data;return chart;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get groupBy(){return groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;if(this.groupBySelector_)
+this.groupBySelector_.selectedValue=groupBy;this.updateContents_();},get groupingUnit(){return groupingUnit_;},set groupingUnit(groupingUnit){this.groupingUnit_=groupingUnit;if(this.groupingUnitSelector_)
+this.groupingUnitSelector_.selectedValue=groupingUnit;this.updateShowCpuIdleTimeCheckboxVisibility_();this.updateContents_();},get showCpuIdleTime(){return this.showCpuIdleTime_;},set showCpuIdleTime(showCpuIdleTime){this.showCpuIdleTime_=showCpuIdleTime;if(this.showCpuIdleTimeCheckbox_)
+this.showCpuIdleTimeCheckbox_.checked=showCpuIdleTime;this.updateContents_();},updateShowCpuIdleTimeCheckboxVisibility_:function(){if(!this.showCpuIdleTimeCheckbox_)
+return;var visible=this.groupingUnit_==CPU_TIME_GROUPING_UNIT;if(visible)
+this.showCpuIdleTimeCheckbox_.style.display='';else
+this.showCpuIdleTimeCheckbox_.style.display='none';},getGroupNameForThread_:function(thread){if(this.groupBy_==GROUP_BY_THREAD_NAME)
+return thread.name?thread.name:thread.userFriendlyName;if(this.groupBy_==GROUP_BY_PROCESS_NAME)
+return thread.parent.userFriendlyName;},updateContents_:function(){var resultArea=this.$.result_area;this.chart_=undefined;resultArea.textContent='';if(this.model_===undefined)
+return;var rangeOfInterest;if(this.rangeOfInterest_.isEmpty)
+rangeOfInterest=this.model_.bounds;else
+rangeOfInterest=this.rangeOfInterest_;var allGroup=this.generateResultsForGroup(this.model_,'all');var resultsByGroupName={};this.model_.getAllThreads().forEach(function(thread){var groupName=this.getGroupNameForThread_(thread);if(resultsByGroupName[groupName]===undefined){resultsByGroupName[groupName]=this.generateResultsForGroup(this.model_,groupName);}
+resultsByGroupName[groupName].appendThreadSlices(rangeOfInterest,thread);allGroup.appendThreadSlices(rangeOfInterest,thread);},this);var getValueFromGroup=function(group){if(this.groupingUnit_==WALL_TIME_GROUPING_UNIT)
+return group.wallTime;return group.cpuTime;}.bind(this);var summaryText=document.createElement('div');summaryText.appendChild(tr.ui.b.createSpan({textContent:'Total '+this.groupingUnit_+': ',bold:true}));summaryText.appendChild(tr.v.ui.createScalarSpan(getValueFromGroup(allGroup),{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument}));resultArea.appendChild(summaryText);var extraValue=0;var extraData=[];if(this.showCpuIdleTime_&&this.groupingUnit_===CPU_TIME_GROUPING_UNIT&&this.model.kernel.bestGuessAtCpuCount!==undefined){var maxCpuTime=rangeOfInterest.range*this.model.kernel.bestGuessAtCpuCount;var idleTime=Math.max(0,maxCpuTime-allGroup.cpuTime);extraData.push({label:'CPU Idle',value:idleTime,valueText:tr.v.Unit.byName.timeDurationInMs.format(idleTime)});extraValue+=idleTime;}
+var otherGroup=this.generateResultsForGroup(this.model_,'Other');var groups=this.trimPieChartData(tr.b.dictionaryValues(resultsByGroupName),otherGroup,getValueFromGroup,extraValue);if(groups.length==0){resultArea.appendChild(tr.ui.b.createSpan({textContent:'No data'}));return undefined;}
+this.chart_=this.createPieChartFromResultGroups(groups,this.groupingUnit_+' breakdown by '+this.groupBy_,getValueFromGroup,extraData);resultArea.appendChild(this.chart_);this.chart_.addEventListener('click',function(){var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.c.EventSet([]);this.dispatchEvent(event);});this.chart_.setSize(this.chart_.getMinSize());},get selection(){return selection_;},set selection(selection){this.selection_=selection;if(this.chart_===undefined)
+return;if(selection.timeSummaryGroupName)
+this.chart_.highlightedLegendKey=selection.timeSummaryGroupName;else
+this.chart_.highlightedLegendKey=undefined;},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(model){return{supported:false};},get textLabel(){return'Time Summary';}});}());'use strict';tr.exportTo('tr.e.system_stats',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function SystemStatsSnapshot(objectInstance,ts,args){ObjectSnapshot.apply(this,arguments);this.objectInstance=objectInstance;this.ts=ts;this.args=args;this.stats=args;}
 SystemStatsSnapshot.prototype={__proto__:ObjectSnapshot.prototype,initialize:function(){if(this.args.length==0)
 throw new Error('No system stats snapshot data.');this.stats_=this.args;},getStats:function(){return this.stats_;},setStats:function(stats){this.stats_=stats;}};ObjectSnapshot.register(SystemStatsSnapshot,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshot:SystemStatsSnapshot};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var SystemStatsSnapshotView=tr.ui.b.define('tr-ui-e-system-stats-snapshot-view',tr.ui.analysis.ObjectSnapshotView);SystemStatsSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-system-stats-snapshot-view');},updateContents:function(){var snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.getStats()){this.textContent='No system stats snapshot found.';return;}
 this.textContent='';var stats=snapshot.getStats();this.appendChild(this.buildList_(stats));},isFloat:function(n){return typeof n==='number'&&n%1!==0;},buildList_:function(stats){var statList=document.createElement('ul');for(var statName in stats){var statText=document.createElement('li');statText.textContent=''+statName+': ';statList.appendChild(statText);if(stats[statName]instanceof Object){statList.appendChild(this.buildList_(stats[statName]));}else{if(this.isFloat(stats[statName]))
 statText.textContent+=stats[statName].toFixed(2);else
 statText.textContent+=stats[statName];}}
-return statList;}};tr.ui.analysis.ObjectSnapshotView.register(SystemStatsSnapshotView,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshotView:SystemStatsSnapshotView};});'use strict';tr.exportTo('tr.ui.tracks',function(){var StackedBarsTrack=tr.ui.b.define('stacked-bars-track',tr.ui.tracks.Track);StackedBarsTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('stacked-bars-track');this.objectInstance_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},addEventsToTrackMap:function(eventToTrackMap){var objectSnapshots=this.objectInstance_.snapshots;objectSnapshots.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onSnapshot(snapshot){selection.push(snapshot);}
+return statList;}};tr.ui.analysis.ObjectSnapshotView.register(SystemStatsSnapshotView,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshotView:SystemStatsSnapshotView};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={HEADING_WIDTH:250};return{constants:constants};});'use strict';Polymer('tr-ui-heading',{DOWN_ARROW:String.fromCharCode(0x25BE),RIGHT_ARROW:String.fromCharCode(0x25B8),ready:function(viewport){this.style.width=(tr.ui.b.constants.HEADING_WIDTH-6)+'px';this.heading_='';this.expanded_=true;this.arrowVisible_=false;this.selectionGenerator_=undefined;this.updateContents_();},get heading(){return this.heading_;},set heading(text){if(this.heading_===text)
+return;this.heading_=text;this.updateContents_();},set arrowVisible(val){if(this.arrowVisible_===val)
+return;this.arrowVisible_=!!val;this.updateContents_();},set tooltip(text){this.$.heading.title=text;},set selectionGenerator(generator){if(this.selectionGenerator_===generator)
+return;this.selectionGenerator_=generator;this.updateContents_();},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)
+return;this.expanded_=!!expanded;this.updateContents_();},onHeadingDivClicked_:function(){this.dispatchEvent(new tr.b.Event('heading-clicked',{'bubbles':true}));},updateContents_:function(){if(this.arrowVisible_){this.$.arrow.style.display='';}else{this.$.arrow.style.display='none';this.$.heading.style.display=this.expanded_?'':'none';}
+if(this.arrowVisible_){this.$.arrow.textContent=this.expanded_?this.DOWN_ARROW:this.RIGHT_ARROW;}
+this.$.link.style.display='none';this.$.heading_content.style.display='none';if(this.selectionGenerator_){this.$.link.style.display='inline-block';this.$.link.selection=this.selectionGenerator_;this.$.link.textContent=this.heading_;}else{this.$.heading_content.style.display='inline-block';this.$.heading_content.textContent=this.heading_;}}});'use strict';tr.exportTo('tr.ui.tracks',function(){var Track=tr.ui.b.define('track',tr.ui.b.ContainerThatDecoratesItsChildren);Track.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(viewport){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);if(viewport===undefined)
+throw new Error('viewport is required when creating a Track.');this.viewport_=viewport;this.classList.add('track');},get viewport(){return this.viewport_;},get drawingContainer(){var cur=this;while(cur){if(cur instanceof tr.ui.tracks.DrawingContainer)
+return cur;cur=cur.parentElement;}
+return undefined;},get eventContainer(){},invalidateDrawingContainer:function(){var dc=this.drawingContainer;if(dc)
+dc.invalidate();},context:function(){if(!this.parentNode)
+return undefined;if(!this.parentNode.context)
+throw new Error('Parent container does not support context() method.');return this.parentNode.context();},decorateChild_:function(childTrack){},undecorateChild_:function(childTrack){if(childTrack.detach)
+childTrack.detach();},updateContents_:function(){},drawTrack:function(type){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.draw(type,viewLWorld,viewRWorld);ctx.restore();},draw:function(type,viewLWorld,viewRWorld){},addEventsToTrackMap:function(eventToTrackMap){},addContainersToTrackMap:function(containerToTrackMap){},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loVY,hiVY,selection){var pixelRatio=window.devicePixelRatio||1;var dt=this.viewport.currentDisplayTransform;var viewPixWidthWorld=dt.xViewVectorToWorld(1);var loWX=dt.xViewToWorld(loVX*pixelRatio);var hiWX=dt.xViewToWorld(hiVX*pixelRatio);var clientRect=this.getBoundingClientRect();var a=Math.max(loVY,clientRect.top);var b=Math.min(hiVY,clientRect.bottom);if(a>b)
+return;this.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){},addClosestInstantEventToSelection:function(instantEvents,worldX,worldMaxDist,selection){var instantEvent=tr.b.findClosestElementInSortedArray(instantEvents,function(x){return x.start;},worldX,worldMaxDist);if(!instantEvent)
+return;selection.push(instantEvent);}};return{Track:Track};});'use strict';tr.exportTo('tr.ui.tracks',function(){var StackedBarsTrack=tr.ui.b.define('stacked-bars-track',tr.ui.tracks.Track);StackedBarsTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('stacked-bars-track');this.objectInstance_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},addEventsToTrackMap:function(eventToTrackMap){var objectSnapshots=this.objectInstance_.snapshots;objectSnapshots.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onSnapshot(snapshot){selection.push(snapshot);}
 var snapshots=this.objectInstance_.snapshots;var maxBounds=this.objectInstance_.parent.model.bounds.max;tr.b.iterateOverIntersectingIntervals(snapshots,function(x){return x.ts;},function(x,i){if(i==snapshots.length-1){if(snapshots.length==1)
 return maxBounds;return snapshots[i].ts-snapshots[i-1].ts;}
 return snapshots[i+1].ts-snapshots[i].ts;},loWX,hiWX,onSnapshot);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(!(event instanceof tr.model.ObjectSnapshot))
 throw new Error('Unrecognized event');var objectSnapshots=this.objectInstance_.snapshots;var index=objectSnapshots.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<objectSnapshots.length){selection.push(objectSnapshots[newIndex]);return true;}
 return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectInstance_.snapshots,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
-return;selection.push(snapshot);}};return{StackedBarsTrack:StackedBarsTrack};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var EventPresenter=tr.ui.b.EventPresenter;var statCount;var excludedStats={'meminfo':{'pswpin':0,'pswpout':0,'pgmajfault':0},'diskinfo':{'io':0,'io_time':0,'read_time':0,'reads':0,'reads_merged':0,'sectors_read':0,'sectors_written':0,'weighted_io_time':0,'write_time':0,'writes':0,'writes_merged':0},'swapinfo':{}};var SystemStatsInstanceTrack=tr.ui.b.define('tr-ui-e-system-stats-instance-track',tr.ui.tracks.StackedBarsTrack);SystemStatsInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate:function(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);this.classList.add('tr-ui-e-system-stats-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
+return;selection.push(snapshot);}};return{StackedBarsTrack:StackedBarsTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ObjectInstanceTrack=tr.ui.b.define('object-instance-track',tr.ui.tracks.Track);ObjectInstanceTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('object-instance-track');this.objectInstances_=[];this.objectSnapshots_=[];this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get objectInstances(){return this.objectInstances_;},set objectInstances(objectInstances){if(!objectInstances||objectInstances.length==0){this.heading='';this.objectInstances_=[];this.objectSnapshots_=[];return;}
+this.heading=objectInstances[0].typeName;this.objectInstances_=objectInstances;this.objectSnapshots_=[];this.objectInstances_.forEach(function(instance){this.objectSnapshots_.push.apply(this.objectSnapshots_,instance.snapshots);},this);this.objectSnapshots_.sort(function(a,b){return a.ts-b.ts;});},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get snapshotRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=dt.xViewVectorToWorld(height);var loI;ctx.save();dt.applyTransformToCanvas(ctx);var objectInstances=this.objectInstances_;var loI=tr.b.findLowIndexInSortedArray(objectInstances,function(instance){return instance.deletionTs;},viewLWorld);ctx.strokeStyle='rgb(0,0,0)';for(var i=loI;i<objectInstances.length;++i){var instance=objectInstances[i];var x=instance.creationTs;if(x>viewRWorld)
+break;var right=instance.deletionTs==Number.MAX_VALUE?viewRWorld:instance.deletionTs;ctx.fillStyle=EventPresenter.getObjectInstanceColor(instance);ctx.fillRect(x,pixelRatio,right-x,height-2*pixelRatio);}
+ctx.restore();var objectSnapshots=this.objectSnapshots_;loI=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts+snapshotRadiusWorld;},viewLWorld);for(var i=loI;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var x=snapshot.ts;if(x-snapshotRadiusWorld>viewRWorld)
+break;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getObjectSnapshotColor(snapshot);ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView,0,twoPi);ctx.fill();if(snapshot.selected){ctx.lineWidth=5;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView-1,0,twoPi);ctx.lineWidth=2;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}}
+ctx.lineWidth=1;var selectionState=SelectionState.NONE;if(objectInstances.length&&objectInstances[0].selectionState===SelectionState.DIMMED){selectionState=SelectionState.DIMMED;}
+if(selectionState===SelectionState.DIMMED){var width=bounds.width*pixelRatio;ctx.fillStyle='rgba(255,255,255,0.5)';ctx.fillRect(0,0,width,height);ctx.restore();}},addEventsToTrackMap:function(eventToTrackMap){if(this.objectInstance_!==undefined){this.objectInstance_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}
+if(this.objectSnapshots_!==undefined){this.objectSnapshots_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var foundSnapshot=false;function onSnapshot(snapshot){selection.push(snapshot);foundSnapshot=true;}
+var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=viewPixWidthWorld*snapshotRadiusView;tr.b.iterateOverIntersectingIntervals(this.objectSnapshots_,function(x){return x.ts-snapshotRadiusWorld;},function(x){return 2*snapshotRadiusWorld;},loWX,hiWX,onSnapshot);if(foundSnapshot)
+return;tr.b.iterateOverIntersectingIntervals(this.objectInstances_,function(x){return x.creationTs;},function(x){return x.deletionTs-x.creationTs;},loWX,hiWX,selection.push.bind(selection));},addEventNearToProvidedEventToSelection:function(event,offset,selection){var events;if(event instanceof tr.model.ObjectSnapshot)
+events=this.objectSnapshots_;else if(event instanceof tr.model.ObjectInstance)
+events=this.objectInstances_;else
+throw new Error('Unrecognized event');var index=events.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<events.length){selection.push(events[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectSnapshots_,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
+return;selection.push(snapshot);}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ObjectInstanceTrack,options);return{ObjectInstanceTrack:ObjectInstanceTrack};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var EventPresenter=tr.ui.b.EventPresenter;var statCount;var excludedStats={'meminfo':{'pswpin':0,'pswpout':0,'pgmajfault':0},'diskinfo':{'io':0,'io_time':0,'read_time':0,'reads':0,'reads_merged':0,'sectors_read':0,'sectors_written':0,'weighted_io_time':0,'write_time':0,'writes':0,'writes_merged':0},'swapinfo':{}};var SystemStatsInstanceTrack=tr.ui.b.define('tr-ui-e-system-stats-instance-track',tr.ui.tracks.StackedBarsTrack);SystemStatsInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate:function(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);this.classList.add('tr-ui-e-system-stats-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
 if(objectInstances.length!=1)
 throw new Error('Bad object instance count.');this.objectInstance_=objectInstances[0];if(this.objectInstance_!==null){this.computeRates_(this.objectInstance_.snapshots);this.maxStats_=this.computeMaxStats_(this.objectInstance_.snapshots);}},computeRates_:function(snapshots){for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();var prevSnapshot;var prevStats;if(i==0){prevSnapshot=snapshots[0];}else{prevSnapshot=snapshots[i-1];}
 prevStats=prevSnapshot.getStats();var timeIntervalSeconds=(snapshot.ts-prevSnapshot.ts)/1000;if(timeIntervalSeconds==0)
@@ -6962,141 +6501,1074 @@
 ctx.fillRect(leftView,currentY-barHeight,Math.max(rightView-leftView,1),barHeight);currentY+=height;}}
 return currentY;},drawStatNames_:function(leftView,height,currentY,prefix,maxStats){var ctx=this.context();ctx.textAlign='end';ctx.font='12px Arial';ctx.fillStyle='#000000';for(var statName in maxStats){if(maxStats[statName]instanceof Object){currentY=this.drawStatNames_(leftView,height,currentY,statName,maxStats[statName]);}else{var fullname=statName;if(prefix!='')
 fullname=prefix+' :: '+statName;ctx.fillText(fullname,leftView-10,currentY-height/4);currentY+=height;}}
-return currentY;}};tr.ui.tracks.ObjectInstanceTrack.register(SystemStatsInstanceTrack,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsInstanceTrack:SystemStatsInstanceTrack};});'use strict';tr.exportTo('tr.e.tcmalloc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function HeapSnapshot(){ObjectSnapshot.apply(this,arguments);}
-HeapSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){if(this.args.length==0)
-throw new Error('No heap snapshot data.');this.total_=this.args[0];var allocs=this.args.slice(1);this.heap_={children:{},currentBytes:0,currentAllocs:0,totalBytes:0,totalAllocs:0};for(var i=0;i<allocs.length;i++){var alloc=allocs[i];var traceNames=alloc.trace.split(' ');if(traceNames.indexOf('trace-memory-ignore')!=-1)
-continue;var heapEntry=this.heap_;for(var j=0;j<traceNames.length;j++){var traceName=traceNames[j];if(traceName.length!=0){heapEntry.currentBytes+=alloc.currentBytes;heapEntry.currentAllocs+=alloc.currentAllocs;heapEntry.totalBytes+=alloc.totalBytes;heapEntry.totalAllocs+=alloc.totalAllocs;}
-if(!heapEntry.children[traceName]){heapEntry.children[traceName]={children:{},currentBytes:alloc.currentBytes,currentAllocs:alloc.currentAllocs,totalBytes:alloc.totalBytes,totalAllocs:alloc.totalAllocs};}
-heapEntry=heapEntry.children[traceName];}}}};ObjectSnapshot.register(HeapSnapshot,{typeName:'memory::Heap'});return{HeapSnapshot:HeapSnapshot};});'use strict';tr.exportTo('tr.ui.e.tcmalloc',function(){var TcmallocInstanceView=tr.ui.b.define('tr-ui-e-tcmalloc-instance-view',tr.ui.analysis.ObjectInstanceView);TcmallocInstanceView.prototype={__proto__:tr.ui.analysis.ObjectInstanceView.prototype,decorate:function(){tr.ui.analysis.ObjectInstanceView.prototype.decorate.apply(this);this.classList.add('tr-ui-e-tcmalloc-instance-view');},updateContents:function(){var instance=this.objectInstance_;if(!instance||!instance.snapshots||instance.snapshots.length==0){this.textContent='No data found.';return;}
-this.textContent='';var snapshot=instance.snapshots[0];var heapEntry=snapshot.heap_;var traceNames=Object.keys(heapEntry.children);traceNames.sort(function(a,b){return heapEntry.children[b].currentBytes-
-heapEntry.children[a].currentBytes;});traceNames=traceNames.slice(0,5);var table=document.createElement('table');var titles=['Total'];titles=titles.concat(traceNames);table.appendChild(this.buildRow_(null,titles));var chartArrays=[[],[],[],[],[]];for(var i=0;i<instance.snapshots.length;i++){var snapshot=instance.snapshots[i];var rowData=[snapshot.total_.currentBytes];for(var j=0;j<5;j++){var bytes=snapshot.heap_.children[traceNames[j]].currentBytes;rowData.push(bytes);chartArrays[j].push([Math.round(snapshot.ts/1000),bytes/1024/1024]);}
-var row=this.buildRow_(snapshot,rowData);table.appendChild(row);}
-this.appendChild(table);},buildRow_:function(snapshot,items){var row=document.createElement('tr');var td=document.createElement('td');if(snapshot){var snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);td.appendChild(snapshotLink);}
-row.appendChild(td);for(var i=0;i<items.length;i++){var data=document.createElement('td');data.textContent=items[i];row.appendChild(data);}
-return row;},getByteString_:function(bytes){var mb=bytes/1024/1024;return mb.toFixed(1)+' MB';}};tr.ui.analysis.ObjectInstanceView.register(TcmallocInstanceView,{typeName:'memory::Heap'});return{TcmallocInstanceView:TcmallocInstanceView};});'use strict';tr.exportTo('tr.ui.e.tcmalloc',function(){var TcmallocSnapshotView=tr.ui.b.define('tr-ui-e-tcmalloc-heap-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TcmallocSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-tcmalloc-heap-snapshot-view');},updateContents:function(){var snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.heap_){this.textContent='No heap found.';return;}
-this.textContent='';var subhead=document.createElement('div');subhead.textContent='Retaining '+
-this.getByteString_(snapshot.total_.currentBytes)+' in '+
-snapshot.total_.currentAllocs+' allocations. Showing > 0.1 MB.';subhead.className='subhead';this.appendChild(subhead);var myList=this.buildAllocList_(snapshot.heap_,false);this.appendChild(myList);},buildAllocList_:function(heapEntry,hide){var myList=document.createElement('ul');myList.hidden=hide;var keys=Object.keys(heapEntry.children);keys.sort(function(a,b){return heapEntry.children[b].currentBytes-
-heapEntry.children[a].currentBytes;});for(var i=0;i<keys.length;i++){var traceName=keys[i];var trace=heapEntry.children[traceName];if(trace.currentBytes<100*1024)
-continue;var childCount=Object.keys(trace.children).length;var isLeaf=childCount==0;var myItem=this.buildItem_(traceName,isLeaf,trace.currentBytes,trace.currentAllocs);myList.appendChild(myItem);if(childCount>0)
-myItem.appendChild(this.buildAllocList_(trace,true));}
-return myList;},buildItem_:function(traceName,isLeaf,bytes,allocs){var myItem=document.createElement('li');myItem.className='trace-item';myItem.id=traceName;var byteDiv=document.createElement('div');byteDiv.textContent=this.getByteString_(bytes);byteDiv.className='trace-bytes';myItem.appendChild(byteDiv);if(traceName.length==0){traceName='(here)';}else if(traceName.indexOf('..')==0){var lastSlash=traceName.lastIndexOf('/');if(lastSlash!=-1)
-traceName='Task from '+traceName.substr(lastSlash+1);}
-var traceDiv=document.createElement('div');traceDiv.textContent=traceName;traceDiv.className='trace-name';myItem.appendChild(traceDiv);if(isLeaf)
-return myItem;var self=this;myItem.addEventListener('click',function(event){if(this==event.target||this==event.target.parentElement){this.classList.toggle('expanded');var child=this.querySelector('ul');child.hidden=!child.hidden;self.onItemClicked_(this);}});myItem.classList.add('collapsed');return myItem;},onItemClicked_:function(traceItem){var traces=[];while(traceItem.classList.contains('trace-item')){var traceNameDiv=traceItem.firstElementChild.nextElementSibling;traces.unshift(traceNameDiv.textContent);var traceNameUl=traceItem.parentElement;traceItem=traceNameUl.parentElement;}
-var instance=this.objectSnapshot_.objectInstance;instance.selectedTraces=traces;var trackView=document.querySelector('.timeline-track-view');trackView.viewport_.dispatchChangeEvent();},getByteString_:function(bytes){var mb=bytes/1024/1024;return mb.toFixed(1)+' MB';}};tr.ui.analysis.ObjectSnapshotView.register(TcmallocSnapshotView,{typeName:'memory::Heap'});return{TcmallocSnapshotView:TcmallocSnapshotView};});'use strict';tr.exportTo('tr.ui.e.tcmalloc',function(){var EventPresenter=tr.ui.b.EventPresenter;var HeapInstanceTrack=tr.ui.b.define('tr-ui-e-tcmalloc-heap-instance-track',tr.ui.tracks.StackedBarsTrack);HeapInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate:function(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);this.classList.add('tr-ui-e-tcmalloc-heap-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
-if(objectInstances.length!=1)
-throw new Error('Bad object instance count.');this.objectInstance_=objectInstances[0];this.maxBytes_=this.computeMaxBytes_(this.objectInstance_.snapshots);},computeMaxBytes_:function(snapshots){var maxBytes=0;for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var traceNames=Object.keys(snapshot.heap_.children);var sumBytes=0;for(var j=0;j<traceNames.length;j++){sumBytes+=snapshot.heap_.children[traceNames[j]].currentBytes;}
-if(sumBytes>maxBytes)
-maxBytes=sumBytes;}
-return maxBytes;},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawEvents_(viewLWorld,viewRWorld);break;}},drawEvents_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var width=bounds.width*pixelRatio;var height=bounds.height*pixelRatio;var dt=this.viewport.currentDisplayTransform;var maxBytes=this.maxBytes_;var objectSnapshots=this.objectInstance_.snapshots;var lowIndex=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)
-lowIndex-=1;for(var i=lowIndex;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var left=snapshot.ts;if(left>viewRWorld)
-break;var leftView=dt.xWorldToView(left);if(leftView<0)
-leftView=0;var right;if(i!=objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1)
-right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
-objectSnapshots[i-1].ts);else
-right=this.objectInstance_.parent.model.bounds.max;}
-var rightView=dt.xWorldToView(right);if(rightView>width)
-rightView=width;leftView=Math.floor(leftView);rightView=Math.floor(rightView);var currentY=height;var keys=Object.keys(snapshot.heap_.children);for(var k=keys.length-1;k>=0;k--){var trace=snapshot.heap_.children[keys[k]];if(this.objectInstance_.selectedTraces&&this.objectInstance_.selectedTraces.length>0&&this.objectInstance_.selectedTraces[0]==keys[k]){ctx.fillStyle='rgb(239, 248, 206)';}else
-ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,k);var barHeight=height*trace.currentBytes/maxBytes;ctx.fillRect(leftView,currentY-barHeight,Math.max(rightView-leftView,1),barHeight);currentY-=barHeight;}}
-ctx.lineWidth=1;}};tr.ui.tracks.ObjectInstanceTrack.register(HeapInstanceTrack,{typeName:'memory::Heap'});return{HeapInstanceTrack:HeapInstanceTrack};});'use strict';Polymer('tr-ui-e-s-category-summary-side-panel',{ready:function(){},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get listeningToKeys(){return false;},set selection(selection){},set rangeOfInterest(rangeOfInterest){},updateContents_:function(){this.$.table.tableColumns=[{title:'Category / Title',value:function(row){return row.title;}},{title:'Events',textAlign:'right',value:function(row){return row.count;}}];if(this.model_===undefined){this.$.table.tableRows=[];return;}
-var categories={};this.model_.iterateAllEvents(function handleEvent(event){if(!(event instanceof tr.model.Slice)&&!(event instanceof tr.model.AsyncSlice)&&!(event instanceof tr.model.InstantEvent)&&!(event instanceof tr.model.FlowEvent))
-return;tr.b.getCategoryParts(event.category).forEach(function(category){if(categories[category]===undefined){categories[category]={};}
-var titleCounts=categories[category];if(titleCounts[event.title]===undefined){titleCounts[event.title]=0;}
-titleCounts[event.title]+=1;});});function compareCounts(a,b){return b.count-a.count;}
-var rows=[];for(var category in categories){var categoryRow={title:category,subRows:[],count:0};rows.push(categoryRow);var titleCounts=categories[category];for(var title in titleCounts){var count=titleCounts[title];categoryRow.count+=count;categoryRow.subRows.push({title:title,count:count});}
-categoryRow.subRows.sort(compareCounts);}
-rows.sort(compareCounts);this.$.table.tableRows=rows;},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}
-return{supported:true};},get textLabel(){return'Categories';}});'use strict';Polymer('tr-ui-e-s-input-latency-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.frametimeType_=tr.e.audits.IMPL_FRAMETIME_TYPE;this.latencyChart_=undefined;this.frametimeChart_=undefined;this.selectedProcessId_=undefined;this.mouseDownIndex_=undefined;this.curMouseIndex_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;if(this.model_)
-this.modelHelper_=new tr.e.audits.ChromeModelHelper(model);else
-this.modelHelper_=undefined;this.updateToolbar_();this.updateContents_();},get frametimeType(){return this.frametimeType_;},set frametimeType(type){if(this.frametimeType_===type)
-return;this.frametimeType_=type;this.updateContents_();},get selectedProcessId(){return this.selectedProcessId_;},set selectedProcessId(process){if(this.selectedProcessId_===process)
-return;this.selectedProcessId_=process;this.updateContents_();},set selection(selection){if(this.latencyChart_===undefined)
-return;this.latencyChart_.brushedRange=selection.bounds;},setBrushedIndices:function(mouseDownIndex,curIndex){this.mouseDownIndex_=mouseDownIndex;this.curMouseIndex_=curIndex;this.updateBrushedRange_();},updateBrushedRange_:function(){if(this.latencyChart_===undefined)
-return;var r=new tr.b.Range();if(this.mouseDownIndex_===undefined){this.latencyChart_.brushedRange=r;return;}
-r=this.latencyChart_.computeBrushRangeFromIndices(this.mouseDownIndex_,this.curMouseIndex_);this.latencyChart_.brushedRange=r;var latencySlices=[];this.model_.getAllThreads().forEach(function(thread){thread.iterateAllEvents(function(event){if(event.title.indexOf('InputLatency:')===0)
-latencySlices.push(event);});});latencySlices=tr.e.audits.getSlicesIntersectingRange(r,latencySlices);var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(latencySlices);this.latencyChart_.dispatchEvent(event);},registerMouseEventForLatencyChart_:function(){this.latencyChart_.addEventListener('item-mousedown',function(e){this.mouseDownIndex_=e.index;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mousemove',function(e){if(e.button==undefined)
-return;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mouseup',function(e){this.curMouseIndex=e.index;this.updateBrushedRange_();}.bind(this));},updateToolbar_:function(){var browserProcess=this.modelHelper_.browserProcess;var labels=[];if(browserProcess!==undefined){var label_str='Browser: '+browserProcess.pid;labels.push({label:label_str,value:browserProcess.pid});}
-tr.b.iterItems(this.modelHelper_.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;var label_str='Renderer: '+rendererProcess.userFriendlyName;labels.push({label:label_str,value:rendererProcess.userFriendlyName});},this);if(labels.length===0)
-return;this.selectedProcessId_=labels[0].value;var toolbarEl=this.$.toolbar;toolbarEl.appendChild(tr.ui.b.createSelector(this,'frametimeType','inputLatencySidePanel.frametimeType',this.frametimeType_,[{label:'Main Thread Frame Times',value:tr.e.audits.MAIN_FRAMETIME_TYPE},{label:'Impl Thread Frame Times',value:tr.e.audits.IMPL_FRAMETIME_TYPE}]));toolbarEl.appendChild(tr.ui.b.createSelector(this,'selectedProcessId','inputLatencySidePanel.selectedProcessId',this.selectedProcessId_,labels));},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty)
-return this.model_.bounds;else
-return this.rangeOfInterest_;},createLatencyLineChart:function(data,title){var chart=new tr.ui.b.LineChart();var width=600;if(document.body.clientWidth!=undefined)
-width=document.body.clientWidth*0.5;chart.setSize({width:width,height:chart.height});chart.chartTitle=title;chart.data=data;return chart;},updateContents_:function(){var resultArea=this.$.result_area;this.latencyChart_=undefined;this.frametimeChart_=undefined;resultArea.textContent='';if(this.modelHelper_===undefined)
-return;var rangeOfInterest=this.currentRangeOfInterest;var chromeProcess;if(this.modelHelper_.rendererHelpers[this.selectedProcessId_])
-chromeProcess=this.modelHelper_.rendererHelpers[this.selectedProcessId_];else
-chromeProcess=this.modelHelper_.browserHelper;var frameEvents=chromeProcess.getFrameEventsInRange(this.frametimeType,rangeOfInterest);var frametimeData=tr.e.audits.getFrametimeDataFromEvents(frameEvents);var averageFrametime=tr.b.Statistics.mean(frametimeData,function(d){return d.frametime;});var latencyEvents=this.modelHelper_.browserHelper.getLatencyEventsInRange(rangeOfInterest);var latencyData=[];latencyEvents.forEach(function(event){if(event.inputLatency===undefined)
-return;latencyData.push({x:event.start,latency:event.inputLatency/1000});});var averageLatency=tr.b.Statistics.mean(latencyData,function(d){return d.latency;});var latencySummaryText=document.createElement('div');latencySummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Latency '+averageLatency+' ms',bold:true}));resultArea.appendChild(latencySummaryText);var frametimeSummaryText=document.createElement('div');frametimeSummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Frame Time '+averageFrametime+' ms',bold:true}));resultArea.appendChild(frametimeSummaryText);if(latencyData.length!==0){this.latencyChart_=this.createLatencyLineChart(latencyData,'Latency Over Time');this.registerMouseEventForLatencyChart_();resultArea.appendChild(this.latencyChart_);}
-if(frametimeData.length!=0){this.frametimeChart_=this.createLatencyLineChart(frametimeData,'Frame Times');this.frametimeChart_.style.display='block';resultArea.appendChild(this.frametimeChart_);}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}
-if(!tr.e.audits.ChromeModelHelper.supportsModel(m)){return{supported:false,reason:'No Chrome browser or renderer process found'};}
-var modelHelper=new tr.e.audits.ChromeModelHelper(m);if(modelHelper.browserHelper&&modelHelper.browserHelper.hasLatencyEvents){return{supported:true};}
-return{supported:false,reason:'No InputLatency events trace. Consider enabling '+'benchmark" and "input" category when recording the trace'};},get textLabel(){return'Input Latency';}});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var getColorOfKey=tr.ui.b.getColorOfKey;var MIN_RADIUS=100;var PieChart=tr.ui.b.define('pie-chart',ChartBase);PieChart.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('pie-chart');this.data_=undefined;this.seriesKeys_=undefined;var chartAreaSel=d3.select(this.chartAreaElement);var pieGroupSel=chartAreaSel.append('g').attr('class','pie-group');this.pieGroup_=pieGroupSel.node();this.pathsGroup_=pieGroupSel.append('g').attr('class','paths').node();this.labelsGroup_=pieGroupSel.append('g').attr('class','labels').node();this.linesGroup_=pieGroupSel.append('g').attr('class','lines').node();},get data(){return this.data_;},set data(data){if(data!==undefined){var seriesKeys=[];var seenSeriesKeys={};data.forEach(function(d){var k=d.label;if(seenSeriesKeys[k])
-throw new Error('Label '+k+' has been used already');seriesKeys.push(k);seenSeriesKeys[k]=true;},this);this.seriesKeys_=seriesKeys;}else{this.seriesKeys_=undefined;}
-this.data_=data;this.updateContents_();},get margin(){var margin={top:0,right:0,bottom:0,left:0};if(this.chartTitle_)
-margin.top+=40;return margin;},getMinSize:function(){this.updateContents_();var labelSel=d3.select(this.labelsGroup_).selectAll('.label');var maxLabelWidth=-Number.MAX_VALUE;var leftTextHeightSum=0;var rightTextHeightSum=0;labelSel.each(function(l){var r=this.getBoundingClientRect();maxLabelWidth=Math.max(maxLabelWidth,r.width+32);if(this.style.textAnchor=='end'){leftTextHeightSum+=r.height;}else{rightTextHeightSum+=r.height;}});var titleWidth=this.querySelector('#title').getBoundingClientRect().width;var margin=this.margin;var marginWidth=margin.left+margin.right;var marginHeight=margin.top+margin.bottom;return{width:Math.max(2*MIN_RADIUS+2*maxLabelWidth,titleWidth*1.1)+marginWidth,height:marginHeight+Math.max(2*MIN_RADIUS,leftTextHeightSum,rightTextHeightSum)*1.25};},getLegendKeys_:function(){return undefined;},updateScales_:function(width,height){if(this.data_===undefined)
-return;},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);if(!this.data_)
-return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;var radius=Math.max(MIN_RADIUS,Math.min(width,height*0.95)/2);d3.select(this.pieGroup_).attr('transform','translate('+width/2+','+height/2+')');var pieLayout=d3.layout.pie().value(function(d){return d.value;}).sort(null);var piePathsSel=d3.select(this.pathsGroup_).datum(this.data_).selectAll('path').data(pieLayout);function midAngle(d){return d.startAngle+(d.endAngle-d.startAngle)/2;}
-var pathsArc=d3.svg.arc().innerRadius(0).outerRadius(radius-30);var valueLabelArc=d3.svg.arc().innerRadius(radius-100).outerRadius(radius-30);var lineBeginArc=d3.svg.arc().innerRadius(radius-50).outerRadius(radius-50);var lineEndArc=d3.svg.arc().innerRadius(radius).outerRadius(radius);piePathsSel.enter().append('path').attr('class','arc').attr('fill',function(d,i){var origData=this.data_[i];var highlighted=(origData.label===this.currentHighlightedLegendKey);return getColorOfKey(origData.label,highlighted);}.bind(this)).attr('d',pathsArc).on('click',function(d,i){var origData=this.data_[i];var event=new tr.b.Event('item-click');event.data=origData;event.index=i;this.dispatchEvent(event);d3.event.stopPropagation();}.bind(this)).on('mouseenter',function(d,i){var origData=this.data_[i];this.pushTempHighlightedLegendKey(origData.label);}.bind(this)).on('mouseleave',function(d,i){var origData=this.data_[i];this.popTempHighlightedLegendKey(origData.label);}.bind(this));piePathsSel.enter().append('text').attr('class','arc-text').attr('transform',function(d){return'translate('+valueLabelArc.centroid(d)+')';}).attr('dy','.35em').style('text-anchor','middle').text(function(d,i){var origData=this.data_[i];if(origData.valueText===undefined)
-return'';if(d.endAngle-d.startAngle<0.4)
-return'';return origData.valueText;}.bind(this));piePathsSel.exit().remove();var labelSel=d3.select(this.labelsGroup_).selectAll('.label').data(pieLayout(this.data_));labelSel.enter().append('text').attr('class','label').attr('dy','.35em');labelSel.text(function(d){if(d.data.label.length>40)
-return d.data.label.substr(0,40)+'...';return d.data.label;});labelSel.attr('transform',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*(midAngle(d)<Math.PI?1:-1);return'translate('+pos+')';});labelSel.style('text-anchor',function(d){return midAngle(d)<Math.PI?'start':'end';});var lineSel=d3.select(this.linesGroup_).selectAll('.line').data(pieLayout(this.data_));lineSel.enter().append('polyline').attr('class','line').attr('dy','.35em');lineSel.attr('points',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*0.95*(midAngle(d)<Math.PI?1:-1);return[lineBeginArc.centroid(d),lineEndArc.centroid(d),pos];});},updateHighlight_:function(){ChartBase.prototype.updateHighlight_.call(this);var pathsGroupSel=d3.select(this.pathsGroup_);var that=this;pathsGroupSel.selectAll('.arc').each(function(d,i){var origData=that.data_[i];var highlighted=origData.label==that.currentHighlightedLegendKey;var color=getColorOfKey(origData.label,highlighted);this.style.fill=color;});}};return{PieChart:PieChart};});'use strict';(function(){var GROUP_BY_PROCESS_NAME='process';var GROUP_BY_THREAD_NAME='thread';var WALL_TIME_GROUPING_UNIT='Wall time';var CPU_TIME_GROUPING_UNIT='CPU time';function ResultsForGroup(model,name){this.model=model;this.name=name;this.topLevelSlices=[];this.allSlices=[];}
-ResultsForGroup.prototype={get wallTime(){var wallSum=tr.b.Statistics.sum(this.topLevelSlices,function(x){return x.duration;});return wallSum;},get cpuTime(){var cpuDuration=0;for(var i=0;i<this.topLevelSlices.length;i++){var x=this.topLevelSlices[i];if(x.cpuDuration===undefined){if(x.duration===undefined)
-continue;return 0;}
-cpuDuration+=x.cpuDuration;}
-return cpuDuration;},appendGroupContents:function(group){if(group.model!=this.model)
-throw new Error('Models must be the same');group.allSlices.forEach(function(slice){this.allSlices.push(slice);},this);group.topLevelSlices.forEach(function(slice){this.topLevelSlices.push(slice);},this);},appendThreadSlices:function(rangeOfInterest,thread){var tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.slices);tmp.forEach(function(slice){this.allSlices.push(slice);},this);tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.topLevelSlices);tmp.forEach(function(slice){this.topLevelSlices.push(slice);},this);},getSlicesIntersectingRange:function(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRange(slice.start,slice.end))
-slicesInFilterRange.push(slice);}
-return slicesInFilterRange;}};Polymer('tr-ui-e-s-time-summary-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;this.groupBy_=GROUP_BY_PROCESS_NAME;this.groupingUnit_=CPU_TIME_GROUPING_UNIT;this.showCpuIdleTime_=true;this.chart_=undefined;var toolbarEl=this.$.toolbar;this.groupBySelector_=tr.ui.b.createSelector(this,'groupBy','timeSummarySidePanel.groupBy',this.groupBy_,[{label:'Group by process',value:GROUP_BY_PROCESS_NAME},{label:'Group by thread',value:GROUP_BY_THREAD_NAME}]);toolbarEl.appendChild(this.groupBySelector_);this.groupingUnitSelector_=tr.ui.b.createSelector(this,'groupingUnit','timeSummarySidePanel.groupingUnit',this.groupingUnit_,[{label:'Wall time',value:WALL_TIME_GROUPING_UNIT},{label:'CPU time',value:CPU_TIME_GROUPING_UNIT}]);toolbarEl.appendChild(this.groupingUnitSelector_);this.showCpuIdleTimeCheckbox_=tr.ui.b.createCheckBox(this,'showCpuIdleTime','timeSummarySidePanel.showCpuIdleTime',this.showCpuIdleTime_,'Show CPU idle time');toolbarEl.appendChild(this.showCpuIdleTimeCheckbox_);this.updateShowCpuIdleTimeCheckboxVisibility_();},trimPieChartData:function(groups,otherGroup,getValue,opt_extraValue){groups=groups.filter(function(d){return getValue(d)!=0;});var sum=tr.b.Statistics.sum(groups,getValue);if(opt_extraValue!==undefined)
-sum+=opt_extraValue;function compareByValue(a,b){return getValue(a)-getValue(b);}
-groups.sort(compareByValue);var thresshold=0.1*sum;while(groups.length>1){var group=groups[0];if(getValue(group)>=thresshold)
-break;var v=getValue(group);if(v+getValue(otherGroup)>thresshold)
-break;groups.splice(0,1);otherGroup.appendGroupContents(group);}
-if(getValue(otherGroup)>0)
-groups.push(otherGroup);groups.sort(compareByValue);return groups;},generateResultsForGroup:function(model,name){return new ResultsForGroup(model,name);},createPieChartFromResultGroups:function(groups,title,getValue,opt_extraData){var chart=new tr.ui.b.PieChart();function pushDataForGroup(data,resultsForGroup,value){data.push({label:resultsForGroup.name,value:value,valueText:tr.b.u.TimeDuration.format(value),resultsForGroup:resultsForGroup});}
-chart.addEventListener('item-click',function(clickEvent){var resultsForGroup=clickEvent.data.resultsForGroup;if(resultsForGroup===undefined)
-return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(resultsForGroup.allSlices);event.selection.timeSummaryGroupName=resultsForGroup.name;chart.dispatchEvent(event);});var data=[];groups.forEach(function(resultsForGroup){var value=getValue(resultsForGroup);if(value===0)
-return;pushDataForGroup(data,resultsForGroup,value);});if(opt_extraData)
-data.push.apply(data,opt_extraData);chart.chartTitle=title;chart.data=data;return chart;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get listeningToKeys(){return false;},get groupBy(){return groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;if(this.groupBySelector_)
-this.groupBySelector_.selectedValue=groupBy;this.updateContents_();},get groupingUnit(){return groupingUnit_;},set groupingUnit(groupingUnit){this.groupingUnit_=groupingUnit;if(this.groupingUnitSelector_)
-this.groupingUnitSelector_.selectedValue=groupingUnit;this.updateShowCpuIdleTimeCheckboxVisibility_();this.updateContents_();},get showCpuIdleTime(){return this.showCpuIdleTime_;},set showCpuIdleTime(showCpuIdleTime){this.showCpuIdleTime_=showCpuIdleTime;if(this.showCpuIdleTimeCheckbox_)
-this.showCpuIdleTimeCheckbox_.checked=showCpuIdleTime;this.updateContents_();},updateShowCpuIdleTimeCheckboxVisibility_:function(){if(!this.showCpuIdleTimeCheckbox_)
-return;var visible=this.groupingUnit_==CPU_TIME_GROUPING_UNIT;if(visible)
-this.showCpuIdleTimeCheckbox_.style.display='';else
-this.showCpuIdleTimeCheckbox_.style.display='none';},getGroupNameForThread_:function(thread){if(this.groupBy_==GROUP_BY_THREAD_NAME)
-return thread.name?thread.name:thread.userFriendlyName;if(this.groupBy_==GROUP_BY_PROCESS_NAME)
-return thread.parent.userFriendlyName;},updateContents_:function(){var resultArea=this.$.result_area;this.chart_=undefined;resultArea.textContent='';if(this.model_===undefined)
-return;var rangeOfInterest;if(this.rangeOfInterest_.isEmpty)
-rangeOfInterest=this.model_.bounds;else
-rangeOfInterest=this.rangeOfInterest_;var allGroup=this.generateResultsForGroup(this.model_,'all');var resultsByGroupName={};this.model_.getAllThreads().forEach(function(thread){var groupName=this.getGroupNameForThread_(thread);if(resultsByGroupName[groupName]===undefined){resultsByGroupName[groupName]=this.generateResultsForGroup(this.model_,groupName);}
-resultsByGroupName[groupName].appendThreadSlices(rangeOfInterest,thread);allGroup.appendThreadSlices(rangeOfInterest,thread);},this);var getValueFromGroup=function(group){if(this.groupingUnit_==WALL_TIME_GROUPING_UNIT)
-return group.wallTime;return group.cpuTime;}.bind(this);var summaryText=document.createElement('div');summaryText.appendChild(tr.ui.b.createSpan({textContent:'Total '+this.groupingUnit_+': ',bold:true}));summaryText.appendChild(tr.ui.units.createTimeDurationSpan(getValueFromGroup(allGroup),{ownerDocument:this.ownerDocument}));resultArea.appendChild(summaryText);var extraValue=0;var extraData=[];if(this.showCpuIdleTime_&&this.groupingUnit_===CPU_TIME_GROUPING_UNIT&&this.model.kernel.bestGuessAtCpuCount!==undefined){var maxCpuTime=rangeOfInterest.range*this.model.kernel.bestGuessAtCpuCount;var idleTime=Math.max(0,maxCpuTime-allGroup.cpuTime);extraData.push({label:'CPU Idle',value:idleTime,valueText:tr.b.u.TimeDuration.format(idleTime)});extraValue+=idleTime;}
-var otherGroup=this.generateResultsForGroup(this.model_,'Other');var groups=this.trimPieChartData(tr.b.dictionaryValues(resultsByGroupName),otherGroup,getValueFromGroup,extraValue);if(groups.length==0){resultArea.appendChild(tr.ui.b.createSpan({textContent:'No data'}));return undefined;}
-this.chart_=this.createPieChartFromResultGroups(groups,this.groupingUnit_+' breakdown by '+this.groupBy_,getValueFromGroup,extraData);resultArea.appendChild(this.chart_);this.chart_.addEventListener('click',function(){var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.c.EventSet([]);this.dispatchEvent(event);});this.chart_.setSize(this.chart_.getMinSize());},get selection(){return selection_;},set selection(selection){this.selection_=selection;if(this.chart_===undefined)
-return;if(selection.timeSummaryGroupName)
-this.chart_.highlightedLegendKey=selection.timeSummaryGroupName;else
-this.chart_.highlightedLegendKey=undefined;},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(model){return{supported:false};},get textLabel(){return'Time Summary';}});}());'use strict';tr.exportTo('tr.e.rail',function(){function RAILScore(opt_irs){this.interactionRecords_=[];if(opt_irs)
-this.interactionRecords_.push.apply(this.interactionRecords_,opt_irs);};RAILScore.prototype={get interactionRecords(){return this.interactionRecords_;},get overallScore(){if(!this.interactionRecords.length)
-return undefined;var numerator=0;var denominator=0;this.interactionRecords.forEach(function(ir){var score=ir.railScore;var scale=ir.railScoreScale;if(scale===undefined)
-scale=3;var power=ir.railScorePower;if(power===undefined)
-power=0.3;var base=ir.railScoreBase;if(base===undefined)
-base=Math.exp(1);var weight=Math.pow(base,-scale*Math.pow(score,power));numerator+=score*weight;denominator+=weight;});return numerator/denominator;},asDict:function(){return{overallScore:this.overallScore};}};RAILScore.fromModel=function(model){var rirs=model.interactionRecords.filter(function(ir){return ir instanceof tr.e.rail.RAILInteractionRecord;});if(rirs.length===0)
-return undefined;return new RAILScore(rirs);};return{RAILScore:RAILScore};});'use strict';Polymer('tr-ui-e-rail-rail-score-span',{created:function(){this.railScore_=undefined;},ready:function(){this.updateContent_();},get railScore(){return this.railScore_;},set railScore(railScore){this.railScore_=railScore;this.updateContent_();},updateContent_:function(){if(this.railScore_===undefined){this.$.content.style.display='none';return;}
-this.$.content.style.display='';var overallScore=this.railScore_.overallScore;if(overallScore===undefined)
-return;this.$.score.textContent=overallScore.toLocaleString(undefined,{minimumFractionDigits:3});}});'use strict';(function(){function setCoverageLink(link,labelString,events,eventRatio,cpuMs,cpuRatio){link.setSelectionAndContent(events);labelString+=' '+events.length+' events';labelString+=' ('+parseInt(100*eventRatio)+'%)';if(cpuRatio!==undefined)
-labelString+=', ';link.appendChild(document.createTextNode(labelString));if(cpuRatio===undefined)
-return;var cpuMsSpan=document.createElement('tr-ui-u-time-duration-span');cpuMsSpan.style.display='inline';cpuMsSpan.duration=cpuMs;cpuMsSpan.contentTextDecoration='underline';link.appendChild(cpuMsSpan);var cpuString=' ('+parseInt(100*cpuRatio)+'%)';link.appendChild(document.createTextNode(cpuString));}
-Polymer('tr-ui-e-rail-rail-score-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.model_=undefined;this.railScore_=undefined;this.selection_=new tr.model.EventSet();this.$.test.addEventListener('click',this.createTest_.bind(this));},createTest_:function(){var overlay=new tr.ui.b.Overlay();overlay.title='RAILIRFinder test';var textarea=document.createElement('textarea');textarea.textContent=tr.e.rail.createIRFinderTestCaseStringFromModel(this.model_);textarea.rows=textarea.textContent.split('\n').length;textarea.cols=80;overlay.appendChild(textarea);overlay.visible=true;textarea.select();textarea.focus();},get textLabel(){return'RAIL Info';},supportsModel:function(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}
-var railScore=tr.e.rail.RAILScore.fromModel(m);if(railScore===undefined){return{supported:false,reason:'RAIL interactions were not found on the model'};}
-return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.railScore_=tr.e.rail.RAILScore.fromModel(model);this.$.score.railScore=this.railScore_;var coverage=tr.model.getIRCoverageFromModel(model);if(coverage){var associatedEvents=tr.model.getAssociatedEvents(model.interactionRecords);setCoverageLink(this.shadowRoot.querySelector('#associated-events'),'Associated',associatedEvents,coverage.coveredEventsCountRatio,coverage.associatedEventsCpuTimeMs,coverage.coveredEventsCpuTimeRatio);setCoverageLink(this.shadowRoot.querySelector('#unassociated-events'),'Unassociated',tr.model.getUnassociatedEvents(model,associatedEvents),1.0-coverage.coveredEventsCountRatio,coverage.unassociatedEventsCpuTimeMs,1.0-coverage.coveredEventsCpuTimeRatio);}
-this.updateTable_();},get listeningToKeys(){return false;},set rangeOfInterest(rangeOfInterest){},updateTable_:function(){function toThreeDigitLocaleString(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}
-var columns=[{title:'Type',width:'150px',value:function(ir){var el=document.createElement('tr-ui-b-color-legend');var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([ir]),ir.railTypeName);el.setLabelAndColorId(linkEl,ir.colorId);el.compoundEventSelectionState=ir.computeCompoundEvenSelectionState(this.selection_);return el;}.bind(this),cmp:function(a,b){return a.railTypeName.localeCompare(b.railTypeName);}},{title:'Efficiency',width:'33%',value:function(ir){return toThreeDigitLocaleString(ir.normalizedEfficiency);},textAlign:'right',cmp:function(a,b){return a.normalizedEfficiency-b.normalizedEfficiency;}},{title:'Comfort',width:'33%',value:function(ir){return toThreeDigitLocaleString(ir.normalizedUserComfort);},textAlign:'right',cmp:function(a,b){return a.normalizedUserComfort-b.normalizedUserComfort;}},{title:'Score',width:'33%',value:function(ir){var span=document.createElement('span');span.style.fontWeight='bold';span.textContent=toThreeDigitLocaleString(ir.railScore);return span;},textAlign:'right',cmp:function(a,b){return a.railScore-b.railScore;}}];this.$.table.tableColumns=columns;if(this.railScore_)
-this.$.table.tableRows=this.railScore_.interactionRecords;else
-this.$.table.tableRows=[];this.$.table.rebuild();},onTableSelectionChanged_:function(){var selectedIR=this.$.table.selectedTableRow;var event=new tr.c.RequestSelectionChangeEvent();event.selection=new tr.c.Selection([selectedIR]);this.dispatchEvent(event);},set selection(selection){if(selection===undefined)
-selection=new tr.model.EventSet();if(this.selection_.equals(selection))
-return;this.selection_=selection;this.updateTable_();}});})();'use strict';Polymer('tr-ui-e-s-alerts-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get listeningToKeys(){return false;},set selection(selection){},set rangeOfInterest(rangeOfInterest){},selectAlertsOfType:function(alertTypeString){var alertsOfType=this.model_.alerts.filter(function(alert){return alert.title===alertTypeString;});var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(alertsOfType);this.dispatchEvent(event);},alertsByType_:function(alerts){var alertsByType={};alerts.forEach(function(alert){if(!alertsByType[alert.title])
-alertsByType[alert.title]=[];alertsByType[alert.title].push(alert);});return alertsByType;},alertsTableRows_:function(alertsByType){return Object.keys(alertsByType).map(function(key){return{alertType:key,count:alertsByType[key].length};});},alertsTableColumns_:function(){return[{title:'Alert type',value:function(row){return row.alertType;},width:'180px'},{title:'Count',width:'100%',value:function(row){return row.count;}}];},createAlertsTable_:function(alerts){var alertsByType=this.alertsByType_(alerts);var table=document.createElement('tr-ui-b-table');table.tableColumns=this.alertsTableColumns_();table.tableRows=this.alertsTableRows_(alertsByType);table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.addEventListener('selection-changed',function(e){var row=table.selectedTableRow;if(row)
-this.selectAlertsOfType(row.alertType);}.bind(this));return table;},updateContents_:function(){this.$.result_area.textContent='';if(this.model_===undefined)
-return;var panel=this.createAlertsTable_(this.model_.alerts);this.$.result_area.appendChild(panel);},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}else if(m.alerts.length===0){return{supported:false,reason:'No alerts in tracing model'};}
-return{supported:true};},get textLabel(){return'Alerts';}});'use strict';tr.exportTo('tr.ui.e.highlighter',function(){var Highlighter=tr.ui.tracks.Highlighter;function VSyncHighlighter(viewport){Highlighter.call(this,viewport);this.times_=[];}
+return currentY;}};tr.ui.tracks.ObjectInstanceTrack.register(SystemStatsInstanceTrack,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsInstanceTrack:SystemStatsInstanceTrack};});'use strict';tr.exportTo('tr.c',function(){function ScriptingObject(){}
+ScriptingObject.prototype={onModelChanged:function(model){}};return{ScriptingObject:ScriptingObject};});'use strict';tr.exportTo('tr.c',function(){function ScriptingController(brushingStateController){this.brushingStateController_=brushingStateController;this.scriptObjectNames_=[];this.scriptObjectValues_=[];this.brushingStateController.addEventListener('model-changed',this.onModelChanged_.bind(this));var typeInfos=ScriptingObjectRegistry.getAllRegisteredTypeInfos();typeInfos.forEach(function(typeInfo){this.addScriptObject(typeInfo.metadata.name,typeInfo.constructor);global[typeInfo.metadata.name]=typeInfo.constructor;},this);}
+function ScriptingObjectRegistry(){}
+var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ScriptingObjectRegistry,options);ScriptingController.prototype={get brushingStateController(){return this.brushingStateController_;},onModelChanged_:function(){this.scriptObjectValues_.forEach(function(v){if(v.onModelChanged)
+v.onModelChanged(this.brushingStateController.model);},this);},addScriptObject:function(name,value){this.scriptObjectNames_.push(name);this.scriptObjectValues_.push(value);},executeCommand:function(command){var f=new Function(this.scriptObjectNames_,'return eval('+command+')');return f.apply(null,this.scriptObjectValues_);}};return{ScriptingController:ScriptingController,ScriptingObjectRegistry:ScriptingObjectRegistry};});'use strict';tr.exportTo('tr.metrics',function(){function MetricRegistry(){}
+var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Function;tr.b.decorateExtensionRegistry(MetricRegistry,options);return{MetricRegistry:MetricRegistry};});'use strict';tr.exportTo('tr.v',function(){function Value(canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics){if(typeof(name)!=='string')
+throw new Error('Expected value_name grouping key to be provided');this.groupingKeys=opt_groupingKeys||{};this.groupingKeys.name=name;this.diagnostics=opt_diagnostics||{};this.diagnostics.canonical_url=canonicalUrl;var options=opt_options||{};this.description=options.description;this.important=options.important!==undefined?options.important:false;}
+Value.fromDict=function(d){if(d.type==='numeric')
+return NumericValue.fromDict(d);if(d.type==='dict')
+return DictValue.fromDict(d);if(d.type=='failure')
+return FailureValue.fromDict(d);if(d.type==='skip')
+return SkipValue.fromDict(d);throw new Error('Not implemented');};Value.prototype={get name(){return this.groupingKeys.name;},get canonicalUrl(){return this.diagnostics.canonical_url;},addGroupingKey:function(keyName,key){if(this.groupingKeys.hasOwnProperty(keyName))
+throw new Error('Tried to redefine grouping key '+keyName);this.groupingKeys[keyName]=key;},asDict:function(){return this.asJSON();},asJSON:function(){var d={grouping_keys:this.groupingKeys,description:this.description,important:this.important,diagnostics:this.diagnostics};this._asDictInto(d);if(d.type===undefined)
+throw new Error('_asDictInto must set type field');return d;},_asDictInto:function(d){throw new Error('Not implemented');}};function NumericValue(canonicalUrl,name,numeric,opt_options,opt_groupingKeys,opt_diagnostics){if(!(numeric instanceof tr.v.NumericBase))
+throw new Error('Expected numeric to be instance of tr.v.NumericBase');Value.call(this,canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics);this.numeric=numeric;}
+NumericValue.fromDict=function(d){if(d.numeric===undefined)
+throw new Error('Expected numeric to be provided');var numeric=tr.v.NumericBase.fromDict(d.numeric);return new NumericValue(d.diagnostics.canonical_url,d.grouping_keys.name,numeric,d,d.grouping_keys,d.diagnostics);};NumericValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='numeric';d.numeric=this.numeric.asDict();}};function DictValue(canonicalUrl,name,value,opt_options,opt_groupingKeys,opt_diagnostics){Value.call(this,canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics);this.value=value;}
+DictValue.fromDict=function(d){if(d.units!==undefined)
+throw new Error('Expected units to be undefined');if(d.value===undefined)
+throw new Error('Expected value to be provided');return new DictValue(d.diagnostics.canonical_url,d.grouping_keys.name,d.value,d,d.groupingKeys,d.diagnostics);};DictValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='dict';d.value=this.value;}};function FailureValue(canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics){var options=opt_options||{};var stack;if(options.stack===undefined){if(options.stack_str===undefined){throw new Error('Expected stack_str or stack to be provided');}else{stack=options.stack_str;}}else{stack=options.stack;}
+if(typeof stack!=='string')
+throw new Error('stack must be provided as a string');if(canonicalUrl===undefined){throw new Error('FailureValue must provide canonicalUrl');}
+Value.call(this,canonicalUrl,name,options,opt_groupingKeys,opt_diagnostics);this.stack=stack;}
+FailureValue.fromError=function(canonicalUrl,e){var ex=tr.b.normalizeException(e);return new FailureValue(canonicalUrl,ex.typeName,{description:ex.message,stack:ex.stack});};FailureValue.fromDict=function(d){if(d.units!==undefined)
+throw new Error('Expected units to be undefined');if(d.stack_str===undefined)
+throw new Error('Expected stack_str to be provided');return new FailureValue(d.diagnostics.canonical_url,d.grouping_keys.name,d,d.grouping_keys,d.diagnostics);};FailureValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='failure';d.stack_str=this.stack;}};function SkipValue(canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics){Value.call(this,canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics);}
+SkipValue.fromDict=function(d){if(d.units!==undefined)
+throw new Error('Expected units to be undefined');return new SkipValue(d.diagnostics.canonical_url,d.grouping_keys.name,d,d.grouping_keys,d.diagnostics);};SkipValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='skip';}};return{Value:Value,NumericValue:NumericValue,DictValue:DictValue,FailureValue:FailureValue,SkipValue:SkipValue};});'use strict';tr.exportTo('tr.metrics',function(){function sampleMetric(valueList,model){var unit=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var n1=new tr.v.ScalarNumeric(unit,1);var n2=new tr.v.ScalarNumeric(unit,2);valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'foo',n1));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'bar',n2));}
+sampleMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(sampleMetric);return{sampleMetric:sampleMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function perceptualBlend(ir,index,score){return Math.exp(1-score);}
+function filterExpectationsByRange(irs,opt_range){var filteredExpectations=[];irs.forEach(function(ir){if(!(ir instanceof tr.model.um.UserExpectation))
+return;if(!opt_range||opt_range.intersectsExplicitRangeExclusive(ir.start,ir.end))
+filteredExpectations.push(ir);});return filteredExpectations;}
+return{perceptualBlend:perceptualBlend,filterExpectationsByRange:filterExpectationsByRange};});'use strict';tr.exportTo('tr.metrics.sh',function(){var UNIT=tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;var DESCRIPTION='Normalized CPU budget consumption';function EfficiencyMetric(valueList,model){var scores=[];model.userModel.expectations.forEach(function(ue){var options={};options.description=DESCRIPTION;var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;var score=undefined;if((ue.totalCpuMs===undefined)||(ue.totalCpuMs==0))
+return;var cpuFractionBudget=tr.b.Range.fromExplicitRange(0.5,1.5);if(ue instanceof tr.model.um.IdleExpectation){cpuFractionBudget=tr.b.Range.fromExplicitRange(0.1,1);}else if(ue instanceof tr.model.um.AnimationExpectation){cpuFractionBudget=tr.b.Range.fromExplicitRange(1,2);}
+var cpuMsBudget=tr.b.Range.fromExplicitRange(ue.duration*cpuFractionBudget.min,ue.duration*cpuFractionBudget.max);var normalizedCpu=tr.b.normalize(ue.totalCpuMs,cpuMsBudget.min,cpuMsBudget.max);score=1-tr.b.clamp(normalizedCpu,0,1);scores.push(score);valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'efficiency',new tr.v.ScalarNumeric(UNIT,score),options,groupingKeys));});var options={};options.description=DESCRIPTION;var groupingKeys={};var overallScore=tr.b.Statistics.weightedMean(scores,tr.metrics.sh.perceptualBlend);if(overallScore===undefined)
+return;valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'efficiency',new tr.v.ScalarNumeric(UNIT,overallScore),options,groupingKeys));}
+EfficiencyMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(EfficiencyMetric);return{EfficiencyMetric:EfficiencyMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){var MIN_DISCREPANCY=0.05;var MAX_DISCREPANCY=0.3;var UNIT=tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;var DESCRIPTION='Mean Opinion Score for Animation smoothness';function AnimationSmoothnessMetric(valueList,model){model.userModel.expectations.forEach(function(ue){if(!(ue instanceof tr.model.um.AnimationExpectation))
+return;if(ue.frameEvents===undefined||ue.frameEvents.length===0)
+throw new Error('Animation missing frameEvents '+ue.stableId);var options={};options.description=DESCRIPTION;var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;var frameTimestamps=ue.frameEvents.toArray().map(function(event){return event.start;});var absolute=false;var discrepancy=tr.b.Statistics.timestampsDiscrepancy(frameTimestamps,absolute);var smoothness=1-tr.b.normalize(discrepancy,MIN_DISCREPANCY,MAX_DISCREPANCY);var score=tr.b.clamp(smoothness,0,1);valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'smoothness',new tr.v.ScalarNumeric(UNIT,score),options,groupingKeys));});}
+AnimationSmoothnessMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(AnimationSmoothnessMetric);return{AnimationSmoothnessMetric:AnimationSmoothnessMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){var MAX_FPS=60;var MIN_FPS=10;var UNIT=tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;var DESCRIPTION='Mean Opinion Score for Animation throughput';function AnimationThroughputMetric(valueList,model){model.userModel.expectations.forEach(function(ue){if(!(ue instanceof tr.model.um.AnimationExpectation))
+return;if(ue.frameEvents===undefined||ue.frameEvents.length===0)
+throw new Error('Animation missing frameEvents '+ue.stableId);var options={};options.description=DESCRIPTION;var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;var durationSeconds=ue.duration/1000;var avgSpf=durationSeconds/ue.frameEvents.length;var throughput=1-tr.b.normalize(avgSpf,1/MAX_FPS,1/MIN_FPS);var score=tr.b.clamp(throughput,0,1);valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'throughput',new tr.v.ScalarNumeric(UNIT,score),options,groupingKeys));});}
+AnimationThroughputMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(AnimationThroughputMetric);return{AnimationThroughputMetric:AnimationThroughputMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){var RESPONSE_HISTOGRAM=tr.v.Numeric.fromDict({unit:'unitless',min:150,max:5000,centralBinWidth:485,underflowBin:{min:-Number.MAX_VALUE,max:150,count:1000},centralBins:[{min:150,max:635,count:708},{min:635,max:1120,count:223},{min:1120,max:1605,count:50},{min:1605,max:2090,count:33},{min:2090,max:2575,count:23},{min:2575,max:3060,count:17},{min:3060,max:3545,count:12},{min:3545,max:4030,count:8},{min:4030,max:4515,count:4},{min:4515,max:5000,count:1}],overflowBin:{min:5000,max:Number.MAX_VALUE,count:0}});var FAST_RESPONSE_HISTOGRAM=tr.v.Numeric.fromDict({unit:'unitless',min:66,max:2200,centralBinWidth:214,underflowBin:{min:-Number.MAX_VALUE,max:66,count:1000},centralBins:[{min:66,max:280,count:708},{min:280,max:493,count:223},{min:493,max:706,count:50},{min:706,max:920,count:33},{min:920,max:1133,count:23},{min:1133,max:1346,count:17},{min:1346,max:1560,count:12},{min:1560,max:1773,count:8},{min:1773,max:1987,count:4},{min:1987,max:2200,count:1}],overflowBin:{min:2200,max:Number.MAX_VALUE,count:0}});var LOAD_HISTOGRAM=tr.v.Numeric.fromDict({unit:'unitless',min:1000,max:60000,centralBinWidth:5900,underflowBin:{min:-Number.MAX_VALUE,max:1000,count:1000},centralBins:[{min:1000,max:6900,count:901},{min:6900,max:12800,count:574},{min:12800,max:18700,count:298},{min:18700,max:24600,count:65},{min:24600,max:30500,count:35},{min:30500,max:36400,count:23},{min:36400,max:42300,count:16},{min:42300,max:48200,count:10},{min:48200,max:54100,count:5},{min:54100,max:60000,count:2}],overflowBin:{min:60000,max:Number.MAX_VALUE,count:0}});var UNIT=tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;var DESCRIPTION=('For Load and Response, Mean Opinion Score of completion time; '+'For Animation, perceptual blend of Mean Opinion Scores of '+'throughput and smoothness');function getDurationScore(histogram,duration){return histogram.getInterpolatedCountAt(duration)/histogram.maxCount;}
+function ResponsivenessMetric(valueList,model){tr.metrics.sh.AnimationThroughputMetric(valueList,model);tr.metrics.sh.AnimationSmoothnessMetric(valueList,model);var throughputForAnimation={};var smoothnessForAnimation={};valueList.valueDicts.forEach(function(value){if((value.type!=='numeric')||(value.numeric.type!=='scalar'))
+return;var ue=value.grouping_keys.userExpectationStableId;if(value.grouping_keys.name==='throughput')
+throughputForAnimation[ue]=value.numeric.value;if(value.grouping_keys.name==='smoothness')
+smoothnessForAnimation[ue]=value.numeric.value;});var scores=[];model.userModel.expectations.forEach(function(ue){var score=undefined;if(ue instanceof tr.model.um.IdleExpectation){return;}else if(ue instanceof tr.model.um.LoadExpectation){score=getDurationScore(LOAD_HISTOGRAM,ue.duration);}else if(ue instanceof tr.model.um.ResponseExpectation){var histogram=RESPONSE_HISTOGRAM;if(ue.isAnimationBegin)
+histogram=FAST_RESPONSE_HISTOGRAM;score=getDurationScore(histogram,ue.duration);}else if(ue instanceof tr.model.um.AnimationExpectation){var throughput=throughputForAnimation[ue.stableId];var smoothness=smoothnessForAnimation[ue.stableId];if(throughput===undefined)
+throw new Error('Missing throughput for '+ue.stableId);if(smoothness===undefined)
+throw new Error('Missing smoothness for '+ue.stableId);score=tr.b.Statistics.weightedMean([throughput,smoothness],tr.metrics.sh.perceptualBlend);}else{throw new Error('Unrecognized stage for '+ue.stableId);}
+if(score===undefined)
+throw new Error('Failed to compute responsiveness for '+ue.stableId);scores.push(score);var options={};options.description=DESCRIPTION;var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'responsiveness',new tr.v.ScalarNumeric(UNIT,score),options,groupingKeys));});var options={};options.description=DESCRIPTION;var groupingKeys={};var overallScore=tr.b.Statistics.weightedMean(scores,tr.metrics.sh.perceptualBlend);if(overallScore===undefined)
+return;valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'responsiveness',new tr.v.ScalarNumeric(UNIT,overallScore),options,groupingKeys));}
+ResponsivenessMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(ResponsivenessMetric);return{ResponsivenessMetric:ResponsivenessMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function SystemHealthMetrics(valueList,model){tr.metrics.sh.ResponsivenessMetric(valueList,model);tr.metrics.sh.EfficiencyMetric(valueList,model);}
+SystemHealthMetrics.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(SystemHealthMetrics);return{SystemHealthMetrics:SystemHealthMetrics};});'use strict';tr.exportTo('tr.metrics',function(){function tracingMetric(valueList,model){if(!model.stats.hasEventSizesinBytes){throw new Error('Model stats does not have event size information. '+'Please enable ImportOptions.trackDetailedModelStats.');}
+var eventStats=model.stats.allTraceEventStatsInTimeIntervals;eventStats.sort(function(a,b){return a.timeInterval-b.timeInterval;});var maxEventCountPerSec=0;var maxEventBytesPerSec=0;var totalTraceBytes=0;var WINDOW_SIZE=Math.floor(1000/model.stats.TIME_INTERVAL_SIZE_IN_MS);var runningEventNumPerSec=0;var runningEventBytesPerSec=0;var start=0;var end=0;while(end<eventStats.length){var startEventStats=eventStats[start];var endEventStats=eventStats[end];var timeWindow=endEventStats.timeInterval-startEventStats.timeInterval;if(timeWindow>=WINDOW_SIZE){runningEventNumPerSec-=startEventStats.numEvents;runningEventBytesPerSec-=startEventStats.totalEventSizeinBytes;start++;continue;}
+runningEventNumPerSec+=endEventStats.numEvents;if(maxEventCountPerSec<runningEventNumPerSec)
+maxEventCountPerSec=runningEventNumPerSec;runningEventBytesPerSec+=endEventStats.totalEventSizeinBytes;if(maxEventBytesPerSec<runningEventBytesPerSec)
+maxEventBytesPerSec=runningEventBytesPerSec;totalTraceBytes+=endEventStats.totalEventSizeinBytes;end++;}
+var stats=model.stats.allTraceEventStats;var categoryStatsMap=new Map();var categoryStats=[];for(var i=0;i<stats.length;i++){var categoryStat=categoryStatsMap.get(stats[i].category);if(categoryStat===undefined){categoryStat={category:stats[i].category,totalEventSizeinBytes:0};categoryStatsMap.set(stats[i].category,categoryStat);categoryStats.push(categoryStat);}
+categoryStat.totalEventSizeinBytes+=stats[i].totalEventSizeinBytes;}
+var maxCategoryStats=categoryStats.reduce(function(a,b){return a.totalEventSizeinBytes<b.totalEventSizeinBytes?b:a;});var maxEventBytesPerCategory=maxCategoryStats.totalEventSizeinBytes;var maxCategoryName=maxCategoryStats.category;var maxEventCountPerSecValue=new tr.v.ScalarNumeric(tr.v.Unit.byName.unitlessNumber_smallerIsBetter,maxEventCountPerSec);var maxEventBytesPerSecValue=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,maxEventBytesPerSec);var totalTraceBytesValue=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,totalTraceBytes);var diagnostics={category_with_max_event_size:{name:maxCategoryName,size_in_bytes:maxEventBytesPerCategory}};valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'Total trace size in bytes',totalTraceBytesValue,undefined,undefined,diagnostics));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'Max number of events per second',maxEventCountPerSecValue,undefined,undefined,diagnostics));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'Max event size in bytes per second',maxEventBytesPerSecValue,undefined,undefined,diagnostics));}
+tracingMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(tracingMetric);return{tracingMetric:tracingMetric};});'use strict';Polymer('tr-ui-a-alert-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},getRowsForSingleAlert_:function(alert){var rows=[];for(var argName in alert.args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=alert.args[argName];rows.push({name:argName,value:argView});}
+if(alert.associatedEvents.length){alert.associatedEvents.forEach(function(event,i){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return event;},event.title);var valueString='';if(event instanceof tr.model.TimedEvent)
+valueString='took '+event.duration.toFixed(2)+'ms';rows.push({name:linkEl,value:valueString});});}
+var descriptionEl=tr.ui.b.createDiv({textContent:alert.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(alert.info.docLinks){alert.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}
+return rows;},getRowsForAlerts_:function(alerts){if(alerts.length==1){var rows=[{name:'Alert',value:alerts[0].title}];var detailRows=this.getRowsForSingleAlert_(alerts[0]);rows.push.apply(rows,detailRows);return rows;}else{return alerts.map(function(alert){return{name:'Alert',value:alert.title,isExpanded:alerts.size<10,subRows:this.getRowsForSingleAlert_(alert)};},this);}},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+var alerts=this.currentSelection_;this.$.table.tableRows=this.getRowsForAlerts_(alerts);this.$.table.rebuild();},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';tr.exportTo('tr.b',function(){function MultiDimensionalViewNode(title,isLowerBound){this.title=title;var dimensions=title.length;this.children=new Array(dimensions);for(var i=0;i<dimensions;i++)
+this.children[i]=new Map();this.total=0;this.self=0;this.isLowerBound=!!isLowerBound;}
+MultiDimensionalViewNode.prototype={get subRows(){return tr.b.mapValues(this.children[0]);}};var MultiDimensionalViewType={TOP_DOWN_TREE_VIEW:0,TOP_DOWN_HEAVY_VIEW:1,BOTTOM_UP_HEAVY_VIEW:2};function MultiDimensionalViewBuilder(dimensions){if(dimensions<0)
+throw new Error('Dimensions must be non-negative');this.dimensions_=dimensions;this.buildRoot_=this.createRootNode_();this.topDownTreeViewRoot_=undefined;this.topDownHeavyViewRoot_=undefined;this.bottomUpHeavyViewNode_=undefined;this.maxDimensionDepths_=new Array(dimensions);for(var d=0;d<dimensions;d++)
+this.maxDimensionDepths_[d]=0;}
+MultiDimensionalViewBuilder.ValueKind={SELF:0,TOTAL:1};MultiDimensionalViewBuilder.prototype={addPath:function(path,value,valueKind){if(this.buildRoot_===undefined){throw new Error('Paths cannot be added after either view has been built');}
+if(path.length!==this.dimensions_)
+throw new Error('Path must be '+this.dimensions_+'-dimensional');var node=this.buildRoot_;for(var d=0;d<path.length;d++){var singleDimensionPath=path[d];var singleDimensionPathLength=singleDimensionPath.length;this.maxDimensionDepths_[d]=Math.max(this.maxDimensionDepths_[d],singleDimensionPathLength);for(var i=0;i<singleDimensionPathLength;i++)
+node=this.getOrCreateChildNode_(node,d,singleDimensionPath[i]);}
+switch(valueKind){case MultiDimensionalViewBuilder.ValueKind.SELF:node.self+=value;break;case MultiDimensionalViewBuilder.ValueKind.TOTAL:node.total+=value;break;default:throw new Error('Invalid value kind: '+valueKind);}
+node.isLowerBound=false;},buildView:function(viewType){switch(viewType){case MultiDimensionalViewType.TOP_DOWN_TREE_VIEW:return this.buildTopDownTreeView();case MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW:return this.buildTopDownHeavyView();case MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW:return this.buildBottomUpHeavyView();default:throw new Error('Unknown multi-dimensional view type: '+viewType);}},buildTopDownTreeView:function(){if(this.topDownTreeViewRoot_===undefined){var treeViewRoot=this.buildRoot_;this.buildRoot_=undefined;this.setUpMissingChildRelationships_(treeViewRoot,0);this.finalizeTotalValues_(treeViewRoot,0,new WeakMap());this.topDownTreeViewRoot_=treeViewRoot;}
+return this.topDownTreeViewRoot_;},buildTopDownHeavyView:function(){if(this.topDownHeavyViewRoot_===undefined){this.topDownHeavyViewRoot_=this.buildGenericHeavyView_(this.addDimensionToTopDownHeavyViewNode_.bind(this));}
+return this.topDownHeavyViewRoot_;},buildBottomUpHeavyView:function(){if(this.bottomUpHeavyViewNode_===undefined){this.bottomUpHeavyViewNode_=this.buildGenericHeavyView_(this.addDimensionToBottomUpHeavyViewNode_.bind(this));}
+return this.bottomUpHeavyViewNode_;},createRootNode_:function(){return new MultiDimensionalViewNode(new Array(this.dimensions_),true);},getOrCreateChildNode_:function(parentNode,dimension,childDimensionTitle){if(dimension<0||dimension>=this.dimensions_)
+throw new Error('Invalid dimension');var dimensionChildren=parentNode.children[dimension];var childNode=dimensionChildren.get(childDimensionTitle);if(childNode!==undefined)
+return childNode;var childTitle=parentNode.title.slice();childTitle[dimension]=childDimensionTitle;childNode=new MultiDimensionalViewNode(childTitle,true);dimensionChildren.set(childDimensionTitle,childNode);return childNode;},setUpMissingChildRelationships_:function(node,firstDimensionToSetUp){for(var d=firstDimensionToSetUp;d<this.dimensions_;d++){var currentDimensionChildTitles=new Set(node.children[d].keys());for(var i=0;i<d;i++){for(var previousDimensionChildNode of node.children[i].values()){for(var previousDimensionGrandChildTitle of
+previousDimensionChildNode.children[d].keys()){currentDimensionChildTitles.add(previousDimensionGrandChildTitle);}}}
+for(var currentDimensionChildTitle of currentDimensionChildTitles){var currentDimensionChildNode=this.getOrCreateChildNode_(node,d,currentDimensionChildTitle);for(var i=0;i<d;i++){for(var previousDimensionChildNode of node.children[i].values()){var previousDimensionGrandChildNode=previousDimensionChildNode.children[d].get(currentDimensionChildTitle);if(previousDimensionGrandChildNode!==undefined){currentDimensionChildNode.children[i].set(previousDimensionChildNode.title[i],previousDimensionGrandChildNode);}}}
+this.setUpMissingChildRelationships_(currentDimensionChildNode,d);}}},finalizeTotalValues_:function(node,firstDimensionToFinalize,dimensionalSelfSumsMap){var dimensionalSelfSums=new Array(this.dimensions_);var maxChildResidualSum=0;var nodeSelfSum=node.self;for(var d=0;d<this.dimensions_;d++){var childResidualSum=0;for(var childNode of node.children[d].values()){if(d>=firstDimensionToFinalize)
+this.finalizeTotalValues_(childNode,d,dimensionalSelfSumsMap);var childNodeSelfSums=dimensionalSelfSumsMap.get(childNode);nodeSelfSum+=childNodeSelfSums[d];var residual=childNode.total-childNodeSelfSums[this.dimensions_-1];childResidualSum+=residual;}
+dimensionalSelfSums[d]=nodeSelfSum;maxChildResidualSum=Math.max(maxChildResidualSum,childResidualSum);}
+node.total=Math.max(node.total,nodeSelfSum+maxChildResidualSum);if(dimensionalSelfSumsMap.has(node))
+throw new Error('Internal error: Node finalized more than once');dimensionalSelfSumsMap.set(node,dimensionalSelfSums);},buildGenericHeavyView_:function(treeViewNodeHandler){var treeViewRoot=this.buildTopDownTreeView();var heavyViewRoot=this.createRootNode_();heavyViewRoot.total=treeViewRoot.total;heavyViewRoot.self=treeViewRoot.self;heavyViewRoot.isLowerBound=treeViewRoot.isLowerBound;var recursionDepthTrackers=new Array(this.dimensions_);for(var d=0;d<this.dimensions_;d++){recursionDepthTrackers[d]=new RecursionDepthTracker(this.maxDimensionDepths_[d],d);}
+this.addDimensionsToGenericHeavyViewNode_(treeViewRoot,heavyViewRoot,0,recursionDepthTrackers,false,treeViewNodeHandler);this.setUpMissingChildRelationships_(heavyViewRoot,0);return heavyViewRoot;},addDimensionsToGenericHeavyViewNode_:function(treeViewParentNode,heavyViewParentNode,startDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){for(var d=startDimension;d<this.dimensions_;d++){this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,d,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);}},addDimensionDescendantsToGenericHeavyViewNode_:function(treeViewParentNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){var treeViewChildren=treeViewParentNode.children[currentDimension];var recursionDepthTracker=recursionDepthTrackers[currentDimension];for(var treeViewChildNode of treeViewChildren.values()){recursionDepthTracker.push(treeViewChildNode);treeViewNodeHandler(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive);this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);recursionDepthTracker.pop();}},addDimensionToTopDownHeavyViewNode_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,1);},addDimensionToTopDownHeavyViewNodeRecursively_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth){var recursionDepthTracker=recursionDepthTrackers[currentDimension];var currentDimensionRecursive=subTreeDepth<=recursionDepthTracker.recursionDepth;var currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;var dimensionTitle=treeViewChildNode.title[currentDimension];var heavyViewChildNode=this.getOrCreateChildNode_(heavyViewParentNode,currentDimension,dimensionTitle);heavyViewChildNode.self+=treeViewChildNode.self;if(!currentOrPreviousDimensionsRecursive)
+heavyViewChildNode.total+=treeViewChildNode.total;this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewChildNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToTopDownHeavyViewNode_.bind(this));for(var treeViewGrandChildNode of
+treeViewChildNode.children[currentDimension].values()){recursionDepthTracker.push(treeViewGrandChildNode);this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewGrandChildNode,heavyViewChildNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth+1);recursionDepthTracker.pop();}},addDimensionToBottomUpHeavyViewNode_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){var recursionDepthTracker=recursionDepthTrackers[currentDimension];var bottomIndex=recursionDepthTracker.bottomIndex;var topIndex=recursionDepthTracker.topIndex;var firstNonRecursiveIndex=bottomIndex+recursionDepthTracker.recursionDepth;var viewNodePath=recursionDepthTracker.viewNodePath;var trackerAncestorNode=recursionDepthTracker.trackerAncestorNode;var heavyViewDescendantNode=heavyViewParentNode;for(var i=bottomIndex;i<topIndex;i++){var treeViewAncestorNode=viewNodePath[i];var dimensionTitle=treeViewAncestorNode.title[currentDimension];heavyViewDescendantNode=this.getOrCreateChildNode_(heavyViewDescendantNode,currentDimension,dimensionTitle);var currentDimensionRecursive=i<firstNonRecursiveIndex;var currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;heavyViewDescendantNode.self+=treeViewChildNode.self;if(!currentOrPreviousDimensionsRecursive)
+heavyViewDescendantNode.total+=treeViewChildNode.total;this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewDescendantNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToBottomUpHeavyViewNode_.bind(this));}}};function RecursionDepthTracker(maxDepth,dimension){this.titlePath=new Array(maxDepth);this.viewNodePath=new Array(maxDepth);this.bottomIndex=this.topIndex=maxDepth;this.dimension_=dimension;this.currentTrackerNode_=this.createNode_(0,undefined);}
+RecursionDepthTracker.prototype={push:function(viewNode){if(this.bottomIndex===0)
+throw new Error('Cannot push to a full tracker');var title=viewNode.title[this.dimension_];this.bottomIndex--;this.titlePath[this.bottomIndex]=title;this.viewNodePath[this.bottomIndex]=viewNode;var childTrackerNode=this.currentTrackerNode_.children.get(title);if(childTrackerNode!==undefined){this.currentTrackerNode_=childTrackerNode;return;}
+var maxLengths=zFunction(this.titlePath,this.bottomIndex);var recursionDepth=0;for(var i=0;i<maxLengths.length;i++)
+recursionDepth=Math.max(recursionDepth,maxLengths[i]);childTrackerNode=this.createNode_(recursionDepth,this.currentTrackerNode_);this.currentTrackerNode_.children.set(title,childTrackerNode);this.currentTrackerNode_=childTrackerNode;},pop:function(){if(this.bottomIndex===this.topIndex)
+throw new Error('Cannot pop from an empty tracker');this.titlePath[this.bottomIndex]=undefined;this.viewNodePath[this.bottomIndex]=undefined;this.bottomIndex++;this.currentTrackerNode_=this.currentTrackerNode_.parent;},get recursionDepth(){return this.currentTrackerNode_.recursionDepth;},createNode_:function(recursionDepth,parent){return{recursionDepth:recursionDepth,parent:parent,children:new Map()};}};function zFunction(list,startIndex){var n=list.length-startIndex;if(n===0)
+return[];var z=new Array(n);z[0]=0;for(var i=1,left=0,right=0;i<n;++i){var maxLength;if(i<=right)
+maxLength=Math.min(right-i+1,z[i-left]);else
+maxLength=0;while(i+maxLength<n&&list[startIndex+maxLength]===list[startIndex+i+maxLength]){++maxLength;}
+if(i+maxLength-1>right){left=i;right=i+maxLength-1;}
+z[i]=maxLength;}
+return z;}
+return{MultiDimensionalViewBuilder:MultiDimensionalViewBuilder,MultiDimensionalViewType:MultiDimensionalViewType,MultiDimensionalViewNode:MultiDimensionalViewNode,RecursionDepthTracker:RecursionDepthTracker,zFunction:zFunction};});'use strict';tr.exportTo('tr.ui.analysis',function(){var NO_BREAK_SPACE=String.fromCharCode(160);var RIGHTWARDS_ARROW=String.fromCharCode(8594);var COLLATOR=new Intl.Collator(undefined,{numeric:true});function TitleColumn(title){this.title=title;}
+TitleColumn.prototype={supportsCellSelection:false,value:function(row){var formattedTitle=this.formatTitle(row);var contexts=row.contexts;if(contexts===undefined||contexts.length===0)
+return formattedTitle;var firstContext=contexts[0];var lastContext=contexts[contexts.length-1];var changeDefinedContextCount=0;for(var i=1;i<contexts.length;i++){if((contexts[i]===undefined)!==(contexts[i-1]===undefined))
+changeDefinedContextCount++;}
+var color=undefined;var prefix=undefined;if(!firstContext&&lastContext){color='red';prefix='+++';}else if(firstContext&&!lastContext){color='green';prefix='---';}
+if(changeDefinedContextCount>1){color='purple';}
+if(color===undefined&&prefix===undefined)
+return formattedTitle;var titleEl=document.createElement('span');if(prefix!==undefined){var prefixEl=tr.ui.b.createSpan({textContent:prefix});prefixEl.style.fontFamily='monospace';titleEl.appendChild(prefixEl);titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));}
+if(color!==undefined)
+titleEl.style.color=color;titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedTitle));return titleEl;},formatTitle:function(row){return row.title;},cmp:function(rowA,rowB){return COLLATOR.compare(rowA.title,rowB.title);}};function MemoryColumn(name,cellPath,aggregationMode){this.name=name;this.cellPath=cellPath;this.aggregationMode=aggregationMode;}
+MemoryColumn.fromRows=function(rows,cellKey,aggregationMode,rules){var cellNames=new Set();function gatherCellNames(rows){rows.forEach(function(row){if(row===undefined)
+return;var fieldCells=row[cellKey];if(fieldCells!==undefined){tr.b.iterItems(fieldCells,function(fieldName,fieldCell){if(fieldCell===undefined||fieldCell.fields===undefined)
+return;cellNames.add(fieldName);});}
+var subRows=row.subRows;if(subRows!==undefined)
+gatherCellNames(subRows);});}
+gatherCellNames(rows);var positions=[];cellNames.forEach(function(cellName){var cellPath=[cellKey,cellName];var matchingRule=MemoryColumn.findMatchingRule(cellName,rules);var constructor=matchingRule.columnConstructor;var column=new constructor(cellName,cellPath,aggregationMode);positions.push({importance:matchingRule.importance,column:column});});positions.sort(function(a,b){if(a.importance===b.importance)
+return COLLATOR.compare(a.column.name,b.column.name);return b.importance-a.importance;});return positions.map(function(position){return position.column});};MemoryColumn.spaceEqually=function(columns){var columnWidth=(100/columns.length).toFixed(3)+'%';columns.forEach(function(column){column.width=columnWidth;});};MemoryColumn.findMatchingRule=function(name,rules){for(var i=0;i<rules.length;i++){var rule=rules[i];if(MemoryColumn.nameMatchesCondition(name,rule.condition))
+return rule;}
+return undefined;};MemoryColumn.nameMatchesCondition=function(name,condition){if(condition===undefined)
+return true;if(typeof(condition)==='string')
+return name===condition;return condition.test(name);};MemoryColumn.AggregationMode={DIFF:0,MAX:1};MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER='at some selected timestamps';MemoryColumn.prototype={get title(){return this.name;},cell:function(row){var cell=row;var cellPath=this.cellPath;for(var i=0;i<cellPath.length;i++){if(cell===undefined)
+return undefined;cell=cell[cellPath[i]];}
+return cell;},aggregateCells:function(row,subRows){},fields:function(row){var cell=this.cell(row);if(cell===undefined)
+return undefined;return cell.fields;},value:function(row){var fields=this.fields(row);if(this.hasAllRelevantFieldsUndefined(fields))
+return'';var contexts=row.contexts;var color=this.color(fields,contexts);var infos=[];this.addInfos(fields,contexts,infos);var formattedFields=this.formatFields(fields);if((color===undefined||formattedFields==='')&&infos.length===0)
+return formattedFields;var fieldEl=document.createElement('span');fieldEl.style.display='flex';fieldEl.style.alignItems='center';fieldEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedFields));infos.forEach(function(info){var infoEl=document.createElement('span');infoEl.style.paddingLeft='4px';infoEl.style.cursor='help';infoEl.style.fontWeight='bold';infoEl.textContent=info.icon;if(info.color!==undefined)
+infoEl.style.color=info.color;infoEl.title=info.message;fieldEl.appendChild(infoEl);},this);if(color!==undefined)
+fieldEl.style.color=color;return fieldEl;},hasAllRelevantFieldsUndefined:function(fields){if(fields===undefined)
+return true;switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return fields[0]===undefined&&fields[fields.length-1]===undefined;case MemoryColumn.AggregationMode.MAX:default:return fields.every(function(field){return field===undefined;});}},color:function(fields,contexts){return undefined;},formatFields:function(fields){if(fields.length===1)
+return this.formatSingleField(fields[0]);else
+return this.formatMultipleFields(fields);},formatSingleField:function(field){throw new Error('Not implemented');},formatMultipleFields:function(fields){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.formatMultipleFieldsDiff(fields[0],fields[fields.length-1]);case MemoryColumn.AggregationMode.MAX:return this.formatMultipleFieldsMax(fields);default:return tr.ui.b.createSpan({textContent:'(unsupported aggregation mode)',italic:true});}},formatMultipleFieldsDiff:function(firstField,lastField){throw new Error('Not implemented');},formatMultipleFieldsMax:function(fields){return this.formatSingleField(this.getMaxField(fields));},cmp:function(rowA,rowB){var fieldsA=this.fields(rowA);var fieldsB=this.fields(rowB);if(fieldsA!==undefined&&fieldsB!==undefined&&fieldsA.length!==fieldsB.length)
+throw new Error('Different number of fields');var undefinedA=this.hasAllRelevantFieldsUndefined(fieldsA);var undefinedB=this.hasAllRelevantFieldsUndefined(fieldsB);if(undefinedA&&undefinedB)
+return 0;if(undefinedA)
+return-1;if(undefinedB)
+return 1;return this.compareFields(fieldsA,fieldsB);},compareFields:function(fieldsA,fieldsB){if(fieldsA.length===1)
+return this.compareSingleFields(fieldsA[0],fieldsB[0]);else
+return this.compareMultipleFields(fieldsA,fieldsB);},compareSingleFields:function(fieldA,fieldB){throw new Error('Not implemented');},compareMultipleFields:function(fieldsA,fieldsB){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.compareMultipleFieldsDiff(fieldsA[0],fieldsA[fieldsA.length-1],fieldsB[0],fieldsB[fieldsB.length-1]);case MemoryColumn.AggregationMode.MAX:return this.compareMultipleFieldsMax(fieldsA,fieldsB);default:return 0;}},compareMultipleFieldsDiff:function(firstFieldA,lastFieldA,firstFieldB,lastFieldB){throw new Error('Not implemented');},compareMultipleFieldsMax:function(fieldsA,fieldsB){return this.compareSingleFields(this.getMaxField(fieldsA),this.getMaxField(fieldsB));},getMaxField:function(fields){return fields.reduce(function(accumulator,field){if(field===undefined)
+return accumulator;if(accumulator===undefined||this.compareSingleFields(field,accumulator)>0){return field;}
+return accumulator;}.bind(this),undefined);},addInfos:function(fields,contexts,infos){},getImportance:function(importanceRules){if(importanceRules.length===0)
+return 0;var matchingRule=MemoryColumn.findMatchingRule(this.name,importanceRules);if(matchingRule!==undefined)
+return matchingRule.importance;var minImportance=importanceRules[0].importance;for(var i=1;i<importanceRules.length;i++)
+minImportance=Math.min(minImportance,importanceRules[i].importance);return minImportance-1;}};function StringMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
+StringMemoryColumn.prototype={__proto__:MemoryColumn.prototype,formatSingleField:function(string){return string;},formatMultipleFieldsDiff:function(firstString,lastString){if(firstString===undefined){var spanEl=tr.ui.b.createSpan({color:'red'});spanEl.appendChild(tr.ui.b.asHTMLOrTextNode('+'));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;}else if(lastString===undefined){var spanEl=tr.ui.b.createSpan({color:'green'});spanEl.appendChild(tr.ui.b.asHTMLOrTextNode('-'));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));return spanEl;}else if(firstString===lastString){return this.formatSingleField(firstString);}else{var spanEl=tr.ui.b.createSpan({color:'DarkOrange'});spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(' '+RIGHTWARDS_ARROW+' '));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;}},compareSingleFields:function(stringA,stringB){return COLLATOR.compare(stringA,stringB);},compareMultipleFieldsDiff:function(firstStringA,lastStringA,firstStringB,lastStringB){if(firstStringA===undefined&&firstStringB!==undefined)
+return 1;if(firstStringA!==undefined&&firstStringB===undefined)
+return-1;if(firstStringA===undefined&&firstStringB===undefined)
+return this.compareSingleFields(lastStringA,lastStringB);if(lastStringA===undefined&&lastStringB!==undefined)
+return-1;if(lastStringA!==undefined&&lastStringB===undefined)
+return 1;if(lastStringA===undefined&&lastStringB===undefined)
+return this.compareSingleFields(firstStringB,firstStringA);var areStringsAEqual=firstStringA===lastStringA;var areStringsBEqual=firstStringB===lastStringB;if(areStringsAEqual&&areStringsBEqual)
+return 0;if(areStringsAEqual)
+return-1;if(areStringsBEqual)
+return 1;return 0;}};function NumericMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
+NumericMemoryColumn.DIFF_EPSILON=0.0001;NumericMemoryColumn.prototype={__proto__:MemoryColumn.prototype,aggregateCells:function(row,subRows){var subRowCells=subRows.map(this.cell,this);var hasDefinedSubRowNumeric=false;var timestampCount=undefined;subRowCells.forEach(function(subRowCell){if(subRowCell===undefined)
+return;var subRowNumerics=subRowCell.fields;if(subRowNumerics===undefined)
+return;if(timestampCount===undefined)
+timestampCount=subRowNumerics.length;else if(timestampCount!==subRowNumerics.length)
+throw new Error('Sub-rows have different numbers of timestamps');if(hasDefinedSubRowNumeric)
+return;hasDefinedSubRowNumeric=subRowNumerics.some(function(numeric){return numeric!==undefined;});});if(!hasDefinedSubRowNumeric)
+return;var cellPath=this.cellPath;var rowCell=row;for(var i=0;i<cellPath.length;i++){var nextStepName=cellPath[i];var nextStep=rowCell[nextStepName];if(nextStep===undefined){if(i<cellPath.length-1)
+nextStep={};else
+nextStep=new MemoryCell(undefined);rowCell[nextStepName]=nextStep;}
+rowCell=nextStep;}
+if(rowCell.fields===undefined){rowCell.fields=new Array(timestampCount);}else if(rowCell.fields.length!==timestampCount){throw new Error('Row has a different number of timestamps than sub-rows');}
+for(var i=0;i<timestampCount;i++){if(rowCell.fields[i]!==undefined)
+continue;rowCell.fields[i]=tr.model.MemoryAllocatorDump.aggregateNumerics(subRowCells.map(function(subRowCell){if(subRowCell===undefined||subRowCell.fields===undefined)
+return undefined;return subRowCell.fields[i];}));}},formatSingleField:function(numeric){if(numeric===undefined)
+return'';return tr.v.ui.createScalarSpan(numeric);},formatMultipleFieldsDiff:function(firstNumeric,lastNumeric){return this.formatSingleField(this.getDiffField_(firstNumeric,lastNumeric));},compareSingleFields:function(numericA,numericB){return numericA.value-numericB.value;},compareMultipleFieldsDiff:function(firstNumericA,lastNumericA,firstNumericB,lastNumericB){return this.getDiffFieldValue_(firstNumericA,lastNumericA)-
+this.getDiffFieldValue_(firstNumericB,lastNumericB);},getDiffField_:function(firstNumeric,lastNumeric){var definedNumeric=firstNumeric||lastNumeric;return new tr.v.ScalarNumeric(definedNumeric.unit.correspondingDeltaUnit,this.getDiffFieldValue_(firstNumeric,lastNumeric));},getDiffFieldValue_:function(firstNumeric,lastNumeric){var firstValue=firstNumeric===undefined?0:firstNumeric.value;var lastValue=lastNumeric===undefined?0:lastNumeric.value;var diff=lastValue-firstValue;return Math.abs(diff)<NumericMemoryColumn.DIFF_EPSILON?0:diff;}};function MemoryCell(fields){this.fields=fields;}
+MemoryCell.extractFields=function(cell){if(cell===undefined)
+return undefined;return cell.fields;};var RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT=10;function expandTableRowsRecursively(table){var currentLevelRows=table.tableRows;var totalVisibleRowCount=currentLevelRows.length;while(currentLevelRows.length>0){var nextLevelRowCount=0;currentLevelRows.forEach(function(currentLevelRow){var subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)
+return;nextLevelRowCount+=subRows.length;});if(totalVisibleRowCount+nextLevelRowCount>RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT){break;}
+var nextLevelRows=new Array(nextLevelRowCount);var nextLevelRowIndex=0;currentLevelRows.forEach(function(currentLevelRow){var subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)
+return;table.setExpandedForTableRow(currentLevelRow,true);subRows.forEach(function(subRow){nextLevelRows[nextLevelRowIndex++]=subRow;});});totalVisibleRowCount+=nextLevelRowCount;currentLevelRows=nextLevelRows;}}
+function aggregateTableRowCellsRecursively(row,columns,opt_predicate){var subRows=row.subRows;if(subRows===undefined||subRows.length===0)
+return;subRows.forEach(function(subRow){aggregateTableRowCellsRecursively(subRow,columns,opt_predicate);});if(opt_predicate===undefined||opt_predicate(row.contexts))
+aggregateTableRowCells(row,subRows,columns);}
+function aggregateTableRowCells(row,subRows,columns){columns.forEach(function(column){if(!(column instanceof MemoryColumn))
+return;column.aggregateCells(row,subRows);});}
+function createCells(timeToValues,valueFieldsGetter){var fieldNameToFields=tr.b.invertArrayOfDicts(timeToValues,valueFieldsGetter);return tr.b.mapItems(fieldNameToFields,function(fieldName,fields){return new tr.ui.analysis.MemoryCell(fields);});}
+function createWarningInfo(message){return{message:message,icon:String.fromCharCode(9888),color:'red'};}
+return{TitleColumn:TitleColumn,MemoryColumn:MemoryColumn,StringMemoryColumn:StringMemoryColumn,NumericMemoryColumn:NumericMemoryColumn,MemoryCell:MemoryCell,expandTableRowsRecursively:expandTableRowsRecursively,aggregateTableRowCellsRecursively:aggregateTableRowCellsRecursively,aggregateTableRowCells:aggregateTableRowCells,createCells:createCells,createWarningInfo:createWarningInfo};});'use strict';Polymer('tr-ui-a-stacked-pane',{rebuild:function(){if(!this.paneDirty_){return;}
+this.paneDirty_=false;this.rebuildPane_();},scheduleRebuildPane_:function(){if(this.paneDirty_)
+return;this.paneDirty_=true;setTimeout(this.rebuild.bind(this),0);},rebuildPane_:function(){},set childPaneBuilder(childPaneBuilder){this.childPaneBuilder_=childPaneBuilder;this.dispatchEvent(new tr.b.Event('request-child-pane-change'));},get childPaneBuilder(){return this.childPaneBuilder_;},appended:function(){this.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ScalarNumeric=tr.v.ScalarNumeric;var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var RowDimension={ROOT:-1,STACK_FRAME:0,OBJECT_TYPE:1};var LATIN_SMALL_LETTER_F_WITH_HOOK=String.fromCharCode(0x0192);var CIRCLED_LATIN_CAPITAL_LETTER_T=String.fromCharCode(0x24C9);function HeapDumpNodeTitleColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
+HeapDumpNodeTitleColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){var title=row.title;var dimension=row.dimension;switch(dimension){case RowDimension.ROOT:return title;case RowDimension.STACK_FRAME:case RowDimension.OBJECT_TYPE:return this.formatSubRow_(title,dimension);default:throw new Error('Invalid row dimension: '+row.dimension);}},cmp:function(rowA,rowB){if(rowA.dimension!==rowB.dimension)
+return rowA.dimension-rowB.dimension;return tr.ui.analysis.TitleColumn.prototype.cmp.call(this,rowA,rowB);},formatSubRow_:function(title,dimension){var titleEl=document.createElement('span');var symbolEl=document.createElement('span');var symbolColorName;if(dimension===RowDimension.STACK_FRAME){symbolEl.textContent=LATIN_SMALL_LETTER_F_WITH_HOOK;symbolEl.title='Stack frame';symbolColorName='heap_dump_stack_frame';}else{symbolEl.textContent=CIRCLED_LATIN_CAPITAL_LETTER_T;symbolEl.title='Object type';symbolColorName='heap_dump_object_type';}
+symbolEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString(symbolColorName);symbolEl.style.paddingRight='4px';symbolEl.style.cursor='help';symbolEl.style.weight='bold';titleEl.appendChild(symbolEl);titleEl.appendChild(document.createTextNode(title));return titleEl;}};var COLUMN_RULES=[{importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn}];Polymer('tr-ui-a-memory-dump-heap-details-pane',{created:function(){this.heapDumps_=undefined;this.aggregationMode_=undefined;this.viewMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.info_bar.message='Note: Values displayed in the heavy view '+'are lower bounds (except for the root).';this.$.view_mode_container.appendChild(tr.ui.b.createSelector(this,'viewMode','memoryDumpHeapDetailsPane.viewMode',tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:tr.b.MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW}]));},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},get heapDumps(){return this.heapDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},set viewMode(viewMode){this.viewMode_=viewMode;this.scheduleRebuildPane_();},get viewMode(){return this.viewMode_;},get heavyView(){switch(this.viewMode){case tr.b.MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW:case tr.b.MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW:return true;default:return false;}},rebuildPane_:function(){if(this.heapDumps_===undefined||this.heapDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.view_mode_container.style.display='none';this.$.info_bar.visible=false;this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';this.$.view_mode_container.style.display='block';this.$.info_bar.visible=this.heavyView;var stackFrameTrees=this.createStackFrameTrees_(this.heapDumps_);var rows=this.createRows_(stackFrameTrees);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createStackFrameTrees_:function(heapDumps){return heapDumps.map(function(heapDump){if(heapDump===undefined)
+return undefined;var builder=new tr.b.MultiDimensionalViewBuilder(2);heapDump.entries.forEach(function(entry){var leafStackFrame=entry.leafStackFrame;var stackTracePath=leafStackFrame===undefined?[]:leafStackFrame.getUserFriendlyStackTrace().reverse();var objectTypeName=entry.objectTypeName;var objectTypeNamePath=objectTypeName===undefined?[]:[objectTypeName];builder.addPath([stackTracePath,objectTypeNamePath],entry.size,tr.b.MultiDimensionalViewBuilder.ValueKind.TOTAL);},this);return builder.buildView(this.viewMode);},this);},createRows_:function(stackFrameTrees){var definedHeapDump=tr.b.findFirstInArray(this.heapDumps);if(definedHeapDump===undefined)
+return[];var rootRowTitle=definedHeapDump.allocatorName;return[this.createHeapRowRecursively_(stackFrameTrees,RowDimension.ROOT,rootRowTitle)];},createHeapRowRecursively_:function(nodes,dimension,title){var cells=tr.ui.analysis.createCells(nodes,function(node){return{'Size':new ScalarNumeric(sizeInBytes_smallerIsBetter,node.total)};});var row={dimension:dimension,title:title,contexts:nodes,cells:cells};var stackFrameSubRows=this.createHeapDimensionSubRowsRecursively_(nodes,RowDimension.STACK_FRAME);var objectTypeSubRows=this.createHeapDimensionSubRowsRecursively_(nodes,RowDimension.OBJECT_TYPE);var subRows=stackFrameSubRows.concat(objectTypeSubRows);if(subRows.length>0)
+row.subRows=subRows;return row;},createHeapDimensionSubRowsRecursively_:function(nodes,dimension){var dimensionGroupedChildNodes=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(nodes,function(node){var childDict={};var displayedChildrenTotal=0;var hasDisplayedChildren=false;for(var child of node.children[dimension].values()){if(!this.heavyView&&child.isLowerBound)
+continue;childDict[child.title[dimension]]=child;displayedChildrenTotal+=child.total;hasDisplayedChildren=true;}
+if(!this.heavyView&&displayedChildrenTotal<node.total&&hasDisplayedChildren){var otherTitle=node.title.slice();otherTitle[dimension]='<other>';childDict['<other>']={title:otherTitle,total:node.total-displayedChildrenTotal,children:[new Map(),new Map()]};}
+return childDict;},this));return dimensionGroupedChildNodes.map(function(subRowNodes){var subRowTitle=tr.b.findFirstInArray(subRowNodes).title[dimension];return this.createHeapRowRecursively_(subRowNodes,dimension,subRowTitle);},this);},createColumns_:function(rows){var titleColumn=new HeapDumpNodeTitleColumn('Stack frame');titleColumn.width='500px';var numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'cells',this.aggregationMode_,COLUMN_RULES);tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);var columns=[titleColumn].concat(numericColumns);return columns;}});return{RowDimension:RowDimension};});'use strict';tr.exportTo('tr.ui.analysis',function(){var SUBALLOCATION_CONTEXT=true;var MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;var PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;var PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;var LEFTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FD);var RIGHTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FE);var EN_DASH=String.fromCharCode(0x2013);var CIRCLED_LATIN_SMALL_LETTER_I=String.fromCharCode(0x24D8);function AllocatorDumpNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Component');}
+AllocatorDumpNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(!row.suballocation)
+return row.title;return tr.ui.b.createSpan({textContent:row.title,italic:true,tooltip:row.fullNames===undefined?undefined:row.fullNames.join(', ')});}};function getAndUpdateEntry(map,name,createdCallback){var entry=map.get(name);if(entry===undefined){entry={count:0};createdCallback(entry);map.set(name,entry);}
+entry.count++;return entry;}
+function SizeInfoMessageBuilder(){this.parts_=[];this.indent_=0;}
+SizeInfoMessageBuilder.prototype={append:function(){this.parts_.push.apply(this.parts_,Array.prototype.slice.apply(arguments));},appendMap:function(map,hasPluralSuffix,emptyText,itemCallback,opt_this){opt_this=opt_this||this;if(map.size===0){if(emptyText)
+this.append(emptyText);}else if(map.size===1){this.parts_.push(' ');var key=map.keys().next().value;itemCallback.call(opt_this,key,map.get(key));}else{if(hasPluralSuffix)
+this.parts_.push('s');this.parts_.push(':');this.indent_++;for(var key of map.keys()){this.parts_.push('\n',' '.repeat(3*(this.indent_-1)),' - ');itemCallback.call(opt_this,key,map.get(key));}
+this.indent_--;}},appendImportanceRange:function(range){this.append(' (importance: ');if(range.min===range.max)
+this.append(range.min);else
+this.append(range.min,EN_DASH,range.max);this.append(')');},appendSizeIfDefined:function(size){if(size!==undefined)
+this.append(' (',tr.v.Unit.byName.sizeInBytes.format(size),')');},appendSomeTimestampsQuantifier:function(){this.append(' ',tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER);},build:function(){return this.parts_.join('');}};function EffectiveSizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+EffectiveSizeColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,addInfos:function(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)
+return;var ownerNameToEntry=new Map();var ownedNameToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
+continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT)
+return;dump.ownedBy.forEach(function(ownerLink){var ownerDump=ownerLink.source;this.getAndUpdateOwnershipEntry_(ownerNameToEntry,ownerDump,ownerLink);},this);var ownedLink=dump.owns;if(ownedLink!==undefined){var ownedDump=ownedLink.target;var ownedEntry=this.getAndUpdateOwnershipEntry_(ownedNameToEntry,ownedDump,ownedLink,true);var sharerNameToEntry=ownedEntry.sharerNameToEntry;ownedDump.ownedBy.forEach(function(sharerLink){var sharerDump=sharerLink.source;if(sharerDump===dump)
+return;this.getAndUpdateOwnershipEntry_(sharerNameToEntry,sharerDump,sharerLink);},this);}}
+if(ownerNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shared by');messageBuilder.appendMap(ownerNameToEntry,false,undefined,function(ownerName,ownerEntry){messageBuilder.append(ownerName);if(ownerEntry.count<numerics.length)
+messageBuilder.appendSomeTimestampsQuantifier();messageBuilder.appendImportanceRange(ownerEntry.importanceRange);},this);infos.push({message:messageBuilder.build(),icon:LEFTWARDS_OPEN_HEADED_ARROW,color:'green'});}
+if(ownedNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shares');messageBuilder.appendMap(ownedNameToEntry,false,undefined,function(ownedName,ownedEntry){messageBuilder.append(ownedName);var ownedCount=ownedEntry.count;if(ownedCount<numerics.length)
+messageBuilder.appendSomeTimestampsQuantifier();messageBuilder.appendImportanceRange(ownedEntry.importanceRange);messageBuilder.append(' with');messageBuilder.appendMap(ownedEntry.sharerNameToEntry,false,' no other dumps',function(sharerName,sharerEntry){messageBuilder.append(sharerName);if(sharerEntry.count<ownedCount)
+messageBuilder.appendSomeTimestampsQuantifier();messageBuilder.appendImportanceRange(sharerEntry.importanceRange);},this);},this);infos.push({message:messageBuilder.build(),icon:RIGHTWARDS_OPEN_HEADED_ARROW,color:'green'});}},getAndUpdateOwnershipEntry_:function(map,dump,link,opt_withSharerNameToEntry){var entry=getAndUpdateEntry(map,dump.quantifiedName,function(newEntry){newEntry.importanceRange=new tr.b.Range();if(opt_withSharerNameToEntry)
+newEntry.sharerNameToEntry=new Map();});entry.importanceRange.addValue(link.importance||0);return entry;}};function SizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+SizeColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,addInfos:function(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)
+return;this.addOverlapInfo_(numerics,memoryAllocatorDumps,infos);this.addProvidedSizeWarningInfos_(numerics,memoryAllocatorDumps,infos);},addOverlapInfo_:function(numerics,memoryAllocatorDumps,infos){var siblingNameToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
+continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT)
+return;var ownedBySiblingSizes=dump.ownedBySiblingSizes;for(var siblingDump of ownedBySiblingSizes.keys()){var siblingName=siblingDump.name;getAndUpdateEntry(siblingNameToEntry,siblingName,function(newEntry){if(numerics.length===1)
+newEntry.size=ownedBySiblingSizes.get(siblingDump);});}}
+if(siblingNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('overlaps with its sibling');messageBuilder.appendMap(siblingNameToEntry,true,undefined,function(siblingName,siblingEntry){messageBuilder.append('\'',siblingName,'\'');messageBuilder.appendSizeIfDefined(siblingEntry.size);if(siblingEntry.count<numerics.length)
+messageBuilder.appendSomeTimestampsQuantifier();},this);infos.push({message:messageBuilder.build(),icon:CIRCLED_LATIN_SMALL_LETTER_I,color:'blue'});}},addProvidedSizeWarningInfos_:function(numerics,memoryAllocatorDumps,infos){var infoTypeToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
+continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT)
+return;dump.infos.forEach(function(dumpInfo){getAndUpdateEntry(infoTypeToEntry,dumpInfo.type,function(newEntry){if(numerics.length===1){newEntry.providedSize=dumpInfo.providedSize;newEntry.dependencySize=dumpInfo.dependencySize;}});});}
+for(var infoType of infoTypeToEntry.keys()){var entry=infoTypeToEntry.get(infoType);var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('provided size');messageBuilder.appendSizeIfDefined(entry.providedSize);var dependencyName;switch(infoType){case PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:dependencyName='the aggregated size of the children';break;case PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:dependencyName='the size of the largest owner';break;default:dependencyName='an unknown dependency';break;}
+messageBuilder.append(' was less than ',dependencyName);messageBuilder.appendSizeIfDefined(entry.dependencySize);if(entry.count<numerics.length)
+messageBuilder.appendSomeTimestampsQuantifier();infos.push(tr.ui.analysis.createWarningInfo(messageBuilder.build()));}}};var NUMERIC_COLUMN_RULES=[{condition:tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME,importance:10,columnConstructor:EffectiveSizeColumn},{condition:tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME,importance:9,columnConstructor:SizeColumn},{condition:'page_size',importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:/size/,importance:5,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn}];var DIAGNOSTIC_COLUMN_RULES=[{importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];Polymer('tr-ui-a-memory-dump-allocator-details-pane',{created:function(){this.memoryAllocatorDumps_=undefined;this.heapDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.scheduleRebuildPane_();},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){if(this.memoryAllocatorDumps_===undefined||this.memoryAllocatorDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();this.childPaneBuilder=undefined;return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);rows.forEach(function(rootRow){tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,columns,function(contexts){return contexts!==undefined&&contexts.some(function(context){return context===SUBALLOCATION_CONTEXT;});});});this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);if(this.heapDumps_===undefined){this.childPaneBuilder=undefined;}else{this.childPaneBuilder=function(){var pane=document.createElement('tr-ui-a-memory-dump-heap-details-pane');pane.heapDumps=this.heapDumps_;pane.aggregationMode=this.aggregationMode_;return pane;}.bind(this);}},createRows_:function(){return[this.createAllocatorRowRecursively_(this.memoryAllocatorDumps_)];},createAllocatorRowRecursively_:function(dumps){var definedDump=tr.b.findFirstInArray(dumps);var title=definedDump.name;var fullName=definedDump.fullName;var numericCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.numerics;});var diagnosticCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.diagnostics;});var suballocatedBy=undefined;if(title.startsWith('__')){for(var i=0;i<dumps.length;i++){var dump=dumps[i];if(dump===undefined||dump.ownedBy.length===0){continue;}
+var ownerDump=dump.ownedBy[0].source;if(dump.ownedBy.length>1||dump.children.length>0||ownerDump.containerMemoryDump!==dump.containerMemoryDump){suballocatedBy=undefined;break;}
+if(suballocatedBy===undefined){suballocatedBy=ownerDump.fullName;}else if(suballocatedBy!==ownerDump.fullName){suballocatedBy=undefined;break;}}}
+var row={title:title,fullNames:[fullName],contexts:dumps,numericCells:numericCells,diagnosticCells:diagnosticCells,suballocatedBy:suballocatedBy};var childDumpNameToDumps=tr.b.invertArrayOfDicts(dumps,function(dump){return tr.b.arrayToDict(dump.children,function(child){return child.name;});});var subRows=[];var suballocationClassificationRootNode=undefined;tr.b.iterItems(childDumpNameToDumps,function(childName,childDumps){var childRow=this.createAllocatorRowRecursively_(childDumps);if(childRow.suballocatedBy===undefined){subRows.push(childRow);}else{suballocationClassificationRootNode=this.classifySuballocationRow_(childRow,suballocationClassificationRootNode);}},this);if(suballocationClassificationRootNode!==undefined){var suballocationRow=this.createSuballocationRowRecursively_('suballocations',suballocationClassificationRootNode);subRows.push(suballocationRow);}
+if(subRows.length>0)
+row.subRows=subRows;return row;},classifySuballocationRow_:function(suballocationRow,rootNode){if(rootNode===undefined){rootNode={children:{},row:undefined};}
+var suballocationLevels=suballocationRow.suballocatedBy.split('/');var currentNode=rootNode;for(var i=0;i<suballocationLevels.length;i++){var suballocationLevel=suballocationLevels[i];var nextNode=currentNode.children[suballocationLevel];if(nextNode===undefined){currentNode.children[suballocationLevel]=nextNode={children:{},row:undefined};}
+var currentNode=nextNode;}
+var existingRow=currentNode.row;if(existingRow!==undefined){for(var i=0;i<suballocationRow.contexts.length;i++){var newContext=suballocationRow.contexts[i];if(newContext===undefined)
+continue;if(existingRow.contexts[i]!==undefined)
+throw new Error('Multiple suballocations with the same owner name');existingRow.contexts[i]=newContext;['numericCells','diagnosticCells'].forEach(function(cellKey){var suballocationCells=suballocationRow[cellKey];if(suballocationCells===undefined)
+return;tr.b.iterItems(suballocationCells,function(cellName,cell){if(cell===undefined)
+return;var fields=cell.fields;if(fields===undefined)
+return;var field=fields[i];if(field===undefined)
+return;var existingCells=existingRow[cellKey];if(existingCells===undefined){existingCells={};existingRow[cellKey]=existingCells;}
+var existingCell=existingCells[cellName];if(existingCell===undefined){existingCell=new tr.ui.analysis.MemoryCell(new Array(fields.length));existingCells[cellName]=existingCell;}
+existingCell.fields[i]=field;});});}
+existingRow.fullNames.push.apply(existingRow.fullNames,suballocationRow.fullNames);}else{currentNode.row=suballocationRow;}
+return rootNode;},createSuballocationRowRecursively_:function(name,node){var childCount=Object.keys(node.children).length;if(childCount===0){if(node.row===undefined)
+throw new Error('Suballocation node must have a row or children');var row=node.row;row.title=name;row.suballocation=true;return row;}
+var subRows=tr.b.dictionaryValues(tr.b.mapItems(node.children,this.createSuballocationRowRecursively_,this));if(node.row!==undefined){var row=node.row;row.title='<unspecified>';row.suballocation=true;subRows.unshift(row);}
+var contexts=new Array(subRows[0].contexts.length);for(var i=0;i<subRows.length;i++){subRows[i].contexts.forEach(function(subContext,index){if(subContext!==undefined)
+contexts[index]=SUBALLOCATION_CONTEXT;});}
+return{title:name,suballocation:true,contexts:contexts,subRows:subRows};},createColumns_:function(rows){var titleColumn=new AllocatorDumpNameColumn();titleColumn.width='200px';var numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'numericCells',this.aggregationMode_,NUMERIC_COLUMN_RULES);var diagnosticColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'diagnosticCells',this.aggregationMode_,DIAGNOSTIC_COLUMN_RULES);var fieldColumns=numericColumns.concat(diagnosticColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);var columns=[titleColumn].concat(fieldColumns);return columns;}});return{SUBALLOCATION_CONTEXT:SUBALLOCATION_CONTEXT,AllocatorDumpNameColumn:AllocatorDumpNameColumn,EffectiveSizeColumn:EffectiveSizeColumn,SizeColumn:SizeColumn};});'use strict';tr.exportTo('tr.ui.analysis',function(){var ScalarNumeric=tr.v.ScalarNumeric;var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var CONSTANT_COLUMN_RULES=[{condition:'Start address',importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];var VARIABLE_COLUMN_RULES=[{condition:'Virtual size',importance:7,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Protection flags',importance:6,columnConstructor:tr.ui.analysis.StringMemoryColumn},{condition:'PSS',importance:5,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Private dirty',importance:4,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Private clean',importance:3,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Shared dirty',importance:2,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Shared clean',importance:1,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Swapped',importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn}];var BYTE_STAT_COLUMN_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','privateCleanResident':'Private clean','sharedDirtyResident':'Shared dirty','sharedCleanResident':'Shared clean','swapped':'Swapped'};function hexString(address,is64BitAddress){if(address===undefined)
+return undefined;var hexPadding=is64BitAddress?'0000000000000000':'00000000';return(hexPadding+address.toString(16)).substr(-hexPadding.length);}
+function pruneEmptyRuleRows(row){if(row.subRows===undefined||row.subRows.length===0)
+return;if(row.subRows[0].rule===undefined){return;}
+row.subRows.forEach(pruneEmptyRuleRows);row.subRows=row.subRows.filter(function(subRow){return subRow.subRows.length>0;});}
+Polymer('tr-ui-a-memory-dump-vm-regions-details-pane',{created:function(){this.vmRegions_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set vmRegions(vmRegions){this.vmRegions_=vmRegions;this.scheduleRebuildPane_();},get vmRegions(){return this.vmRegions_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){if(this.vmRegions_===undefined||this.vmRegions_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_(this.vmRegions_);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createRows_:function(timeToVmRegionTree){var is64BitAddress=timeToVmRegionTree.some(function(vmRegionTree){if(vmRegionTree===undefined)
+return false;return vmRegionTree.someRegion(function(region){if(region.startAddress===undefined)
+return false;return region.startAddress>=4294967296;});});return[this.createClassificationNodeRow(timeToVmRegionTree,is64BitAddress)];},createClassificationNodeRow:function(timeToNode,is64BitAddress){var definedNode=tr.b.findFirstInArray(timeToNode);var childNodeIdToTimeToNode=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToNode,function(node){var children=node.children;if(children===undefined)
+return undefined;var childMap={};children.forEach(function(childNode){if(!childNode.hasRegions)
+return;childMap[childNode.title]=childNode;});return childMap;}));var childNodeSubRows=childNodeIdToTimeToNode.map(function(timeToChildNode){return this.createClassificationNodeRow(timeToChildNode,is64BitAddress);},this);var regionIdToTimeToRegion=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToNode,function(node){var regions=node.regions;if(regions===undefined)
+return undefined;return tr.b.arrayToDict(regions,function(region){return region.uniqueIdWithinProcess;});}));var regionSubRows=regionIdToTimeToRegion.map(function(timeToRegion){return this.createRegionRow_(timeToRegion,is64BitAddress);},this);var subRows=childNodeSubRows.concat(regionSubRows);return{title:definedNode.title,contexts:timeToNode,variableCells:this.createVariableCells_(timeToNode),subRows:subRows};},createRegionRow_:function(timeToRegion,is64BitAddress){var definedRegion=tr.b.findFirstInArray(timeToRegion);return{title:definedRegion.mappedFile,contexts:timeToRegion,constantCells:this.createConstantCells_(definedRegion,is64BitAddress),variableCells:this.createVariableCells_(timeToRegion)};},createConstantCells_:function(definedRegion,is64BitAddress){return tr.ui.analysis.createCells([definedRegion],function(region){var startAddress=region.startAddress;if(startAddress===undefined)
+return undefined;return{'Start address':hexString(startAddress,is64BitAddress)};});},createVariableCells_:function(timeToRegion){return tr.ui.analysis.createCells(timeToRegion,function(region){var fields={};var sizeInBytes=region.sizeInBytes;if(sizeInBytes!==undefined){fields['Virtual size']=new ScalarNumeric(sizeInBytes_smallerIsBetter,sizeInBytes);}
+var protectionFlags=region.protectionFlagsToString;if(protectionFlags!==undefined)
+fields['Protection flags']=protectionFlags;tr.b.iterItems(BYTE_STAT_COLUMN_MAP,function(byteStatName,columnName){var byteStat=region.byteStats[byteStatName];if(byteStat===undefined)
+return;fields[columnName]=new ScalarNumeric(sizeInBytes_smallerIsBetter,byteStat);});return fields;});},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.TitleColumn('Mapped file');titleColumn.width='200px';var constantColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'constantCells',undefined,CONSTANT_COLUMN_RULES);var variableColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'variableCells',this.aggregationMode_,VARIABLE_COLUMN_RULES);var fieldColumns=constantColumns.concat(variableColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);var columns=[titleColumn].concat(fieldColumns);return columns;}});return{};});'use strict';Polymer('tr-ui-b-color-legend',{ready:function(){var blackSquareCharCode=9632;this.$.square.innerText=String.fromCharCode(blackSquareCharCode);this.label_=undefined;this.compoundEventSelectionState_=tr.model.CompoundEventSelectionState.NOT_SELECTED;},set compoundEventSelectionState(compoundEventSelectionState){this.compoundEventSelectionState_=compoundEventSelectionState;},get label(){return this.label_;},set label(label){if(label===undefined){this.setLabelAndColorId(undefined,undefined);return;}
+var colorId=tr.b.ColorScheme.getColorIdForGeneralPurposeString(label);this.setLabelAndColorId(label,colorId);},setLabelAndColorId:function(label,colorId){this.label_=label;this.$.label.textContent='';this.$.label.appendChild(tr.ui.b.asHTMLOrTextNode(label));if(colorId===undefined)
+this.$.square.style.color='initial';else
+this.$.square.style.color=tr.b.ColorScheme.colorsAsStrings[colorId];}});'use strict';Polymer('tr-ui-b-view-specific-brushing-state',{get viewId(){return this.getAttribute('view-id');},set viewId(viewId){this.setAttribute('view-id',viewId);},get:function(){var viewId=this.viewId;if(!viewId)
+throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
+return undefined;return brushingStateController.getViewSpecificBrushingState(viewId);},set:function(state){var viewId=this.viewId;if(!viewId)
+throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
+return;brushingStateController.changeViewSpecificBrushingState(viewId,state);}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ColorScheme=tr.b.ColorScheme;var ScalarNumeric=tr.v.ScalarNumeric;var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX='_bytes';var DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;var SOME_TIMESTAMPS_INFO_QUANTIFIER=tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER;var RIGHTWARDS_ARROW_WITH_HOOK=String.fromCharCode(0x21AA);var RIGHTWARDS_ARROW_FROM_BAR=String.fromCharCode(0x21A6);var GREATER_THAN_OR_EQUAL_TO=String.fromCharCode(0x2265);var UNMARRIED_PARTNERSHIP_SYMBOL=String.fromCharCode(0x26AF);var TRIGRAM_FOR_HEAVEN=String.fromCharCode(0x2630);function lazyMap(list,fn,opt_this){opt_this=opt_this||this;var result=undefined;list.forEach(function(item,index){var value=fn.call(opt_this,item,index);if(value===undefined)
+return;if(result===undefined)
+result=new Array(list.length);result[index]=value;});return result;}
+function ProcessNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Process');}
+ProcessNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(row.contexts===undefined)
+return row.title;var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=row.title;return titleEl;}};function UsedMemoryColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+UsedMemoryColumn.COLOR=ColorScheme.getColorForReservedNameAsString('used_memory_column');UsedMemoryColumn.OLDER_COLOR=ColorScheme.getColorForReservedNameAsString('older_used_memory_column');UsedMemoryColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:UsedMemoryColumn.COLOR});},color:function(numerics,processMemoryDumps){return UsedMemoryColumn.COLOR;},getChildPaneBuilder:function(processMemoryDumps){if(processMemoryDumps===undefined)
+return undefined;var vmRegions=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)
+return undefined;return pmd.mostRecentVmRegions;});if(vmRegions===undefined)
+return undefined;return function(){var pane=document.createElement('tr-ui-a-memory-dump-vm-regions-details-pane');pane.vmRegions=vmRegions;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function PeakMemoryColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
+PeakMemoryColumn.prototype={__proto__:UsedMemoryColumn.prototype,addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)
+return;var resettableValueCount=0;var nonResettableValueCount=0;for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
+continue;if(processMemoryDumps[i].arePeakResidentBytesResettable)
+resettableValueCount++;else
+nonResettableValueCount++;}
+if(resettableValueCount>0&&nonResettableValueCount>0){infos.push(tr.ui.analysis.createWarningInfo('Both resettable and '+'non-resettable peak RSS values were provided by the process'));}else if(resettableValueCount>0){infos.push({icon:RIGHTWARDS_ARROW_WITH_HOOK,message:'Peak RSS since previous memory dump.'});}else{infos.push({icon:RIGHTWARDS_ARROW_FROM_BAR,message:'Peak RSS since process startup. Finer grained '+'peaks require a Linux kernel version '+
+GREATER_THAN_OR_EQUAL_TO+' 4.0.'});}}};function ByteStatColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
+ByteStatColumn.prototype={__proto__:UsedMemoryColumn.prototype,color:function(numerics,processMemoryDumps){if(processMemoryDumps===undefined)
+return UsedMemoryColumn.COLOR;var allOlderValues=processMemoryDumps.every(function(processMemoryDump){if(processMemoryDump===undefined)
+return true;return!processMemoryDump.hasOwnVmRegions;});if(allOlderValues)
+return UsedMemoryColumn.OLDER_COLOR;else
+return UsedMemoryColumn.COLOR;},addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)
+return;var olderValueCount=0;for(var i=0;i<numerics.length;i++){var processMemoryDump=processMemoryDumps[i];if(processMemoryDump!==undefined&&!processMemoryDump.hasOwnVmRegions){olderValueCount++;}}
+if(olderValueCount===0)
+return;var infoQuantifier=olderValueCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Older value'+infoQuantifier+' (only heavy (purple) memory dumps contain memory maps).',icon:UNMARRIED_PARTNERSHIP_SYMBOL});}};UsedMemoryColumn.RULES=[{condition:'Total resident',importance:10,columnConstructor:UsedMemoryColumn},{condition:'Peak total resident',importance:9,columnConstructor:PeakMemoryColumn},{condition:'PSS',importance:8,columnConstructor:ByteStatColumn},{condition:'Private dirty',importance:7,columnConstructor:ByteStatColumn},{condition:'Swapped',importance:6,columnConstructor:ByteStatColumn},{importance:0,columnConstructor:UsedMemoryColumn}];UsedMemoryColumn.TOTALS_MAP={'residentBytes':'Total resident','peakResidentBytes':'Peak total resident'};UsedMemoryColumn.BYTE_STAT_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','swapped':'Swapped'};function AllocatorColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+AllocatorColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=this.name;return titleEl;},addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)
+return;var heapDumpCount=0;for(var i=0;i<processMemoryDumps.length;i++){var processMemoryDump=processMemoryDumps[i];if(processMemoryDump===undefined)
+continue;var heapDumps=processMemoryDump.heapDumps;if(heapDumps===undefined)
+continue;if(heapDumps[this.name]!==undefined)
+heapDumpCount++;}
+if(heapDumpCount===0)
+return;var infoQuantifier=heapDumpCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Heap dump provided'+infoQuantifier+'.',icon:TRIGRAM_FOR_HEAVEN});},getChildPaneBuilder:function(processMemoryDumps){if(processMemoryDumps===undefined)
+return undefined;var memoryAllocatorDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)
+return undefined;return pmd.getMemoryAllocatorDumpByFullName(this.name);},this);if(memoryAllocatorDumps===undefined)
+return undefined;var heapDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined||pmd.heapDumps===undefined)
+return undefined;return pmd.heapDumps[this.name];},this);return function(){var pane=document.createElement('tr-ui-a-memory-dump-allocator-details-pane');pane.memoryAllocatorDumps=memoryAllocatorDumps;pane.heapDumps=heapDumps;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function TracingColumn(name,cellPath,aggregationMode){AllocatorColumn.call(this,name,cellPath,aggregationMode);}
+TracingColumn.COLOR=ColorScheme.getColorForReservedNameAsString('tracing_memory_column');TracingColumn.prototype={__proto__:AllocatorColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:TracingColumn.COLOR});},color:function(numerics,processMemoryDumps){return TracingColumn.COLOR;}};AllocatorColumn.RULES=[{condition:'tracing',importance:0,columnConstructor:TracingColumn},{importance:1,columnConstructor:AllocatorColumn}];Polymer('tr-ui-a-memory-dump-overview-pane',{created:function(){this.processMemoryDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.CELL;this.$.table.addEventListener('selection-changed',function(tableEvent){tableEvent.stopPropagation();this.changeChildPane_();}.bind(this));},set processMemoryDumps(processMemoryDumps){this.processMemoryDumps_=processMemoryDumps;this.scheduleRebuildPane_();},get processMemoryDumps(){return this.processMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},get selectedMemoryCell(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
+var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)
+return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)
+return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];var selectedMemoryCell=selectedColumn.cell(selectedTableRow);return selectedMemoryCell;},changeChildPane_:function(){this.storeSelection_();this.childPaneBuilder=this.determineChildPaneBuilderFromSelection_();},determineChildPaneBuilderFromSelection_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
+var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)
+return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)
+return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];return selectedColumn.getChildPaneBuilder(selectedTableRow.contexts);},rebuildPane_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);var footerRows=this.createFooterRows_(rows,columns);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.tableColumns=columns;this.$.table.rebuild();this.restoreSelection_();},createRows_:function(){var timeToPidToProcessMemoryDump=this.processMemoryDumps_;var pidToTimeToProcessMemoryDump=tr.b.invertArrayOfDicts(timeToPidToProcessMemoryDump);return tr.b.dictionaryValues(tr.b.mapItems(pidToTimeToProcessMemoryDump,function(pid,timeToDump){var process=tr.b.findFirstInArray(timeToDump).process;var usedMemoryCells=tr.ui.analysis.createCells(timeToDump,function(dump){var sizes={};var totals=dump.totals;if(totals!==undefined){tr.b.iterItems(UsedMemoryColumn.TOTALS_MAP,function(totalName,cellName){var total=totals[totalName];if(total===undefined)
+return;sizes[cellName]=new ScalarNumeric(sizeInBytes_smallerIsBetter,total);});var platformSpecific=totals.platformSpecific;if(platformSpecific!==undefined){tr.b.iterItems(platformSpecific,function(name,size){if(name.endsWith(PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX)){name=name.substring(0,name.length-
+PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX.length);}
+name=name.replace('_',' ').trim();name=name.charAt(0).toUpperCase()+name.slice(1);sizes[name]=new ScalarNumeric(sizeInBytes_smallerIsBetter,size);});}}
+var vmRegions=dump.mostRecentVmRegions;if(vmRegions!==undefined){tr.b.iterItems(UsedMemoryColumn.BYTE_STAT_MAP,function(byteStatName,cellName){var byteStat=vmRegions.byteStats[byteStatName];if(byteStat===undefined)
+return;sizes[cellName]=new ScalarNumeric(sizeInBytes_smallerIsBetter,byteStat);});}
+return sizes;});var allocatorCells=tr.ui.analysis.createCells(timeToDump,function(dump){var memoryAllocatorDumps=dump.memoryAllocatorDumps;if(memoryAllocatorDumps===undefined)
+return undefined;var sizes={};memoryAllocatorDumps.forEach(function(allocatorDump){var rootDisplayedSizeNumeric=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(rootDisplayedSizeNumeric!==undefined)
+sizes[allocatorDump.fullName]=rootDisplayedSizeNumeric;});return sizes;});return{title:process.userFriendlyName,contexts:timeToDump,usedMemoryCells:usedMemoryCells,allocatorCells:allocatorCells};}));},createFooterRows_:function(rows,columns){if(rows.length<=1)
+return[];var totalRow={title:'Total'};tr.ui.analysis.aggregateTableRowCells(totalRow,rows,columns);return[totalRow];},createColumns_:function(rows){var titleColumn=new ProcessNameColumn();titleColumn.width='200px';var usedMemorySizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'usedMemoryCells',this.aggregationMode_,UsedMemoryColumn.RULES);var allocatorSizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'allocatorCells',this.aggregationMode_,AllocatorColumn.RULES);var sizeColumns=usedMemorySizeColumns.concat(allocatorSizeColumns);tr.ui.analysis.MemoryColumn.spaceEqually(sizeColumns);var columns=[titleColumn].concat(sizeColumns);return columns;},storeSelection_:function(){var selectedRowTitle;var selectedRow=this.$.table.selectedTableRow;if(selectedRow!==undefined)
+selectedRowTitle=selectedRow.title;var selectedColumnName;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex!==undefined){var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];selectedColumnName=selectedColumn.name;}
+this.$.state.set({rowTitle:selectedRowTitle,columnName:selectedColumnName});},restoreSelection_:function(){var settings=this.$.state.get();if(settings===undefined||settings.rowTitle===undefined||settings.columnName===undefined)
+return;var selectedColumnName=settings.columnName;var selectedColumnIndex=tr.b.findFirstIndexInArray(this.$.table.tableColumns,function(column){return column.name===selectedColumnName;});if(selectedColumnIndex<0)
+return;var selectedRowTitle=settings.rowTitle;var selectedRow=tr.b.findFirstInArray(this.$.table.tableRows,function(row){return row.title===selectedRowTitle;});if(selectedRow===undefined)
+return;this.$.table.selectedTableRow=selectedRow;this.$.table.selectedColumnIndex=selectedColumnIndex;}});return{ProcessNameColumn:ProcessNameColumn,UsedMemoryColumn:UsedMemoryColumn,PeakMemoryColumn:PeakMemoryColumn,ByteStatColumn:ByteStatColumn,AllocatorColumn:AllocatorColumn,TracingColumn:TracingColumn};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-memory-dump-header-pane',{created:function(){this.containerMemoryDumps_=undefined;},ready:function(){this.$.aggregation_mode_container.appendChild(tr.ui.b.createSelector(this,'aggregationMode','memoryDumpHeaderPane.aggregationMode',tr.ui.analysis.MemoryColumn.AggregationMode.DIFF,[{label:'Diff',value:tr.ui.analysis.MemoryColumn.AggregationMode.DIFF},{label:'Max',value:tr.ui.analysis.MemoryColumn.AggregationMode.MAX}]));},set containerMemoryDumps(containerMemoryDumps){this.containerMemoryDumps_=containerMemoryDumps;this.scheduleRebuildPane_();},get containerMemoryDumps(){return this.containerMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){this.updateLabel_();this.updateAggregationModeSelector_();this.changeChildPane_();},updateLabel_:function(){this.$.label.textContent='';if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){this.$.label.textContent='No memory dumps selected';return;}
+var containerDumpCount=this.containerMemoryDumps_.length;var isMultiSelection=containerDumpCount>1;this.$.label.appendChild(document.createTextNode('Selected '+containerDumpCount+' memory dump'+
+(isMultiSelection?'s':'')+' in '+this.containerMemoryDumps_[0].containerName+' at '));this.$.label.appendChild(document.createTextNode(tr.v.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[0].start)));if(isMultiSelection){var ELLIPSIS=String.fromCharCode(8230);this.$.label.appendChild(document.createTextNode(ELLIPSIS));this.$.label.appendChild(document.createTextNode(tr.v.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[containerDumpCount-1].start)));}},updateAggregationModeSelector_:function(){var displayStyle;if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=1)
+displayStyle='none';else
+displayStyle='initial';this.$.aggregation_mode_container.style.display=displayStyle;},changeChildPane_:function(){this.childPaneBuilder=function(){if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0)
+return undefined;var overviewPane=document.createElement('tr-ui-a-memory-dump-overview-pane');overviewPane.processMemoryDumps=this.containerMemoryDumps_.map(function(containerDump){return containerDump.processMemoryDumps;});overviewPane.aggregationMode=this.aggregationMode;return overviewPane;}.bind(this);}});return{};});'use strict';Polymer('tr-ui-a-stacked-pane-view',{setPaneBuilder:function(paneBuilder,opt_parentPane){var paneContainer=this.$.pane_container;if(opt_parentPane){if(!(opt_parentPane instanceof HTMLElement))
+throw new Error('Parent pane must be an HTML element');if(opt_parentPane.parentElement!==paneContainer)
+throw new Error('Parent pane must be a child of the pane container');}
+while(paneContainer.lastElementChild!==null&&paneContainer.lastElementChild!==opt_parentPane){var removedPane=this.$.pane_container.lastElementChild;var listener=this.listeners_.get(removedPane);if(listener===undefined)
+throw new Error('No listener associated with pane');this.listeners_.delete(removedPane);removedPane.removeEventListener('request-child-pane-change',listener);paneContainer.removeChild(removedPane);}
+if(opt_parentPane&&opt_parentPane.parentElement!==paneContainer)
+throw new Error('Parent pane was removed from the pane container');if(!paneBuilder)
+return;var pane=paneBuilder();if(!pane)
+return;if(!(pane instanceof HTMLElement))
+throw new Error('Pane must be an HTML element');var listener=function(event){this.setPaneBuilder(pane.childPaneBuilder,pane);}.bind(this);if(!this.listeners_){this.listeners_=new WeakMap();}
+this.listeners_.set(pane,listener);pane.addEventListener('request-child-pane-change',listener);paneContainer.appendChild(pane);pane.appended();},rebuild:function(){var currentPane=this.$.pane_container.firstElementChild;while(currentPane){currentPane.rebuild();currentPane=currentPane.nextElementSibling;}},get panesForTesting(){var panes=[];var currentChild=this.$.pane_container.firstElementChild;while(currentChild){panes.push(currentChild);currentChild=currentChild.nextElementSibling;}
+return panes;}});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-container-memory-dump-sub-view',{set selection(selection){if(selection===undefined){this.currentSelection_=undefined;this.dumpsByContainerName_=undefined;this.updateContents_();return;}
+selection.forEach(function(event){if(!(event instanceof tr.model.ContainerMemoryDump)){throw new Error('Memory dump sub-view only supports container memory dumps');}});this.currentSelection_=selection;this.dumpsByContainerName_=tr.b.group(this.currentSelection_.toArray(),function(dump){return dump.containerName;});tr.b.iterItems(this.dumpsByContainerName_,function(containerName,dumps){dumps.sort(function(a,b){return a.start-b.start;});});this.updateContents_();},get selection(){return this.currentSelection_;},get requiresTallView(){return true;},updateContents_:function(){this.$.content.textContent='';if(this.dumpsByContainerName_===undefined)
+return;var containerNames=Object.keys(this.dumpsByContainerName_);if(containerNames.length===0)
+return;if(containerNames.length>1)
+this.buildViewForMultipleContainerNames_();else
+this.buildViewForSingleContainerName_();},buildViewForSingleContainerName_:function(){var containerMemoryDumps=tr.b.dictionaryValues(this.dumpsByContainerName_)[0];var dumpView=this.ownerDocument.createElement('tr-ui-a-stacked-pane-view');this.$.content.appendChild(dumpView);dumpView.setPaneBuilder(function(){var headerPane=document.createElement('tr-ui-a-memory-dump-header-pane');headerPane.containerMemoryDumps=containerMemoryDumps;return headerPane;});},buildViewForMultipleContainerNames_:function(){var ownerDocument=this.ownerDocument;var rows=tr.b.dictionaryValues(tr.b.mapItems(this.dumpsByContainerName_,function(containerName,dumps){return{containerName:containerName,subRows:dumps,isExpanded:true};}));rows.sort(function(a,b){return a.containerName.localeCompare(b.containerName);});var columns=[{title:'Dump',value:function(row){if(row.subRows===undefined)
+return this.singleDumpValue_(row);else
+return this.groupedDumpValue_(row);},singleDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([row]));linkEl.appendChild(tr.v.ui.createScalarSpan(row.start,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:ownerDocument}));return linkEl;},groupedDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(row.subRows));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.subRows.length+' memory dump'+
+(row.subRows.length===1?'':'s')+' in '}));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.containerName,bold:true}));return linkEl;}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.tableColumns=columns;table.tableRows=rows;table.showHeader=false;table.rebuild();this.$.content.appendChild(table);}});return{};});'use strict';(function(){var COUNTER_SAMPLE_TABLE_COLUMNS=[{title:'Counter',width:'150px',value:function(row){return row.counter;}},{title:'Series',width:'150px',value:function(row){return row.series;}},{title:'Time',width:'150px',value:function(row){return row.start;}},{title:'Value',width:'100%',value:function(row){return row.value;}}];Polymer('tr-ui-a-counter-sample-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=COUNTER_SAMPLE_TABLE_COLUMNS;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.selection?this.getRows_(this.selection.toArray()):[];this.$.table.rebuild();},getRows_:function(samples){var samplesByCounter=tr.b.group(samples,function(sample){return sample.series.counter.guid;});var rows=[];tr.b.iterItems(samplesByCounter,function(unused,counterSamples){var samplesBySeries=tr.b.group(counterSamples,function(sample){return sample.series.guid;});tr.b.iterItems(samplesBySeries,function(unused,seriesSamples){var seriesRows=this.getRowsForSamples_(seriesSamples);seriesRows[0].counter=seriesSamples[0].series.counter.name;seriesRows[0].series=seriesSamples[0].series.name;if(seriesRows.length>1){seriesRows[0].subRows=seriesRows.slice(1);seriesRows[0].isExpanded=true;}
+rows.push(seriesRows[0]);},this);},this);return rows;},getRowsForSamples_:function(samples){return samples.map(function(sample){return{start:sample.timestamp,value:sample.value};});}});})();'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-layout-tree-sub-view',{set selection(selection){this.currentSelection_=selection;this.updateContents_();},get selection(){return this.currentSelection_;},updateContents_:function(){this.$.content.textContent='';if(!this.currentSelection_)
+return;var columns=[{title:'Tag/Name',value:function(layoutObject){return layoutObject.tag||':'+layoutObject.name;}},{title:'htmlId',value:function(layoutObject){return layoutObject.htmlId||'';}},{title:'classNames',value:function(layoutObject){return layoutObject.classNames||'';}},{title:'reasons',value:function(layoutObject){return layoutObject.needsLayoutReasons.join(', ');}},{title:'width',value:function(layoutObject){return layoutObject.absoluteRect.width;}},{title:'height',value:function(layoutObject){return layoutObject.absoluteRect.height;}},{title:'absX',value:function(layoutObject){return layoutObject.absoluteRect.left;}},{title:'absY',value:function(layoutObject){return layoutObject.absoluteRect.top;}},{title:'relX',value:function(layoutObject){return layoutObject.relativeRect.left;}},{title:'relY',value:function(layoutObject){return layoutObject.relativeRect.top;}},{title:'float',value:function(layoutObject){return layoutObject.isFloat?'float':'';}},{title:'positioned',value:function(layoutObject){return layoutObject.isPositioned?'positioned':'';}},{title:'relative',value:function(layoutObject){return layoutObject.isRelativePositioned?'relative':'';}},{title:'sticky',value:function(layoutObject){return layoutObject.isStickyPositioned?'sticky':'';}},{title:'anonymous',value:function(layoutObject){return layoutObject.isAnonymous?'anonymous':'';}},{title:'row',value:function(layoutObject){if(layoutObject.tableRow===undefined)
+return'';return layoutObject.tableRow;}},{title:'col',value:function(layoutObject){if(layoutObject.tableCol===undefined)
+return'';return layoutObject.tableCol;}},{title:'rowSpan',value:function(layoutObject){if(layoutObject.tableRowSpan===undefined)
+return'';return layoutObject.tableRowSpan;}},{title:'colSpan',value:function(layoutObject){if(layoutObject.tableColSpan===undefined)
+return'';return layoutObject.tableColSpan;}},{title:'address',value:function(layoutObject){return layoutObject.id.toString(16);}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.defaultExpansionStateCallback=function(layoutObject,parentLayoutObject){return true;};table.subRowsPropertyName='childLayoutObjects';table.tableColumns=columns;table.tableRows=this.currentSelection_.map(function(snapshot){return snapshot.rootLayoutObject;});table.rebuild();this.$.content.appendChild(table);}});return{};});'use strict';Polymer('tr-ui-a-selection-summary-table',{created:function(){this.selection_=new tr.b.Range();},ready:function(){this.$.table.showHeader=false;this.$.table.tableColumns=[{title:'Name',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;var rows=[];var hasRange;if(this.selection_&&(!selection.bounds.isEmpty))
+hasRange=true;else
+hasRange=false;rows.push({title:'Selection start',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.min,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}):'<empty>'});rows.push({title:'Selection extent',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.range,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument}):'<empty>'});this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){function MultiEventSummary(title,events){this.title=title;this.duration_=undefined;this.selfTime_=undefined;this.events_=events;this.cpuTimesComputed_=false;this.cpuSelfTime_=undefined;this.cpuDuration_=undefined;this.maxDuration_=undefined;this.maxCpuDuration_=undefined;this.maxSelfTime_=undefined;this.maxCpuSelfTime_=undefined;this.untotallableArgs_=[];this.totalledArgs_=undefined;};MultiEventSummary.prototype={set title(title){if(title=='Totals')
+this.totalsRow=true;this.title_=title;},get title(){return this.title_;},get duration(){if(this.duration_===undefined){this.duration_=tr.b.Statistics.sum(this.events_,function(event){return event.duration;});}
+return this.duration_;},get cpuSelfTime(){this.computeCpuTimesIfNeeded_();return this.cpuSelfTime_;},get cpuDuration(){this.computeCpuTimesIfNeeded_();return this.cpuDuration_;},computeCpuTimesIfNeeded_:function(){if(this.cpuTimesComputed_)
+return;this.cpuTimesComputed_=true;var cpuSelfTime=0;var cpuDuration=0;var hasCpuData=false;for(var i=0;i<this.events_.length;i++){var event=this.events_[i];if(event.cpuDuration!==undefined){cpuDuration+=event.cpuDuration;hasCpuData=true;}
+if(event.cpuSelfTime!==undefined){cpuSelfTime+=event.cpuSelfTime;hasCpuData=true;}}
+if(hasCpuData){this.cpuDuration_=cpuDuration;this.cpuSelfTime_=cpuSelfTime;}},get selfTime(){if(this.selfTime_===undefined){this.selfTime_=0;for(var i=0;i<this.events_.length;i++){if(this.events_[i].selfTime!==undefined)
+this.selfTime_+=this.events[i].selfTime;}}
+return this.selfTime_;},get events(){return this.events_;},get numEvents(){return this.events_.length;},get numAlerts(){if(this.numAlerts_===undefined){this.numAlerts_=tr.b.Statistics.sum(this.events_,function(event){return event.associatedAlerts.length;});}
+return this.numAlerts_;},get untotallableArgs(){this.updateArgsIfNeeded_();return this.untotallableArgs_;},get totalledArgs(){this.updateArgsIfNeeded_();return this.totalledArgs_;},get maxDuration(){if(this.maxDuration_===undefined){this.maxDuration_=tr.b.Statistics.max(this.events_,function(event){return event.duration;});}
+return this.maxDuration_;},get maxCpuDuration(){if(this.maxCpuDuration_===undefined){this.maxCpuDuration_=tr.b.Statistics.max(this.events_,function(event){return event.cpuDuration;});}
+return this.maxCpuDuration_;},get maxSelfTime(){if(this.maxSelfTime_===undefined){this.maxSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.selfTime;});}
+return this.maxSelfTime_;},get maxCpuSelfTime(){if(this.maxCpuSelfTime_===undefined){this.maxCpuSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.cpuSelfTime;});}
+return this.maxCpuSelfTime_;},updateArgsIfNeeded_:function(){if(this.totalledArgs_!==undefined)
+return;var untotallableArgs={};var totalledArgs={};for(var i=0;i<this.events_.length;i++){var event=this.events_[i];for(var argName in event.args){var argVal=event.args[argName];var type=typeof argVal;if(type!=='number'){untotallableArgs[argName]=true;delete totalledArgs[argName];continue;}
+if(untotallableArgs[argName]){continue;}
+if(totalledArgs[argName]===undefined)
+totalledArgs[argName]=0;totalledArgs[argName]+=argVal;}}
+this.untotallableArgs_=tr.b.dictionaryKeys(untotallableArgs);this.totalledArgs_=totalledArgs;}};return{MultiEventSummary:MultiEventSummary};});'use strict';Polymer('tr-ui-a-multi-event-summary-table',{ready:function(){this.showTotals_=false;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;this.eventsByTitle_=undefined;},updateTableColumns_:function(rows,maxValues){var hasCpuData=false;var hasAlerts=false;rows.forEach(function(row){if(row.cpuDuration!==undefined)
+hasCpuData=true;if(row.cpuSelfTime!==undefined)
+hasCpuData=true;if(row.numAlerts)
+hasAlerts=true;});var ownerDocument=this.ownerDocument;var columns=[];columns.push({title:'Name',value:function(row){if(row.title==='Totals')
+return'Totals';var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.events);},row.title);return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.title.localeCompare(rowB.title);}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration',value:function(row){return tr.v.ui.createScalarSpan(row.duration,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.duration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
+if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.cpuDuration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time',value:function(row){return tr.v.ui.createScalarSpan(row.selfTime,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.selfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time',value:function(row){return tr.v.ui.createScalarSpan(row.cpuSelfTime,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.cpuSelfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
+columns.push({title:'Occurrences',value:function(row){return row.numEvents;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numEvents-rowB.numEvents;}});var alertsColumnIndex;if(hasAlerts){columns.push({title:'Num Alerts',value:function(row){return row.numAlerts;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numAlerts-rowB.numAlerts;}});alertsColumnIndex=columns.length-1;}
+var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;if(hasAlerts){this.$.table.sortColumnIndex=alertsColumnIndex;this.$.table.sortDescending=true;}},configure:function(config){if(config.eventsByTitle===undefined)
+throw new Error('Required: eventsByTitle');if(config.showTotals!==undefined)
+this.showTotals_=config.showTotals;else
+this.showTotals_=true;if(config.eventsHaveDuration!==undefined)
+this.eventsHaveDuration_=config.eventsHaveDuration;else
+this.eventsHaveDuration_=true;if(config.eventsHaveSubRows!==undefined)
+this.eventsHaveSubRows_=config.eventsHaveSubRows;else
+this.eventsHaveSubRows_=true;this.eventsByTitle_=config.eventsByTitle;this.updateContents_();},get showTotals(){return this.showTotals_;},set showTotals(showTotals){this.showTotals_=showTotals;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get eventsByTitle(){return this.eventsByTitle_;},set eventsByTitle(eventsByTitle){this.eventsByTitle_=eventsByTitle;this.updateContents_();},get selectionBounds(){return this.selectionBounds_;},set selectionBounds(selectionBounds){this.selectionBounds_=selectionBounds;this.updateContents_();},updateContents_:function(){var eventsByTitle;if(this.eventsByTitle_!==undefined)
+eventsByTitle=this.eventsByTitle_;else
+eventsByTitle=[];var allEvents=[];var rows=[];tr.b.iterItems(eventsByTitle,function(title,eventsOfSingleTitle){allEvents.push.apply(allEvents,eventsOfSingleTitle);var row=new tr.ui.analysis.MultiEventSummary(title,eventsOfSingleTitle);rows.push(row);});this.updateTableColumns_(rows);this.$.table.tableRows=rows;var maxValues={duration:undefined,selfTime:undefined,cpuSelfTime:undefined,cpuDuration:undefined};if(this.eventsHaveDuration){for(var column in maxValues){maxValues[column]=tr.b.Statistics.max(rows,function(event){return event[column];});}}
+var footerRows=[];if(this.showTotals_){var multiEventSummary=new tr.ui.analysis.MultiEventSummary('Totals',allEvents);footerRows.push(multiEventSummary);}
+this.updateTableColumns_(rows,maxValues);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-event-details-table',{created:function(){this.selection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},ready:function(){this.initTitleTable_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;this.updateTitleTable_();if(this.selection_===undefined){this.$.table.tableRows=[];this.$.table.tableFooterRows=[];this.$.table.rebuild();return;}
+var summary=new tr.ui.analysis.MultiEventSummary('Totals',this.selection_);this.updateColumns_(summary);this.updateRows_(summary);this.$.table.rebuild();},initTitleTable_:function(){var table=this.$.titletable;table.showHeader=false;table.tableColumns=[{title:'Title',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},updateTitleTable_:function(){var title;if(this.selection_&&this.selection_.length)
+title=this.selection_[0].title;else
+title='<No selection>';var table=this.$.titletable;table.tableRows=[{title:'Title',value:title}];},updateColumns_:function(summary){var hasCpuData;if(summary.cpuDuration!==undefined)
+hasCpuData=true;if(summary.cpuSelfTime!==undefined)
+hasCpuData=true;var colWidthPercentage;if(hasCpuData)
+colWidthPercentage='20%';else
+colWidthPercentage='33.3333%';var ownerDocument=this.ownerDocument;var columns=[];columns.push({title:'Start',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype){return row.title;}
+var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.event);});linkEl.appendChild(tr.v.ui.createScalarSpan(row.start,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:ownerDocument}));return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.start-rowB.start;}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.duration,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
+if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.selfTime,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.cpuSelfTime,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
+var argKeys=tr.b.dictionaryKeys(summary.totalledArgs);argKeys.sort();var otherKeys=summary.untotallableArgs.slice(0);otherKeys.sort();argKeys.push.apply(argKeys,otherKeys);var keysWithColumns=argKeys.slice(0,4);var keysInOtherColumn=argKeys.slice(4);keysWithColumns.forEach(function(argKey){var hasTotal=summary.totalledArgs[argKey];var colDesc={title:'Arg: '+argKey,value:function(row){if(row.__proto__!==tr.ui.analysis.MultiEventSummary.prototype){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=row.args[argKey];return argView;}
+if(hasTotal)
+return row.totalledArgs[argKey];return'';},width:'<upated further down>'};if(hasTotal){colDesc.cmp=function(rowA,rowB){return rowA.args[argKey]-rowB.args[argKey];};}
+columns.push(colDesc);});if(keysInOtherColumn.length){columns.push({title:'Other Args',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype)
+return'';var argView=document.createElement('tr-ui-a-generic-object-view');var obj={};for(var i=0;i<keysInOtherColumn.length;i++)
+obj[keysInOtherColumn[i]]=row.args[keysInOtherColumn[i]];argView.object=obj;return argView;},width:'<upated further down>'});}
+var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;},updateRows_:function(summary){this.$.table.sortColumnIndex=0;function Row(event){this.event=event;}
+Row.prototype={get start(){return this.event.start;},get duration(){return this.event.duration;},get cpuDuration(){return this.event.cpuDuration;},get selfTime(){return this.event.selfTime;},get cpuSelfTime(){return this.event.cpuSelfTime;},get args(){return this.event.args;}};this.$.table.tableRows=this.selection_.map(function(event){return new Row(event);});this.$.table.footerRows=[summary];}});'use strict';Polymer('tr-ui-a-multi-event-sub-view',{created:function(){this.currentSelection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},set selection(selection){if(selection.length<=1)
+throw new Error('Only supports multiple items');this.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},updateContents_:function(){var selection=this.currentSelection_;this.$.content.textContent='';if(!selection)
+return;var eventsByTitle=selection.getEventsOrganizedByTitle();var numTitles=tr.b.dictionaryLength(eventsByTitle);var summaryTableEl=document.createElement('tr-ui-a-multi-event-summary-table');summaryTableEl.configure({showTotals:numTitles>1,eventsByTitle:eventsByTitle,eventsHaveDuration:this.eventsHaveDuration_,eventsHaveSubRows:this.eventsHaveSubRows_});this.$.content.appendChild(summaryTableEl);var selectionSummaryTableEl=document.createElement('tr-ui-a-selection-summary-table');selectionSummaryTableEl.selection=this.currentSelection_;this.$.content.appendChild(selectionSummaryTableEl);if(numTitles===1){var detailsTableEl=document.createElement('tr-ui-a-multi-event-details-table');detailsTableEl.eventsHaveDuration=this.eventsHaveDuration_;detailsTableEl.eventsHaveSubRows=this.eventsHaveSubRows_;detailsTableEl.selection=selection;this.$.content.appendChild(detailsTableEl);}}});'use strict';tr.exportTo('tr.ui.analysis',function(){var FLOW_IN=0x1;var FLOW_OUT=0x2;var FLOW_IN_OUT=FLOW_IN|FLOW_OUT;function FlowClassifier(){this.numEvents_=0;this.eventsByGUID_={};}
+FlowClassifier.prototype={getFS_:function(event){var fs=this.eventsByGUID_[event.guid];if(fs===undefined){this.numEvents_++;fs={state:0,event:event};this.eventsByGUID_[event.guid]=fs;}
+return fs;},addInFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_IN;return event;},addOutFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_OUT;return event;},hasEvents:function(){return this.numEvents_>0;},get inFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN)
+selection.push(fs.event);}
+return selection;},get outFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_OUT)
+selection.push(fs.event);}
+return selection;},get internalFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN_OUT)
+selection.push(fs.event);}
+return selection;}};return{FlowClassifier:FlowClassifier};});'use strict';Polymer('tr-ui-a-related-events',{ready:function(){this.eventGroups_=[];this.cancelFunctions_=[];this.$.table.tableColumns=[{title:'Event(s)',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip)
+typeEl.title=row.tooltip;return typeEl;},width:'150px'},{title:'Link',width:'100%',value:function(row){var linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name)
+linkEl.setSelectionAndContent(row.selection,row.name);else
+linkEl.selection=row.selection;return linkEl;}}];},hasRelatedEvents:function(){return(this.eventGroups_&&this.eventGroups_.length>0);},setRelatedEvents:function(eventSet){this.cancelAllTasks_();this.eventGroups_=[];this.addConnectedFlows_(eventSet);this.addConnectedEvents_(eventSet);this.addOverlappingSamples_(eventSet);this.updateContents_();},addConnectedFlows_:function(eventSet){var classifier=new tr.ui.analysis.FlowClassifier();eventSet.forEach(function(slice){if(slice.inFlowEvents){slice.inFlowEvents.forEach(function(flow){classifier.addInFlow(flow);});}
+if(slice.outFlowEvents){slice.outFlowEvents.forEach(function(flow){classifier.addOutFlow(flow);});}});if(!classifier.hasEvents())
+return;var addToEventGroups=function(type,flowEvent){this.eventGroups_.push({type:type,selection:new tr.model.EventSet(flowEvent),name:flowEvent.title});};classifier.inFlowEvents.forEach(addToEventGroups.bind(this,'Incoming flow'));classifier.outFlowEvents.forEach(addToEventGroups.bind(this,'Outgoing flow'));classifier.internalFlowEvents.forEach(addToEventGroups.bind(this,'Internal flow'));},cancelAllTasks_:function(){this.cancelFunctions_.forEach(function(cancelFunction){cancelFunction();});this.cancelFunctions_=[];},addConnectedEvents_:function(eventSet){this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Preceding events','Add all events that have led to the selected one(s), connected by '+'flow arrows or by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addAncestors_(event,events);if(event.startSlice)
+events.push(event.startSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Following events','Add all events that have been caused by the selected one(s), '+'connected by flow arrows or by call stack.',eventSet,function(event,events){this.addOutFlowEvents_(event,events);this.addDescendents_(event,events);if(event.endSlice)
+events.push(event.endSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('All connected events','Add all events connected to the selected one(s) by flow arrows or '+'by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addOutFlowEvents_(event,events);this.addAncestors_(event,events);this.addDescendents_(event,events);if(event.startSlice)
+events.push(event.startSlice);if(event.endSlice)
+events.push(event.endSlice);}.bind(this)));},createEventsLinkIfNeeded_:function(title,tooltip,events,addFunction){events=new tr.model.EventSet(events);var lengthBefore=events.length;var task;var isCanceled=false;function addEventsUntilTimeout(startingIndex){if(isCanceled)
+return;var startingTime=window.performance.now();while(startingIndex<events.length){addFunction(events[startingIndex],events);startingIndex++;if(window.performance.now()-startingTime>8){var newTask=new tr.b.Task(addEventsUntilTimeout.bind(this,startingIndex),this);task.after(newTask);task=newTask;return;}}
+if(lengthBefore===events.length)
+return;this.eventGroups_.push({type:title,tooltip:tooltip,selection:events});this.updateContents_();};function cancelTask(){isCanceled=true;}
+task=new tr.b.Task(addEventsUntilTimeout.bind(this,0),this);tr.b.Task.RunWhenIdle(task);return cancelTask;},addInFlowEvents_:function(event,eventSet){if(!event.inFlowEvents)
+return;event.inFlowEvents.forEach(function(e){eventSet.push(e);});},addOutFlowEvents_:function(event,eventSet){if(!event.outFlowEvents)
+return;event.outFlowEvents.forEach(function(e){eventSet.push(e);});},addAncestors_:function(event,eventSet){if(!event.iterateAllAncestors)
+return;event.iterateAllAncestors(function(e){eventSet.push(e);});},addDescendents_:function(event,eventSet){if(!event.iterateAllDescendents)
+return;event.iterateAllDescendents(function(e){eventSet.push(e);});},addOverlappingSamples_:function(eventSet){var samples=new tr.model.EventSet;eventSet.forEach(function(slice){if(!slice.parentContainer||!slice.parentContainer.samples)
+return;var candidates=slice.parentContainer.samples;var range=tr.b.Range.fromExplicitRange(slice.start,slice.start+slice.duration);var filteredSamples=range.filterArray(candidates,function(value){return value.start;});filteredSamples.forEach(function(sample){samples.push(sample);});}.bind(this));if(samples.length>0){this.eventGroups_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected slice(s).',selection:samples});}},updateContents_:function(){var table=this.$.table;if(this.eventGroups_===undefined)
+table.tableRows=[];else
+table.tableRows=this.eventGroups_.slice();table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-async-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},get relatedEventsToHighlight(){if(!this.$.content.selection)
+return undefined;var selection=new tr.model.EventSet();this.$.content.selection.forEach(function(asyncEvent){if(!asyncEvent.associatedEvents)
+return;asyncEvent.associatedEvents.forEach(function(event){selection.push(event);});});if(selection.length)
+return selection;return undefined;}});'use strict';Polymer('tr-ui-a-multi-cpu-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-multi-flow-event-sub-view',{ready:function(){this.$.content.eventsHaveDuration=false;this.$.content.eventsHaveSubRows=false;},set selection(selection){this.$.content.selection=selection;},get selection(){return this.$.content.selection;}});'use strict';Polymer('tr-ui-a-multi-frame-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(frameEvent){frameEvent.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';Polymer('tr-ui-a-multi-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.$.content.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';Polymer('tr-ui-a-multi-object-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;var objectEvents=tr.b.asArray(selection).sort(tr.b.Range.compareByMinTimes);var timeSpanConfig={unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument};var table=this.$.content;table.tableColumns=[{title:'First',value:function(event){if(event instanceof tr.model.ObjectSnapshot)
+return tr.v.ui.createScalarSpan(event.ts,timeSpanConfig);var spanEl=document.createElement('span');spanEl.appendChild(tr.v.ui.createScalarSpan(event.creationTs,timeSpanConfig));spanEl.appendChild(tr.ui.b.createSpan({textContent:'-',marginLeft:'4px',marginRight:'4px'}));if(event.deletionTs!=Number.MAX_VALUE){spanEl.appendChild(tr.v.ui.createScalarSpan(event.deletionTs,timeSpanConfig));}
+return spanEl;},width:'200px'},{title:'Second',value:function(event){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(event);},event.userFriendlyName);return linkEl;},width:'100%'}];table.tableRows=objectEvents;table.rebuild();}});'use strict';var EventSet=tr.model.EventSet;var CHART_TITLE='Power (W) by ms since vertical sync';var CHART_WIDTH_FRACTION_OF_BODY=0.5;Polymer('tr-ui-a-frame-power-usage-chart',{ready:function(){this.chart_=undefined;this.samples_=new EventSet();this.vSyncTimestamps_=[];},get chart(){return this.chart_;},get samples(){return this.samples_;},get vSyncTimestamps(){return this.vSyncTimestamps_;},setData:function(samples,vSyncTimestamps){this.samples_=(samples===undefined)?new EventSet():samples;this.vSyncTimestamps_=(vSyncTimestamps===undefined)?[]:vSyncTimestamps;this.updateContents_();},updateContents_:function(){this.clearChart_();var data=this.getDataForLineChart_();if(data.length===0)
+return;this.chart_=this.createChart_(data);this.$.content.appendChild(this.chart_);},createChart_:function(data){var chart=new tr.ui.b.LineChart();var width=document.body.clientWidth*CHART_WIDTH_FRACTION_OF_BODY;chart.setSize({width:width,height:chart.height});chart.chartTitle=CHART_TITLE;chart.data=data;return chart;},clearChart_:function(){var content=this.$.content;while(content.firstChild)
+content.removeChild(content.firstChild);this.chart_=undefined;},getDataForLineChart_:function(){var sortedSamples=this.sortSamplesByTimestampAscending_(this.samples);var vSyncTimestamps=this.vSyncTimestamps.slice();var lastVSyncTimestamp=undefined;var points=[];var frameNumber=0;sortedSamples.forEach(function(sample){while(vSyncTimestamps.length>0&&vSyncTimestamps[0]<=sample.start){lastVSyncTimestamp=vSyncTimestamps.shift();frameNumber++;}
+if(lastVSyncTimestamp===undefined)
+return;var point={x:sample.start-lastVSyncTimestamp};point['f'+frameNumber]=sample.power/1000;points.push(point);});return points;},sortSamplesByTimestampAscending_:function(samples){return samples.toArray().sort(function(smpl1,smpl2){return smpl1.start-smpl2.start;});}});'use strict';Polymer('tr-ui-a-power-sample-summary-table',{ready:function(){this.$.table.tableColumns=[{title:'Min power',width:'100px',value:function(row){return tr.v.Unit.byName.powerInWatts.format(row.min/1000.0);}},{title:'Max power',width:'100px',value:function(row){return tr.v.Unit.byName.powerInWatts.format(row.max/1000.0);}},{title:'Time-weighted average',width:'100px',value:function(row){return tr.v.Unit.byName.powerInWatts.format(row.timeWeightedAverage/1000.0);}},{title:'Energy consumed',width:'100px',value:function(row){return tr.v.Unit.byName.energyInJoules.format(row.energyConsumed);}},{title:'Sample count',width:'100%',value:function(row){return row.sampleCount;}}];this.samples=new tr.model.EventSet();},get samples(){return this.samples_;},set samples(samples){if(samples===this.samples)
+return;this.samples_=(samples===undefined)?new tr.model.EventSet():samples;this.updateContents_();},updateContents_:function(){if(this.samples.length===0){this.$.table.tableRows=[];}else{this.$.table.tableRows=[{min:this.getMin(),max:this.getMax(),timeWeightedAverage:this.getTimeWeightedAverage(),energyConsumed:this.getEnergyConsumed(),sampleCount:this.samples.length}];}
+this.$.table.rebuild();},getMin:function(){return Math.min.apply(null,this.samples.map(function(sample){return sample.power;}));},getMax:function(){return Math.max.apply(null,this.samples.map(function(sample){return sample.power;}));},getTimeWeightedAverage:function(){var energyConsumed=this.getEnergyConsumed();if(energyConsumed==='N/A')
+return'N/A';var energyInMillijoules=this.getEnergyConsumed()*1000;var durationInSeconds=this.samples.bounds.duration/1000;return energyInMillijoules/durationInSeconds;},getEnergyConsumed:function(){if(this.samples.length<2)
+return'N/A';var bounds=this.samples.bounds;return this.samples[0].series.getEnergyConsumed(bounds.min,bounds.max);}});'use strict';var EventSet=tr.model.EventSet;Polymer('tr-ui-a-power-sample-table',{ready:function(){this.$.table.tableColumns=[{title:'Time',width:'100px',value:function(row){return tr.v.ui.createScalarSpan(row.start,{unit:tr.v.Unit.byName.timeStampInMs});}},{title:'Power',width:'100%',value:function(row){return tr.v.ui.createScalarSpan(row.power/1000,{unit:tr.v.Unit.byName.powerInWatts});}}];this.samples=new EventSet();},get samples(){return this.samples_;},set samples(samples){this.samples_=(samples===undefined)?new EventSet():samples;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.samples.toArray();this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){var samples=this.selection;var vSyncTimestamps=(this.selection===undefined)?[]:this.selection[0].series.device.vSyncTimestamps;this.$.summaryTable.samples=samples;this.$.samplesTable.samples=samples;this.$.chart.setData(this.selection,vSyncTimestamps);}});'use strict';(function(){Polymer('tr-ui-a-multi-sample-sub-view',{created:function(){this.viewOption_=undefined;this.selection_=undefined;},ready:function(){var viewSelector=tr.ui.b.createSelector(this,'viewOption','tracing.ui.analysis.multi_sample_sub_view',tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:tr.b.MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW}]);this.$.control.appendChild(viewSelector);this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},get viewOption(){return this.viewOption_;},set viewOption(viewOption){this.viewOption_=viewOption;this.updateContents_();},createSamplingSummary_:function(selection,viewOption){var builder=new tr.b.MultiDimensionalViewBuilder(1);var samples=selection.getEventsOrganizedByBaseType().sample;samples.forEach(function(sample){builder.addPath([sample.getUserFriendlyStackTrace().reverse()],1,tr.b.MultiDimensionalViewBuilder.ValueKind.SELF);});return builder.buildView(viewOption);},updateContents_:function(){if(this.selection===undefined){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.rebuild();return;}
+var samplingData=this.createSamplingSummary_(this.selection,this.viewOption);var columns=[this.createPercentColumn_('Total',samplingData.total),this.createSamplesColumn_('Total'),this.createPercentColumn_('Self',samplingData.total),this.createSamplesColumn_('Self'),{title:'Symbol',value:function(row){return row.title[0];},width:'250px',cmp:function(a,b){return a.title[0].localeCompare(b.title[0]);},showExpandButtons:true}];this.$.table.tableColumns=columns;this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;this.$.table.tableRows=samplingData.subRows;this.$.table.rebuild();},createPercentColumn_:function(title,samplingDataTotal){var field=title.toLowerCase();return{title:title+' percent',value:function(row){var percent=row[field]/samplingDataTotal;var span=document.createElement('tr-v-ui-scalar-span');span.value=(percent*100).toFixed(2);span.percentage=percent;span.unit=tr.v.Unit.byName.unitlessNumber;return span;}.bind(this),width:'60px',cmp:function(a,b){return a[field]-b[field];}};},createSamplesColumn_:function(title){var field=title.toLowerCase();return{title:title+' samples',value:function(row){return row[field];},width:'60px',cmp:function(a,b){return a[field]-b[field];}};}});})();'use strict';Polymer('tr-ui-a-multi-thread-slice-sub-view',{created:function(){this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;if(tr.isExported('tr.ui.e.chrome.cc.RasterTaskSelection')){if(tr.ui.e.chrome.cc.RasterTaskSelection.supports(selection)){var ltvSelection=new tr.ui.e.chrome.cc.RasterTaskSelection(selection);var ltv=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();ltv.objectSnapshot=ltvSelection.containingSnapshot;ltv.selection=ltvSelection;ltv.extraHighlightsByLayerId=ltvSelection.extraHighlightsByLayerId;this.$.content.textContent='';this.$.content.appendChild(ltv);this.requiresTallView_=true;return;}}
+this.$.content.textContent='';var mesv=document.createElement('tr-ui-a-multi-event-sub-view');mesv.selection=selection;this.$.content.appendChild(mesv);var relatedEvents=document.createElement('tr-ui-a-related-events');relatedEvents.setRelatedEvents(selection);if(relatedEvents.hasRelatedEvents()){this.$.content.appendChild(relatedEvents);}},get requiresTallView(){if(this.$.content.children.length===0)
+return false;var childTagName=this.$.content.children[0].tagName;if(childTagName==='TR-UI-A-MULTI-EVENT-SUB-VIEW')
+return false;return true;}});'use strict';Polymer('tr-ui-a-multi-thread-time-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-multi-user-expectation-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.currentSelection_=selection;this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(ir){ir.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';Polymer('tr-ui-a-single-async-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single slices');this.$.content.setSelectionWithoutErrorChecks(selection);this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});return rows;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-single-cpu-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.CpuSlice))
+throw new Error('Only supports thread time slices');this.currentSelection_=selection;var cpuSlice=selection[0];var thread=cpuSlice.threadThatWasRunning;var shadowRoot=this.shadowRoot;if(thread){shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;}else{shadowRoot.querySelector('#process-name').parentElement.style.display='none';shadowRoot.querySelector('#thread-name').textContent=cpuSlice.title;}
+shadowRoot.querySelector('#start').setValueAndUnit(cpuSlice.start,tr.v.Unit.byName.timeStampInMs);shadowRoot.querySelector('#duration').setValueAndUnit(cpuSlice.duration,tr.v.Unit.byName.timeDurationInMs);var runningThreadEl=shadowRoot.querySelector('#running-thread');var timeSlice=cpuSlice.getAssociatedTimeslice();if(!timeSlice){runningThreadEl.parentElement.style.display='none';}else{var threadLink=document.createElement('tr-ui-a-analysis-link');threadLink.selection=new tr.model.EventSet(timeSlice);threadLink.textContent='Click to select';runningThreadEl.parentElement.style.display='';runningThreadEl.textContent='';runningThreadEl.appendChild(threadLink);}
+shadowRoot.querySelector('#args').object=cpuSlice.args;}});'use strict';Polymer('tr-ui-a-single-flow-event-sub-view',{getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});function createLinkTo(slice){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(slice);});linkEl.textContent=slice.userFriendlyName;return linkEl;}
+rows.push({name:'From',value:createLinkTo(event.startSlice)});rows.push({name:'To',value:createLinkTo(event.endSlice)});return rows;}});'use strict';Polymer('tr-ui-a-single-frame-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!=1)
+throw new Error('Only supports single frame!');this.currentSelection_=selection;this.$.asv.selection=selection[0].associatedAlerts;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-single-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-single-event-sub-view');realView.setSelectionWithoutErrorChecks(selection);this.$.content.appendChild(realView);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectInstanceView=tr.ui.b.define('object-instance-view');ObjectInstanceView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectInstance_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectInstance=obj;},get modelEvent(){return this.objectInstance;},get objectInstance(){return this.objectInstance_;},set objectInstance(i){this.objectInstance_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstanceView;options.defaultMetadata={showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectInstanceView,options);return{ObjectInstanceView:ObjectInstanceView};});'use strict';Polymer('tr-ui-a-single-object-instance-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.$.content.children.length===0)
+return false;if(this.$.content.children[0]instanceof
+tr.ui.analysis.ObjectInstanceView)
+return this.$.content.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectInstance))
+throw new Error('Only supports object instances');this.$.content.textContent='';this.currentSelection_=selection;var instance=selection[0];var typeInfo=tr.ui.analysis.ObjectInstanceView.getTypeInfo(instance.category,instance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.$.content.appendChild(customView);customView.modelEvent=instance;}else{this.appendGenericAnalysis_(instance);}},appendGenericAnalysis_:function(instance){var html='';html+='<div class="title">'+
+instance.typeName+' '+
+instance.id+'</div>\n';html+='<table>';html+='<tr>';html+='<tr><td>creationTs:</td><td>'+
+instance.creationTs+'</td></tr>\n';if(instance.deletionTs!=Number.MAX_VALUE){html+='<tr><td>deletionTs:</td><td>'+
+instance.deletionTs+'</td></tr>\n';}else{html+='<tr><td>deletionTs:</td><td>not deleted</td></tr>\n';}
+html+='<tr><td>snapshots:</td><td id="snapshots"></td></tr>\n';html+='</table>';this.$.content.innerHTML=html;var snapshotsEl=this.$.content.querySelector('#snapshots');instance.snapshots.forEach(function(snapshot){var snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);snapshotsEl.appendChild(snapshotLink);});}});'use strict';Polymer('tr-ui-a-single-object-snapshot-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.children.length===0)
+return false;if(this.children[0]instanceof tr.ui.analysis.ObjectSnapshotView)
+return this.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectSnapshot))
+throw new Error('Only supports object instances');this.textContent='';this.currentSelection_=selection;var snapshot=selection[0];var typeInfo=tr.ui.analysis.ObjectSnapshotView.getTypeInfo(snapshot.objectInstance.category,snapshot.objectInstance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.appendChild(customView);customView.modelEvent=snapshot;}else{this.appendGenericAnalysis_(snapshot);}},appendGenericAnalysis_:function(snapshot){var instance=snapshot.objectInstance;this.textContent='';var titleEl=document.createElement('div');titleEl.classList.add('title');titleEl.appendChild(document.createTextNode('Snapshot of '));this.appendChild(titleEl);var instanceLinkEl=document.createElement('tr-ui-a-analysis-link');instanceLinkEl.selection=new tr.model.EventSet(instance);titleEl.appendChild(instanceLinkEl);titleEl.appendChild(document.createTextNode(' @ '));titleEl.appendChild(tr.v.ui.createScalarSpan(snapshot.ts,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}));var tableEl=document.createElement('table');this.appendChild(tableEl);var rowEl=document.createElement('tr');tableEl.appendChild(rowEl);var labelEl=document.createElement('td');labelEl.textContent='args:';rowEl.appendChild(labelEl);var argsEl=document.createElement('td');argsEl.id='args';rowEl.appendChild(argsEl);var objectViewEl=document.createElement('tr-ui-a-generic-object-view');objectViewEl.object=snapshot.args;argsEl.appendChild(objectViewEl);}});'use strict';Polymer('tr-ui-a-single-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.samplesTable.samples=this.selection;}});'use strict';Polymer('tr-ui-a-single-sample-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.tableColumns=[{title:'FirstColumn',value:function(row){return row.title;},width:'250px'},{title:'SecondColumn',value:function(row){return row.value;},width:'100%'}];this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;if(this.currentSelection_===undefined){this.$.content.tableRows=[];return;}
+var sample=this.currentSelection_[0];var table=this.$.content;var rows=[];rows.push({title:'Title',value:sample.title});rows.push({title:'Sample time',value:tr.v.ui.createScalarSpan(sample.start,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument})});var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sample.leafStackFrame;rows.push({title:'Stack trace',value:sfEl});table.tableRows=rows;table.rebuild();}});'use strict';Polymer('tr-ui-a-single-thread-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents())
+this.$.relatedEvents.style.display='';else
+this.$.relatedEvents.style.display='none';}});'use strict';Polymer('tr-ui-a-single-thread-time-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.ThreadTimeSlice))
+throw new Error('Only supports thread time slices');this.currentSelection_=selection;var timeSlice=selection[0];var thread=timeSlice.thread;var shadowRoot=this.shadowRoot;shadowRoot.querySelector('#state').textContent=timeSlice.title;var stateColor=tr.b.ColorScheme.colorsAsStrings[timeSlice.colorId];shadowRoot.querySelector('#state').style.backgroundColor=stateColor;shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;shadowRoot.querySelector('#start').setValueAndUnit(timeSlice.start,tr.v.Unit.byName.timeStampInMs);shadowRoot.querySelector('#duration').setValueAndUnit(timeSlice.duration,tr.v.Unit.byName.timeDurationInMs);var onCpuEl=shadowRoot.querySelector('#on-cpu');onCpuEl.textContent='';var runningInsteadEl=shadowRoot.querySelector('#running-instead');if(timeSlice.cpuOnWhichThreadWasRunning){runningInsteadEl.parentElement.removeChild(runningInsteadEl);var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(timeSlice.getAssociatedCpuSlice());cpuLink.textContent=timeSlice.cpuOnWhichThreadWasRunning.userFriendlyName;onCpuEl.appendChild(cpuLink);}else{onCpuEl.parentElement.removeChild(onCpuEl);var cpuSliceThatTookCpu=timeSlice.getCpuSliceThatTookCpu();if(cpuSliceThatTookCpu){var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(cpuSliceThatTookCpu);if(cpuSliceThatTookCpu.thread)
+cpuLink.textContent=cpuSliceThatTookCpu.thread.userFriendlyName;else
+cpuLink.textContent=cpuSliceThatTookCpu.title;runningInsteadEl.appendChild(cpuLink);}else{runningInsteadEl.parentElement.removeChild(runningInsteadEl);}}
+var argsEl=shadowRoot.querySelector('#args');if(tr.b.dictionaryKeys(timeSlice.args).length>0){var argsView=document.createElement('tr-ui-a-generic-object-view');argsView.object=timeSlice.args;argsEl.parentElement.style.display='';argsEl.textContent='';argsEl.appendChild(argsView);}else{argsEl.parentElement.style.display='none';}}});'use strict';tr.exportTo('tr.metrics',function(){function ValueList(values){if(values!==undefined)
+this.values_=values;else
+this.values_=[];}
+ValueList.prototype={get valueDicts(){return this.values_.map(function(v){return v.asDict();});},getValuesWithName:function(name){return this.values_.filter(function(value){return value.name.indexOf(name)>-1;});},addValue:function(v){if(!(v instanceof tr.v.NumericValue)){var err=new Error('Tried to add value '+v+' which is non-Numeric');err.name='ValueError';throw err;}
+this.values_.push(v);}};return{ValueList:ValueList};});'use strict';Polymer('tr-ui-a-single-user-expectation-sub-view',{created:function(){this.currentSelection_=undefined;this.realView_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.textContent='';this.realView_=document.createElement('tr-ui-a-single-event-sub-view');this.realView_.addEventListener('customize-rows',this.onCustomizeRows_.bind(this));this.appendChild(this.realView_);this.currentSelection_=selection;this.realView_.setSelectionWithoutErrorChecks(selection);},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;},onCustomizeRows_:function(event){var ue=this.selection[0];var valueList=new tr.metrics.ValueList();function runMetric(metricInfo){try{metricInfo.constructor(valueList,ue.parentModel);}catch(failure){console.error(metricInfo,failure);}}
+tr.metrics.MetricRegistry.getAllRegisteredTypeInfos().forEach(runMetric);var metricValues={};valueList.valueDicts.forEach(function(value){if(value.grouping_keys.userExpectationStableId!==ue.stableId)
+return;if((value.type!=='numeric')||(value.numeric.type!=='scalar'))
+return;metricValues[value.grouping_keys.name]=value.numeric;});for(var name in metricValues){event.rows.push({name:name,value:tr.v.ui.createScalarSpan(metricValues[name].value,{unit:tr.v.Unit.fromJSON(metricValues[name].unit)})});}
+if(ue.rawCpuMs){event.rows.push({name:'Total CPU',value:tr.v.ui.createScalarSpan(ue.totalCpuMs,{unit:tr.v.Unit.byName.timeDurationInMs})});}}});'use strict';Polymer('tr-ui-a-tab-view',{ready:function(){this.$.tshh.style.display='none';this.tabs_=[];this.selectedTab_=undefined;for(var i=0;i<this.children.length;i++)
+this.processAddedChild_(this.children[i]);this.childrenObserver_=new MutationObserver(this.childrenUpdated_.bind(this));this.childrenObserver_.observe(this,{childList:'true'});},get tabStripHeadingText(){return this.$.tsh.textContent;},set tabStripHeadingText(tabStripHeadingText){this.$.tsh.textContent=tabStripHeadingText;if(!!tabStripHeadingText)
+this.$.tshh.style.display='';else
+this.$.tshh.style.display='none';},get selectedTab(){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(this.selectedTab_)
+return this.selectedTab_.content;return undefined;},set selectedTab(content){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(content===undefined||content===null){this.changeSelectedTabById_(undefined);return;}
+var contentTabId=undefined;for(var i=0;i<this.tabs_.length;i++)
+if(this.tabs_[i].content===content){contentTabId=this.tabs_[i].id;break;}
+if(contentTabId===undefined)
+return;this.changeSelectedTabById_(contentTabId);},get tabsHidden(){var ts=this.shadowRoot.querySelector('tab-strip');return ts.hasAttribute('tabs-hidden');},set tabsHidden(tabsHidden){tabsHidden=!!tabsHidden;var ts=this.shadowRoot.querySelector('tab-strip');if(tabsHidden)
+ts.setAttribute('tabs-hidden',true);else
+ts.removeAttribute('tabs-hidden');},get tabs(){return this.tabs_.map(function(tabObject){return tabObject.content;});},processAddedChild_:function(child){var observerAttributeSelected=new MutationObserver(this.childAttributesChanged_.bind(this));var observerAttributeTabLabel=new MutationObserver(this.childAttributesChanged_.bind(this));var tabObject={id:this.tabs_.length,content:child,label:child.getAttribute('tab-label'),observers:{forAttributeSelected:observerAttributeSelected,forAttributeTabLabel:observerAttributeTabLabel}};this.tabs_.push(tabObject);if(child.hasAttribute('selected')){if(this.selectedTab_)
+child.removeAttribute('selected');else
+this.setSelectedTabById_(tabObject.id);}
+var previousSelected=child.selected;var tabView=this;Object.defineProperty(child,'selected',{configurable:true,set:function(value){if(value){tabView.changeSelectedTabById_(tabObject.id);return;}
+var wasSelected=tabView.selectedTab_===tabObject;if(wasSelected)
+tabView.changeSelectedTabById_(undefined);},get:function(){return this.hasAttribute('selected');}});if(previousSelected)
+child.selected=previousSelected;observerAttributeSelected.observe(child,{attributeFilter:['selected']});observerAttributeTabLabel.observe(child,{attributeFilter:['tab-label']});},processRemovedChild_:function(child){for(var i=0;i<this.tabs_.length;i++){this.tabs_[i].id=i;if(this.tabs_[i].content===child){this.tabs_[i].observers.forAttributeSelected.disconnect();this.tabs_[i].observers.forAttributeTabLabel.disconnect();if(this.tabs_[i]===this.selectedTab_){this.clearSelectedTab_();this.fire('selected-tab-change');}
+child.removeAttribute('selected');delete child.selected;this.tabs_.splice(i,1);i--;}}},childAttributesChanged_:function(mutations,observer){var tabObject=undefined;for(var i=0;i<this.tabs_.length;i++){var observers=this.tabs_[i].observers;if(observers.forAttributeSelected===observer||observers.forAttributeTabLabel===observer){tabObject=this.tabs_[i];break;}}
+if(!tabObject)
+return;for(var i=0;i<mutations.length;i++){var node=tabObject.content;if(mutations[i].attributeName==='tab-label')
+tabObject.label=node.getAttribute('tab-label');if(mutations[i].attributeName==='selected'){var nodeIsSelected=node.hasAttribute('selected');if(nodeIsSelected)
+this.changeSelectedTabById_(tabObject.id);else
+this.changeSelectedTabById_(undefined);}}},childrenUpdated_:function(mutations,observer){mutations.forEach(function(mutation){for(var i=0;i<mutation.removedNodes.length;i++)
+this.processRemovedChild_(mutation.removedNodes[i]);for(var i=0;i<mutation.addedNodes.length;i++)
+this.processAddedChild_(mutation.addedNodes[i]);},this);},tabButtonSelectHandler_:function(event,detail,sender){this.changeSelectedTabById_(sender.getAttribute('button-id'));},changeSelectedTabById_:function(id){var newTab=id!==undefined?this.tabs_[id]:undefined;var changed=this.selectedTab_!==newTab;this.saveCurrentTabScrollPosition_();this.clearSelectedTab_();if(id!==undefined){this.setSelectedTabById_(id);this.restoreCurrentTabScrollPosition_();}
+if(changed)
+this.fire('selected-tab-change');},setSelectedTabById_:function(id){this.selectedTab_=this.tabs_[id];this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.setAttribute('selected','selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});},saveTabStates:function(){this.saveCurrentTabScrollPosition_();},saveCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.selectedTab_.content._savedScrollTop=this.$['content-container'].scrollTop;this.selectedTab_.content._savedScrollLeft=this.$['content-container'].scrollLeft;}},restoreCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.$['content-container'].scrollTop=this.selectedTab_.content._savedScrollTop||0;this.$['content-container'].scrollLeft=this.selectedTab_.content._savedScrollLeft||0;}},clearSelectedTab_:function(){if(this.selectedTab_){this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.removeAttribute('selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});this.selectedTab_=undefined;}}});'use strict';(function(){var EventRegistry=tr.model.EventRegistry;Polymer('tr-ui-a-analysis-view',{ready:function(){this.tabView_=document.createElement('tr-ui-a-tab-view');this.tabView_.style.flex='1 1 auto';this.appendChild(this.tabView_);this.brushingStateController_=undefined;this.onSelectedTabChange_=this.onSelectedTabChange_.bind(this);this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.lastSeenSelection_=new tr.model.EventSet();},set tallMode(value){if(value)
+this.classList.add('tall-mode');else
+this.classList.remove('tall-mode');},get tallMode(){return this.classList.contains('tall-mode');},get tabView(){return this.tabView_;},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}
+this.onSelectionChanged_();},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(e){var selection=this.brushingStateController_.selection;var selectionHasSameValue=this.lastSeenSelection_.equals(selection);this.lastSeenSelection_=selection;if(selectionHasSameValue)
+return;var lastSelectedTabTagName;var lastSelectedTabTypeName;if(this.tabView_.selectedTab){lastSelectedTabTagName=this.tabView_.selectedTab.tagName;lastSelectedTabTypeName=this.tabView_.selectedTab._eventTypeName;}
+this.tallMode=false;var previouslySelectedTab=this.tabView_.selectedTab;this.tabView_.removeEventListener('selected-tab-change',this.onSelectedTabChange_);var previousSubViews={};for(var i=0;i<this.tabView_.children.length;i++){var previousSubView=this.tabView_.children[i];previousSubViews[previousSubView._eventTypeName]=previousSubView;}
+this.tabView_.saveTabStates();this.tabView_.textContent='';if(selection.length==0){this.tabView_.tabStripHeadingText='Nothing selected. Tap stuff.';}else if(selection.length==1){this.tabView_.tabStripHeadingText='1 item selected: ';}else{this.tabView_.tabStripHeadingText=selection.length+' items selected: ';}
+var eventsByBaseTypeName=selection.getEventsOrganizedByBaseType(true);var numBaseTypesToAnalyze=tr.b.dictionaryLength(eventsByBaseTypeName);for(var eventTypeName in eventsByBaseTypeName){var subSelection=eventsByBaseTypeName[eventTypeName];var subView=this.createSubViewForSelection_(eventTypeName,subSelection,previousSubViews[eventTypeName]);subView._eventTypeName=eventTypeName;this.tabView_.appendChild(subView);subView.selection=subSelection;}
+var tab;if(lastSelectedTabTagName)
+tab=this.tabView_.querySelector(lastSelectedTabTagName);if(!tab&&lastSelectedTabTypeName){var tab=tr.b.findFirstInArray(this.tabView_.children,function(tab){return tab._eventTypeName===lastSelectedTabTypeName;});}
+if(!tab)
+tab=this.tabView_.firstChild;this.tabView_.selectedTab=tab;this.onSelectedTabChange_();this.tabView_.addEventListener('selected-tab-change',this.onSelectedTabChange_);},createSubViewForSelection_:function(eventTypeName,subSelection,previousSubView){var eventTypeInfo=EventRegistry.getEventTypeInfoByTypeName(eventTypeName);var singleMode=subSelection.length==1;var tagName;if(subSelection.length===1)
+tagName=eventTypeInfo.metadata.singleViewElementName;else
+tagName=eventTypeInfo.metadata.multiViewElementName;if(!tr.ui.b.getPolymerElementNamed(tagName))
+throw new Error('Element not registered: '+tagName);var subView;if(previousSubView&&previousSubView.tagName===tagName.toUpperCase())
+subView=previousSubView;else
+subView=document.createElement(tagName);var camelLabel;if(subSelection.length===1)
+camelLabel=EventRegistry.getUserFriendlySingularName(eventTypeName);else
+camelLabel=EventRegistry.getUserFriendlyPluralName(eventTypeName);subView.tabLabel=camelLabel+' ('+subSelection.length+')';return subView;},onSelectedTabChange_:function(){var brushingStateController=this.brushingStateController_;if(this.tabView_.selectedTab){var selectedTab=this.tabView_.selectedTab;this.tallMode=selectedTab.requiresTallView;if(brushingStateController){var rlth=selectedTab.relatedEventsToHighlight;brushingStateController.changeAnalysisViewRelatedEvents(rlth);}}else{this.tallMode=false;if(brushingStateController)
+brushingStateController.changeAnalysisViewRelatedEvents(undefined);}}});})();'use strict';Polymer('tr-ui-b-dropdown',{ready:function(){this.$.outer.tabIndex=0;},get iconElement(){return this.$.icon;},onOuterKeyDown_:function(e){if(e.keyCode===' '.charCodeAt(0)){this.toggle_();e.preventDefault();e.stopPropagation();}},onOuterClick_:function(e){var or=this.$.outer.getBoundingClientRect();var inside=true;inside&=e.clientX>=or.left;inside&=e.clientX<or.right;inside&=e.clientY>=or.top;inside&=e.clientY<or.bottom;if(!inside)
+return;e.preventDefault();this.toggle_();},toggle_:function(){if(!this.isOpen)
+this.show();else
+this.close();},show:function(){if(this.isOpen)
+return;this.$.outer.classList.add('open');var ddr=this.$.outer.getBoundingClientRect();var rW=Math.max(ddr.width,150);this.$.dialog.style.minWidth=rW+'px';this.$.dialog.showModal();var ddw=this.$.outer.getBoundingClientRect().width;var w=this.$.dialog.getBoundingClientRect().width;this.$.dialog.style.top=ddr.bottom-1+'px';this.$.dialog.style.left=ddr.left+'px';},onDialogClick_:function(e){if(!this.isOpen)
+return;if(e.srcElement!==this.$.dialog)
+return;e.preventDefault();this.close();},onDialogCancel_:function(e){e.preventDefault();this.close();},close:function(){if(!this.isOpen)
+return;this.$.dialog.close();this.$.outer.classList.remove('open');this.$.outer.focus();},get isOpen(){return this.$.dialog.hasAttribute('open');}});'use strict';tr.exportTo('tr.ui.b',function(){var FaviconsByHue={blue:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjj8xAGArIgqOPzE8nUY3dqJJOJeiSTiXnUY3do4/MTxhKyIKjkAxAAAAAAAAAAAAAAAAAAAAAABQJBwAAAAAAZJBMzSoSzqlsU8+6bRQP/21UT//tVE//7RQP/2wTz3ppko6pY9AMjQAAAABTyMbAAAAAAB7e3sAAP//AKFSRE+wTz3dtVE//7VRP/+1UT//tVE//7VRP/+zUD7/sE89/7BOPf+qTDvdl0M0TwAAAABWJx4A+fn5ANjd3TnIiX7ftVA9/7VRP/+1UT//tVE//7VRP/+xTz3/rE08/6xMO/+sTDv/rE08/6dKOt+SQTM5q0w7ALO0tA3v8fGu05uR/7NMOf+0Tzz/tE88/7RPPv+uTT3/p0o7/6ZJOv+mSTr/pkk6/6ZJOv+mSjr/n0Y4rnIwKg3h4eFK9/j48N2zrP/FeGr/xnps/8Z6bP/AaUv/tlw1/7RbNf+1WzX/tFs1/7RbNf+0WzX/tFs1/7NbNPCqWy1K7e3tjPn5+f/49vX/9vLy//by8v/28vH/8bZv/+6RH//ukyP/7pMj/+6SI//ukiP/7pMj/+2SIv/qjyL/34kfjPHx8bL5+fn/+fn5//n5+f/5+fr/+fn5//W7cP/zlB3/85Yh//OWIf/zliH/85Yh//GVIf/rkR//6ZAf/+KLHrLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f/1unD/85Qd//OWIf/zliH/85Yh//CUIP/mjh//44we/+OMHv/diR628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/9bx0//OXI//zmCb/85gm/++VIv/hjB//3Yoe/92KHv/dih7/2IYdmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5//jo0//33bv/9929//bbtf/euDX/06oJ/9OrC//Tqwv/06oM98yfD1zr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/5+vv/+fv8//n7/f/3+PH/3Ms6/9O8AP/UvQD/1L0A/9K8AMbItAAY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/5+fr/9/bu/9zKOf/TuwD/1LwA/9S8APLQuABW3cQAAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+fn6//f27v/cyTn/07sA/9S8APTRugB4w60ABcmyAAAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/49/H/5Ndu/NjEIdLSugBdybIABsy1AAAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tvX063Lt6MMhOQAAAM+/RAAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCwUEDDgZExxWJx4tYiwiN2IsIjdWJx4tOBkTHAsFBAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAbDAkKZS0jMYs+MWydRjeipko6x6tMO9utTTzjrU0846tMO9umSjrHnUY3oos+MWxlLSMxGwwJCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgZFAAPBwUHcjMoPJtFNpqsTTzhs1A+/LVRP/+2UT//tVE//7VRP/+1UT//tVE//7ZRP/+1UT//s1A+/KxNPOGbRTaacTInPA8HBQc4GRMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yp4AUCQcGZVDNICtTjzktVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+0UT//s1A+/7JQPv+rTDvkkkEzgE8jGxn/xZoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA////AGswJSqiSTivs1A++7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tFA+/7FPPf+xTz3/sU89/7FPPf+vTj37nkc3r2guJCr///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP/DogB/VEwsqE09v7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7NQPv+vTj3/r049/69OPf+vTj3/r049/69OPf+uTjz/oUg4v20xJiz/nnsAAgEBAAAAAAAAAAAAAAAAAAAAAAD19fUAkp2fHdK2sbW5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+yUD7/rU08/6xNPP+tTTz/rU08/61NPP+tTTz/rU08/61NPP+sTTz/nkY3tWAqIR2pSzsAAAAAAAAAAAAAAAAAeXl5ADY2Ngnd39+O6tbT/blbSv+1UD7/tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//slA+/6xNPP+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+qTDv9lkM0jiUQDQlSJR0AAAAAAAAAAAD///8AxMTES/X29u3s2NX/uVtK/7VQPv+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7FPPv+qTDv/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6lLOv+lSTnthDsuS/+TcgAAAAAAm5ubAHBwcA/o6Oix+vv8/+zY1P+5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+xTz3/qEs6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+bRTaxSiEaD2cuJAD///8AycnJRfX19fD6+/z/69fU/7hYR/+0Tjv/tE48/7ROPP+0Tjz/tE48/7ROPP+0Tz3/r04+/6VJOv+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDr/o0g5/6NIOf+jSDn/o0g6/6BHOfCCOS9F0FxKAAAAAALk5OSN+fn5//n6+v/y5+X/05uS/9CTiP/QlIn/0JSJ/9CUif/QlIn/0JSK/8yGb//AaDb/vWc0/71nNf+9ZzT/vWc0/71nNP+9ZjT/vWY0/71mNP+9ZjT/vGY0/7xmNP+8ZjT/vGY0/7xmNP+8ZjT/u2U0/7FiLY0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+vr/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//KWI//ylSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//CUIf/vkyD/5Y0fxY1XExbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/wlCD/7pIg/+6SIP/pjx/lunIZM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/75Mg/+uRH//qkB//6pAf/+iPH/TIfBtQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+6TIP/ojx//548f/+ePH//njx//5o4f+c1/HGHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/tkiD/5Y0f/+SNH//ljR//5Y0f/+WNH//kjB/6zn8cZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/65Eg/+KMHv/iix7/4ose/+KLHv/iix7/4ose/+CLHvfLfRta3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+qRIP/gih7/34oe/9+KHv/fih7/34oe/9+KHv/fih7/3Yge78V6GkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LH/85Yg//OVHv/zlR7/85Ue//OVHv/zlR7/85Ue//OVIf/pjyH/3ogf/92HH//dhx//3Ycf/92HH//dhx//3Ycf/92HH//ahh7ZunMZI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fr7//jr2f/2ypL/9smP//bJkP/2yZD/9smQ//bJkP/2yZD/5rNI/9OeFP/SnhX/0p4V/9KeFf/SnhX/0Z0V/9GdFf/RnRX/0Z0V/8yWFq6KVBcI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn6//n6/P/5+vz/+fr8//n6/P/5+vz/+fr8//n6/P/h013/0rsA/9O8AP/TvAD/07wA/9O8AP/TvAD/07wA/9O8AP/SvAD+yLMAav/mAADr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6ANu/qgAkyLEAALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/zrYAgQAAAACfjQAAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6AMzCrAAeybIAAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/TuwDsy7QATu7UAACXhQAAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/07wA9M63AG6ZiQADtqIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9O8APDPuABzuKMABsGrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+HSW//TugD/1LsA/9S8AP/TuwDazrcAWbejAATBqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/7uas/+bZdv/j1mvt2cYznMu0ACsUFAAAtaEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL4+frS9/j8kPT1/Trs8v8G8PP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',green:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbWJLAEpCMwptYks8eWxTdn1wVpd9cFaXeWxTdm1iSzxKQzMKbWJLAAAAAAAAAAAAAAAAAAAAAAA+OCsAAAAAAXBlTTSBdFmliHpe6Yp8X/2LfWD/i31g/4p8X/2HeV3pf3NYpW5jTDQAAAABPTcqAAAAAAB7e3sAlv//AIB1Xk+HeV3di31g/4t9YP+LfWD/i31g/4t9YP+Je1//h3pd/4d5Xf+DdVrddGhQTwAAAABDPC4A+fn5ANrb3DmupZPfinxf/4t9YP+LfWD/i31g/4t9YP+Iel7/hHdb/4R2W/+Edlv/hHdb/4BzWN9wZU05g3ZaALS0tA3w8PGuu7Sj/4h5W/+Je17/iXte/4t8X/+HeFz/gnNY/4FyWP+Bclj/gXJY/4FyWP+Bclj/fG1Url9NPA3h4eFK9/j48MvFuf+kmoP/ppuF/6abhf+JkHL/c4Rj/3OEY/9zhGP/coNj/3KDY/9yg2P/coNj/3CDYvBgf19K7e3tjPn5+f/39vb/9fTz//X08//09PP/itKw/0m+h/9Mv4n/TL+J/0y/if9Mv4n/TL+J/0y+iP9Lu4b/RrJ/jPHx8bL5+fn/+fn5//n5+f/5+fn/+fn5/4rXtP9Hwon/SsOL/0rDi/9Kw4v/SsOL/0nCiv9HvYb/RruF/0S1gbLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f+K17P/R8KJ/0rDi/9Kw4v/SsOL/0nBif9GuYT/RbaC/0W2gv9Dsn+28vLymfn5+f/5+fn/+fn5//n5+f/5+fn/jdi1/0vDjP9OxI7/TsSO/0rAiv9FtoP/RLKA/0SygP9EsoD/Qq59mfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9rw5v/H6tn/yOra/8Lp2f9e1b7/O8yz/z3MtP89zLT/Pcuy9zzApVzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+vr//Pr7//z6+//z+fn/ZuPY/zbczv853c7/Od3O/zjbzcY10sYY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/8Pj3/2Xj1/823Mz/OdzN/znczfI42MlWO+XWAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5//D49/9j4tf/NdvM/znczfQ42ct4Ncu9BTbRwgAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/z+Pj/jung/FLf0tI42ctdNdHCBjfUxgAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tu329XLO7+whAFQmAGrUygAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQgGDCsmHRxCOy4tS0M0N0tDNDdCOy4tKyYdHAkIBgwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAVEg4KTUU1MWtgSmx5bVOigHNYx4N2W9uFd1zjhXdc44N2W9uAc1jHeW1TomtgSmxNRjUxFRMOCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsnHgALCggHWE88PHdrUpqEd1vhiXxf/It9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXxf/IR3W+F3a1KaV048PAsKCAcrJx4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///AAPjcqGXJnT4CFeFzki31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+KfWD/iXxf/4l7Xv+DdlrkcGVNgDw2Khn//+sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AFJKOSp9cFavinxf+4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/inxf/4h6Xv+Iel3/iHpd/4h6Xv+GeV37eW1Ur1BINyr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP//3gBsZ1osgnVbv4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4l8X/+HeV3/hnlc/4Z5XP+GeVz/hnlc/4Z5XP+GeFz/fG9Vv1RLOiz/9LoAAgIBAAAAAAAAAAAAAAAAAAAAAAD19fUAl5ibHcbCurWShGn/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Je1//hXhc/4R3W/+Fd1v/hXdb/4V3W/+Fd1v/hXdb/4V3W/+Ed1v/eW1TtUlCMh2CdVkAAAAAAAAAAAAAAAAAeXl5ADY2Ngne3t+O4t/Z/ZKFaf+LfV//i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXte/4R3W/+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+CdVr9c2dPjhwZEwk/OSsAAAAAAAAAAAD///8AxMTES/X19u3k4dv/koRp/4t9X/+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4h6Xv+CdVr/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf9+clftZVtGS/3jrgAAAAAAm5ubAHBwcA/o6Oix+/v7/+Pg2/+ShGn/i31f/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Iel7/gXRZ/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP93a1KxOTMnD1BHNwD///8AycnJRfX19fD7+/v/4+Da/5CCZ/+Jel3/iXtd/4l7Xf+Je13/iXtd/4l7Xf+Ke17/iHhd/4BxV/9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/31uVPBnWURFo45tAAAAAALk5OSN+fn5//r6+v/t7Oj/vLSk/7aunP+3rp3/t66d/7eunf+3rp3/uK+e/6Gmjv9vkG3/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmr/bI1q/2yNav9sjWr/bI1q/2uNav9rjWr/a41q/16GZI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+fr/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/wOfV/0vCi/9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0nAif9Jv4j/RreCxStxUBbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMSM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9JwYn/SL6I/0i+iP9GuoXlOJVqM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/ScCJ/0e8hv9HvIb/R7yG/0a6hfQ9oXJQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0i/iP9GuoX/RrqE/0a6hP9GuoT/RrmD+T6ldWHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMOM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Ivof/RbiD/0W3gv9FuIP/RbiD/0W4g/9Ft4L6PqZ2ZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SL2H/0W2gv9FtYH/RbWB/0W1gf9FtYH/RbWB/0S0gPc+o3Ra3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0e8hv9EtID/RLOA/0SzgP9Es4D/RLOA/0SzgP9Es4D/Q7F/7zyecULS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/SsOL/0jCiv9Iwor/SMKK/0jCiv9Iwor/SMKK/0rCiv9HuoT/RLF+/0Owff9EsH3/RLB9/0Swff9EsH3/RLB9/0Swff9CrnzZOJZrI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6/9/x6f+l38X/o9/D/6Tfw/+k38P/pN/D/6Tfw/+k38T/a9Kz/0DBof9BwKH/QcCh/0HAof9BwKD/QcCg/0G/oP9Bv6D/Qb+g/0C4mK4tbU4I////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6//v6+//7+vv/+/r7//v6+//7+vv//Pr7//v6+/+B597/NdvN/znczf853M3/OdzN/znczf853M3/OdzN/znczf85283+NtHDakb/+gDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f823Mz/OdzN/znczf853M3/OdzN/znczf853M3/OdzN/zjay9s0x7kkNs/BALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdzN/znczf853M3/N9XHgQAAAAAspZoAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znczf853M3/OdzN/zjay8w0yrweNtDCAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f8228z/OdzN/znczf853M3/OdzN/znczf8528zsN9PETkD45gAonJEAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdvM9DjWx24qoJUDMb2wAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znbzPA418hzMr6xBjTIugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/37m3f8z28z/N9zN/znczf8528zaONbIWTK/sgQ0yLsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/vfDr/5Tq4v+L6ODtYODUnDTTxSsAGBsAMrywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+PjS+vf3kPv09Tr/6u4G/+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',red:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQxmbAC0RagpDGZs8ShysdkwdspdMHbKXShysdkMZmzwuEWoKQxmcAAAAAAAAAAAAAAAAAAAAAAAmDlgAAAAAAUQanzRPHrilUx/B6VQgxf1VIMb/VSDG/1Qgxf1TH8DpTh22pUMZnDQAAAABJQ5XAAAAAAB7ensA//8AAFUrr09SH8DdVSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/Ux/B/1IfwP9QHrrdRxqlTwAAAAAoD14A+fn5ANzf1zmMatPfVB7G/1Ugxv9VIMb/VSDG/1Ugxv9TH8L/UR68/1AevP9QHrz/UR68/04dt99EGaA5UB67ALS0sw3x8u+unYDd/1AZxP9THcX/Ux3F/1Qexf9THr//Tx23/08ctv9PHbb/Tx22/08dtv9PHbb/SxuurjkSfg3h4eFK+Pj38LWf5P97UtL/fVXS/31V0/9fOcz/SSfC/0knwP9JJ8D/SSfA/0knwP9JJ8D/SSfA/0gnv/A/KLNK7e3tjPn5+f/29fj/8vD3//Px9//y8Pf/fILz/zQ/8P83QvD/N0Lw/zdC8P83QvD/N0Lw/zdB7/82QOz/Mz3gjPHx8bL5+fn/+fn5//n6+f/5+vn/+fn5/36G9v8yQPT/NkP0/zZD9P82Q/T/NkP0/zVC8v80QOz/M0Dq/zI+47Lz8/O2+fn5//n5+f/5+fn/+fn5//n5+f99hvb/MkD0/zZD9P82Q/T/NkP0/zVC8f8zP+f/Mj7k/zI+5P8xPd628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/gYn2/zdE9P87R/T/O0f0/zZF8P8yQOP/MT/e/zE/3v8xP97/Lz3ZmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9fZ+P/Bxfj/wsb4/7vD+P87j/X/Dnzx/xF98f8RffH/EXzw9xZv5Vzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+/n//Pz5//38+f/x+Pn/OrD+/wCY//8Amf//AJn//wCZ/cYAlPMY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/7vX5/zmu/v8Al///AJj//wCY/vIAlfpWAJ//AOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5/+71+f85rf7/AJb//wCY//QAlvx4AIzrBQCQ8gAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/x9vn/bsP8/CGk/tIAlvxdAJDyBgCT9QAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tuvy93LD4fUhAAC7AESo6wAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgIMDBoKPRwoD14tLhFrNy4RazcoD14tGgo9HAYCDAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+3/wANBR0KLxJuMUEYmGxKHKyiTh22x1Aeu9tRHr3jUR6941Aeu9tOHbbHShysokEYmGwvEm4xDQUeCv+6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoKPgAHAxAHNhR9PEkbqppRHr3hVCDE/FUgxv9VIMf/VSDH/1Ugxv9VIMb/VSDH/1Ugx/9VIMb/VCDE/FEevOFIG6maNRR8PAcDEAcaCj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVUP8AJg5YGUYao4BRH77kVSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMX/VB/E/1Qfw/9QHrvkRRmggCUOVhnQTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA////ADITdSpMHbKvVCDE+1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VCDE/1Mfwv9TH8H/Ux/B/1Mfwv9SH7/7ShytrzEScSr///8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAMto/wBVPoYsUSC3v1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1QfxP9SHsD/Uh6//1Iev/9SHr//Uh6//1Iev/9SHr//SxywvzMTdyymPf8AAQACAAAAAAAAAAAAAAAAAAAAAAD19fUAnaKQHbep1rVfLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/UR6+/1Eevf9RHr3/UR69/1Eevf9RHr3/UR69/1Eevf9RHr3/ShuttS0RaB1PHrkAAAAAAAAAAAAAAAAAeXl5ADY2Ngnf4NyO18zu/V8tyf9UH8b/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VB/D/1EevP9QHrr/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrr9RhqkjhEGKAknDloAAAAAAAAAAAD///8AxMTES/b39O3Zzu//Xy3J/1Qfxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Mfwv9QHbr/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duf9NHLTtPheRS5s5/wAAAAAAm5ubAHBwcA/o6Oix+/z6/9jO7/9fLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9TH8H/Tx24/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9JG6mxIw1RDzAScQD///8AycnJRfX19fD7/Pr/2M3v/1wqyP9SHMX/UhzF/1Icxf9SHMX/UhzF/1Icxf9THcX/Ux7A/04ctf9NHLL/Thyz/04cs/9NHLP/TRyz/00cs/9OHLP/Thyz/04cs/9OHLP/Thyz/04cs/9NHLP/Thyz/0wcsPA/Fo9FYyTkAAAAAALk5OSN+fn5//r6+f/n4vT/noDd/5Z22v+Wdtr/lnba/5Z22v+Wdtr/mHfb/35g1/9KMMr/SC/H/0gvx/9IL8f/SC/H/0gvx/9IL8b/SC/G/0gvxv9HL8b/Ry/G/0cvxv9HL8b/Ry/G/0cvxv9HL8X/Ry7F/z8tuI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/6+vn/+fr5//n6+f/5+vn/+fr5//n6+f/9/fn/ub73/zhF8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zVC8f81QvD/Mz/mxR8njhbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P81QvH/NEHv/zRB7/8zQOrlKTO6M9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NULw/zRA7P80QOv/NEDr/zNA6fQsN8lQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zVB7/8zQOn/Mz/o/zM/6P8zQOj/Mz/n+S04zmHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P80Qe7/Mz/m/zM/5f8zP+b/Mz/m/zM/5v8yP+X6LjnPZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NEHs/zI+4/8yPuP/Mj7j/zI+4/8yPuP/Mj7j/zI+4fctOMxa3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zRA6/8xPeH/MT3g/zE94P8xPeD/MT3g/zE94P8xPeD/MT3e7ys2xkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+4vff/NkP0/zNB9P80QfT/NEH0/zRB9P80QfT/NEH0/zZC8/81P+n/Mjze/zI73f8yO93/Mjvd/zI73f8yO93/Mjvd/zI73f8xO9rZKTO7I56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/9ze+P+covf/mqD3/5qg9/+aoPf/mqD3/5qg9/+aoPf/UoLz/x1p5/8eaeb/Hmnm/x5p5v8eaeX/Hmnl/x5p5f8eaOX/Hmjl/yBh3a4jJokI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vr5//z8+f/8/Pn//Pz5//z8+f/8/Pn//Pz5//z8+f9dvfz/AJf+/wCZ/v8Amf7/AJn+/wCZ/v8Amf7/AJn+/wCZ/v8AmP7+AJLxagC4/wDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/NsAieckAI/xALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJP3gQAAAAAAcr8AAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/MwAi+oeAJDxAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8Al/7sAJL0TgCr/wAAa7QAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj+9ACU+G4AbrgDAIPaAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY/vAAlflzAITcBgCK5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u7/f8Alf//AJf//wCY//8Al/7aAJT4WQCE3AQAiucAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/rNv7/3bG/P9rwfztM6r7nACR9SsAER0AAIPZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+fjS/Pj2kP338jr/+eIG//fqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',yellow:'data:image/vndmicrosofticon;base64,AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAZKhQAOWAiAEV0KgBFdCoAOWAiABkqFAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8ZAAAChAHAEp8JwBvu10AgNeSAInluACN7c4Aj/DXAI/w1wCN7c4AieW4AIDXkgBvu10ASnwnAAoQBwA8ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbLgAAAAAFAFmWMwB/1YwAj/DXAJX7+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJX7+QCP79cAftWMAFmVMwAAAAUAGy4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7v8AAD1mFQB6zXYAkPLdAJf+/gCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP7/AJf+/wCV/P4AjvDdAHjKdgA8ZBUA6f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AABWkCYAh+KoAJb8+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJf+/wCV+v8AlPr/AJT6/wCV+v8Akvf5AIPdqABTjCYA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICABb//wAka5wqAozquwCY/v8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCX/f8Ak/j/AJP3/wCT9/8Ak/f/AJP3/wCT9/8Akvb/AIbiuwBZlyoA//8AAAECAAAAAAAAAAAAAAAAAAAAAADz8/MAqJaJHZDD5rQLnP7/AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alvz/AJL2/wCR9P8AkfT/AJH0/wCR9P8AkfT/AJH0/wCR9P8AkfT/AITftABQhh0AjO0AAAAAAAAAAAAAAAAAfX19ADw8PAni3tuPuuD5/Quc//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJb8/wCQ8/8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8AjvD9AH7UjwAiOQkASHkAAAAAAAgICAD///8AxcXFT/j19O+94vv/Cpz//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCV+/8Aj/H/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCO7v8AiunvAHC8TwD//wAABQgAqKioAHp6ehHp6em3/fv5/7zh+v8KnP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alfr/AI7u/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8Ag9y3AERyEQBenQD///8AzMzMTfb29vP9+/n/vOH6/wqb//8Alv//AJb//wCW//8Alv//AJb//wCW//8Al///AJT5/wCL6/8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCH5fMAb75NAMP/AAAAAAXl5eWX+fn5//v6+f/T6vr/Wbv9/0+3/f9Qt/3/ULf9/1C3/f9Qt/3/Ubj9/zew+/8InO//B5nr/weZ6/8Hmev/B5nq/weZ6v8Hmer/B5nq/weZ6v8Hmer/B5jq/weY6v8HmOn/B5jp/weY6f8HmOn/Bpjp/weP15cBAAAFpKSkHfDw8M/5+fn/+fn5//n5+f/1+Pn/9Pf5//T3+f/09/n/9Pf5//T3+f/4+Pn/o+T6/wq//f8Hv/3/CL/9/wi//f8Iv/3/CL/9/wi//f8Iv/3/CL/8/wi+/P8Ivvz/CL78/wi+/P8Ivvz/CL78/we9+/8HvPr/BrbxzwR9pR3Ly8tA9fX17Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcL//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hv/3/Br36/wa9+v8GuvbsBZnLQNra2mD39/f4+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B778/wa79/8Guvf/Brr3/wa59fgFo9hg4uLidPj4+P35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we++/8GufX/Brj0/wa49P8GuPT/Brfz/QWm3XTk5OR6+Pj4/fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcH//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hvfr/Brfy/wa28f8GtvH/Brbx/wa28f8GtfD9BafdeuXl5W/4+Pj8+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B7z5/wa17/8GtO7/BrTu/wa07v8GtO7/BrTu/waz7fwFpdtv4eHhVvj4+Pb5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we7+P8Gsu3/BrHr/wax6/8Gsev/BrHr/wax6/8Gsev/BrDq9gWh1Vba2toz9vb25vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+k5fv/BsH//wPA//8DwP//A8D//wPA//8DwP//A8D//wXA//8Guvb/BrDq/wau6P8Gruj/Bq7o/wau6P8Gruj/Bq7o/wau6P8GreXmBZnLM7+/vxH09PTC+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/83v+v9x2vz/btn9/2/Z/f9v2f3/b9n9/2/Z/f9v2f3/RdL5/yXG7v8mxOz/JsTs/ybE6/8mxOv/JsTr/yXE6/8lw+v/JcPr/yK95cIQirAR////APDw8IH5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn5//r5+f/6+fn/+vn5//r5+f/6+fn/+vn5//r5+f+H8Pz/Oer+/zzq/v886v7/POr+/zzq/v886v7/POr+/zzq/v886v3/OuDzgWz//wD09PQA5+fnNPf39+n5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876///O+v//zvp/ek32+00Ouf6AMrKygCzs7MF8/Pzmvn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v//zvr//876///OuX5miqptwUwv88AAAAAAPPz8wDp6eku9/f33fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//876///O+v//zvp/d033O8uOuX5AAAAAAAAAAAAvr6+AP///wDx8fFl+Pj49fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876v71OeP2ZY7//wAus8IAAAAAAAAAAAAAAAAA4ODgANPT0wj09PSI+fn5+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v/+jrm+Ygyx9gINdPlAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOHh4Q309PSM+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//g65/qMNtXnDTjd7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOLi4gr09PRw+Pj45/n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Pw/f816///Oev//zvr//876v7nOub5cDbW5wo33O4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ODgANHR0QLx8fE89/f3sfn5+fX5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/t/T7/4Xx/f+A8P31Xez8sTnk9zwuxdUCNtTkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREAP///wDo6OgM9PT0Tff396T4+Pjf+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+fj5+Pjf9vf3pPL09E3m6OgM7/3/APtbOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMjIwD19fUA4uLiBvHx8Sn19fVd9vb2jff396739/e99/f3vff396729vaN9fX1XfHx8Snl4uIG9PX1AFEnIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/wD///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABgAAAAcAAAAPgAAAH4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/KAAAABAAAAAgAAAAAQAgAAAAAAAABAAAEgsAABILAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABorgAAS34IAHTDNQCC22wAh+OMAIfjjACC22wAdMQ1AEx/CABorwAAAAAAAAAAAAAAAAAAAAAAAEBrAAAAAAAAecswAIzsngCU+OUAl/37AJj+/wCY/v8Al/37AJP35QCL6Z4Ad8gwAAAAAAA+aQAAAAAAcXd6AP8AAAAOiNtNAJP32gCY//8AmP//AJj//wCY//8AmP//AJb8/wCU+f8Ak/j/AI7w2gB+1E0AAAAAAEd4APn7/ADc2NU5T7P33gCX//8AmP//AJj//wCY//8AmP//AJX6/wCR8/8AkPL/AJDz/wCQ8/8AjOzeAHrOOQCR9AC3t7cO8e/vsGnA/f8Alf//AJf//wCX//8Al///AJP4/wCN7v8AjOz/AIzs/wCM7P8AjOz/AIzt/wCG4rAAY6oO4uLiT/j39/GIzfz/Mav+/zSs/v80rP7/FaH5/wOV7f8DlOv/A5Tr/wOU6/8DlOv/A5Tr/wOU6/8Dk+jxBIvVT+3t7ZT5+fn/8fb5/+vz+f/r9Pn/6vP5/1nR+/8EvPz/B738/we9/P8Hvfz/B738/we9/P8HvPv/B7r4/wax7ZTy8vK7+fn5//n5+f/6+fn/+vn5//n5+f9e1f3/A8D//wfB//8Hwf//B8H//wfB//8HwP3/Brv3/wa59f8GtO678/Pzwfn5+f/5+fn/+fn5//n5+f/4+fn/XtX9/wPA//8Hwf//B8H//wfB//8Hv/z/Brfz/wa17/8Gte//BrHqwfPz86X5+fn/+fn5//n5+f/5+fn/+Pn5/2DW/f8Gwf//CsL//wrC//8Jv/v/CLXu/wix6f8Isen/CLHp/wet5KXy8vJo+fn5+vn5+f/5+fn/+fn5//n5+f/I7vr/quf7/6zn+/+m5/v/Tdz5/yzV9P8u1fT/LtX0/y7U8/ooyOpo7OzsH/f399D5+fn/+fn5//n5+f/5+fn//Pr5//36+f/++vn/9fn5/2rv/v857P//POz//zzs//886/3QOuLzH////wD09PRh+fn59vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//H4+f9o7v7/OOv//zvr//876//2Ouf6YUH//wDu7u4A6enpB/b29oT5+fn3+fn5//n5+f/5+fn/+fn5//n5+f/x+Pn/Zu7+/zfr//876//3Ouj8hDfc7wc44PMAAAAAAPHx8QDu7u4I9vb2aPj4+Nn5+fn9+fn5//n5+f/5+fn/8/n5/4zx/P1S7P7ZO+n8aDfh9Ag55PcAAAAAAAAAAAAAAAAA6+vrAN/f3wH19fUo9/f3fvj4+MH4+Pje+Pj43vj4+MHq9vh+w/H2KADM5wFk4e8AAAAAAAAAAADwDwAA4AcAAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAgAEAAMADAADgBwAA'};return{FaviconsByHue:FaviconsByHue};});'use strict';Polymer('tr-ui-b-info-bar-group',{ready:function(){this.messages_=[];},clearMessages:function(){this.messages_=[];this.updateContents_();},addMessage:function(text,opt_buttons){opt_buttons=opt_buttons||[];for(var i=0;i<opt_buttons.length;i++){if(opt_buttons[i].buttonText===undefined)
+throw new Error('buttonText must be provided');if(opt_buttons[i].onClick===undefined)
+throw new Error('onClick must be provided');}
+this.messages_.push({text:text,buttons:opt_buttons||[]});this.updateContents_();},updateContents_:function(){this.$.messages.textContent='';this.messages_.forEach(function(message){var bar=document.createElement('tr-ui-b-info-bar');bar.message=message.text;bar.visible=true;message.buttons.forEach(function(button){bar.addButton(button.buttonText,button.onClick);},this);this.$.messages.appendChild(bar);},this);}});'use strict';tr.exportTo('tr.ui',function(){var Task=tr.b.Task;function FindController(brushingStateController){this.brushingStateController_=brushingStateController;this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;this.activePromise_=Promise.resolve();this.activeTask_=undefined;};FindController.prototype={__proto__:Object.prototype,get model(){return this.brushingStateController_.model;},get brushingStateController(){return this.brushingStateController_;},enqueueOperation_:function(operation){var task;if(operation instanceof tr.b.Task)
+task=operation;else
+task=new tr.b.Task(operation,this);if(this.activeTask_){this.activeTask_=this.activeTask_.enqueue(task);}else{this.activeTask_=task;this.activePromise_=Task.RunWhenIdle(this.activeTask_);this.activePromise_.then(function(){this.activePromise_=undefined;this.activeTask_=undefined;}.bind(this));}},startFiltering:function(filterText){var sc=this.brushingStateController_;if(!sc)
+return;this.enqueueOperation_(function(){this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;}.bind(this));var stateFromString;try{stateFromString=sc.uiStateFromString(filterText);}catch(e){this.enqueueOperation_(function(){var overlay=new tr.ui.b.Overlay();overlay.textContent=e.message;overlay.title='UI State Navigation Error';overlay.visible=true;});return this.activePromise_;}
+if(stateFromString!==undefined){this.enqueueOperation_(sc.navToPosition.bind(this,stateFromString,true));}else{if(filterText.length===0){this.enqueueOperation_(sc.findTextCleared.bind(sc));}else{var filter=new tr.c.FullTextFilter(filterText);var filterHits=new tr.model.EventSet();this.enqueueOperation_(sc.addAllEventsMatchingFilterToSelectionAsTask(filter,filterHits));this.enqueueOperation_(function(){this.filterHits_=filterHits;sc.findTextChangedTo(filterHits);}.bind(this));}}
+return this.activePromise_;},get filterHits(){return this.filterHits_;},get currentHitIndex(){return this.currentHitIndex_;},find_:function(dir){var firstHit=this.currentHitIndex_===-1;if(firstHit&&dir<0)
+this.currentHitIndex_=0;var N=this.filterHits.length;this.currentHitIndex_=(this.currentHitIndex_+dir+N)%N;if(!this.brushingStateController_)
+return;this.brushingStateController_.findFocusChangedTo(this.filterHits.subEventSet(this.currentHitIndex_,1));},findNext:function(){this.find_(1);},findPrevious:function(){this.find_(-1);}};return{FindController:FindController};});'use strict';tr.exportTo('tr.ui.b',function(){function TimingTool(viewport,targetElement){this.viewport_=viewport;this.onMouseMove_=this.onMouseMove_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.targetElement_=targetElement;this.isMovingLeftEdge_=false;};TimingTool.prototype={onEnterTiming:function(e){this.targetElement_.addEventListener('mousemove',this.onMouseMove_);this.targetElement_.addEventListener('dblclick',this.onDblClick_);},onBeginTiming:function(e){if(!this.isTouchPointInsideTrackBounds_(e.clientX,e.clientY))
+return;var pt=this.getSnappedToEventPosition_(e);this.mouseDownAt_(pt.x,pt.y);this.updateSnapIndicators_(pt);},updateSnapIndicators_:function(pt){if(!pt.snapped)
+return;var ir=this.viewport_.interestRange;if(ir.min===pt.x)
+ir.leftSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);if(ir.max===pt.x)
+ir.rightSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);},onUpdateTiming:function(e){var pt=this.getSnappedToEventPosition_(e);this.mouseMoveAt_(pt.x,pt.y,true);this.updateSnapIndicators_(pt);},onEndTiming:function(e){this.mouseUp_();},onExitTiming:function(e){this.targetElement_.removeEventListener('mousemove',this.onMouseMove_);this.targetElement_.removeEventListener('dblclick',this.onDblClick_);},onMouseMove_:function(e){if(e.button)
+return;var worldX=this.getWorldXFromEvent_(e);this.mouseMoveAt_(worldX,e.clientY,false);},onDblClick_:function(e){console.error('not implemented');},isTouchPointInsideTrackBounds_:function(clientX,clientY){if(!this.viewport_||!this.viewport_.modelTrackContainer||!this.viewport_.modelTrackContainer.canvas)
+return false;var canvas=this.viewport_.modelTrackContainer.canvas;var canvasRect=canvas.getBoundingClientRect();if(clientX>=canvasRect.left&&clientX<=canvasRect.right&&clientY>=canvasRect.top&&clientY<=canvasRect.bottom)
+return true;return false;},mouseDownAt_:function(worldX,y){var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(ir.isEmpty){ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;return;}
+if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.min=worldX;this.isMovingLeftEdge_=true;return;}
+if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.rightSelected=true;ir.max=worldX;this.isMovingLeftEdge_=false;return;}
+ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;},mouseMoveAt_:function(worldX,y,mouseDown){var ir=this.viewport_.interestRange;if(mouseDown){this.updateMovingEdge_(worldX);return;}
+var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.rightSelected=false;return;}
+if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.leftSelected=false;ir.rightSelected=true;return;}
+ir.leftSelected=false;ir.rightSelected=false;return;},updateMovingEdge_:function(newWorldX){var ir=this.viewport_.interestRange;var a=ir.min;var b=ir.max;if(this.isMovingLeftEdge_)
+a=newWorldX;else
+b=newWorldX;if(a<=b)
+ir.setMinAndMax(a,b);else
+ir.setMinAndMax(b,a);if(ir.min==newWorldX){this.isMovingLeftEdge_=true;ir.leftSelected=true;ir.rightSelected=false;}else{this.isMovingLeftEdge_=false;ir.leftSelected=false;ir.rightSelected=true;}},mouseUp_:function(){var dt=this.viewport_.currentDisplayTransform;var ir=this.viewport_.interestRange;ir.leftSelected=false;ir.rightSelected=false;var pixelRatio=window.devicePixelRatio||1;var minWidthValue=dt.xViewVectorToWorld(2*pixelRatio);if(ir.range<minWidthValue)
+ir.reset();},getWorldXFromEvent_:function(e){var pixelRatio=window.devicePixelRatio||1;var canvas=this.viewport_.modelTrackContainer.canvas;var worldOffset=canvas.getBoundingClientRect().left;var viewX=(e.clientX-worldOffset)*pixelRatio;return this.viewport_.currentDisplayTransform.xViewToWorld(viewX);},getSnappedToEventPosition_:function(e){var pixelRatio=window.devicePixelRatio||1;var EVENT_SNAP_RANGE=16*pixelRatio;var modelTrackContainer=this.viewport_.modelTrackContainer;var modelTrackContainerRect=modelTrackContainer.getBoundingClientRect();var viewport=this.viewport_;var dt=viewport.currentDisplayTransform;var worldMaxDist=dt.xViewVectorToWorld(EVENT_SNAP_RANGE);var worldX=this.getWorldXFromEvent_(e);var mouseY=e.clientY;var selection=new tr.model.EventSet();modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,mouseY,mouseY,selection);if(!selection.length){modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,modelTrackContainerRect.top,modelTrackContainerRect.bottom,selection);}
+var minDistX=worldMaxDist;var minDistY=Infinity;var pixWidth=dt.xViewVectorToWorld(1);var result={x:worldX,y:mouseY-modelTrackContainerRect.top,height:0,snapped:false};var eventBounds=new tr.b.Range();for(var i=0;i<selection.length;i++){var event=selection[i];var track=viewport.trackForEvent(event);var trackRect=track.getBoundingClientRect();eventBounds.reset();event.addBoundsToRange(eventBounds);var eventX;if(Math.abs(eventBounds.min-worldX)<Math.abs(eventBounds.max-worldX)){eventX=eventBounds.min;}else{eventX=eventBounds.max;}
+var distX=eventX-worldX;var eventY=trackRect.top;var eventHeight=trackRect.height;var distY=Math.abs(eventY+eventHeight/2-mouseY);if((distX<=minDistX||Math.abs(distX-minDistX)<pixWidth)&&distY<minDistY){minDistX=distX;minDistY=distY;result.x=eventX;result.y=eventY+
+modelTrackContainer.scrollTop-modelTrackContainerRect.top;result.height=eventHeight;result.snapped=true;}}
+return result;}};return{TimingTool:TimingTool};});'use strict';tr.exportTo('tr.ui',function(){var kDefaultPanAnimationDurationMs=100.0;function TimelineDisplayTransformPanAnimation(deltaX,deltaY,opt_durationMs){this.deltaX=deltaX;this.deltaY=deltaY;if(opt_durationMs===undefined)
+this.durationMs=kDefaultPanAnimationDurationMs;else
+this.durationMs=opt_durationMs;this.startPanX=undefined;this.startPanY=undefined;this.startTimeMs=undefined;}
+TimelineDisplayTransformPanAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.deltaY!==0;},canTakeOverFor:function(existingAnimation){return existingAnimation instanceof TimelineDisplayTransformPanAnimation;},takeOverFor:function(existing,timestamp,target){var remainingDeltaXOnExisting=existing.goalPanX-target.panX;var remainingDeltaYOnExisting=existing.goalPanY-target.panY;var remainingTimeOnExisting=timestamp-(existing.startTimeMs+existing.durationMs);remainingTimeOnExisting=Math.max(remainingTimeOnExisting,0);this.deltaX+=remainingDeltaXOnExisting;this.deltaY+=remainingDeltaYOnExisting;this.durationMs+=remainingTimeOnExisting;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startPanX=target.panX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.panX=tr.b.lerp(percentDone,this.startPanX,this.goalPanX);if(this.affectsPanY)
+target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalPanY);return timestamp>=this.startTimeMs+this.durationMs;},get goalPanX(){return this.startPanX+this.deltaX;},get goalPanY(){return this.startPanY+this.deltaY;}};function TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,goalFocalPointY,zoomInRatioX,opt_durationMs){this.goalFocalPointXWorld=goalFocalPointXWorld;this.goalFocalPointXView=goalFocalPointXView;this.goalFocalPointY=goalFocalPointY;this.zoomInRatioX=zoomInRatioX;if(opt_durationMs===undefined)
+this.durationMs=kDefaultPanAnimationDurationMs;else
+this.durationMs=opt_durationMs;this.startTimeMs=undefined;this.startScaleX=undefined;this.goalScaleX=undefined;this.startPanY=undefined;}
+TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!=this.goalFocalPointY;},canTakeOverFor:function(existingAnimation){return false;},takeOverFor:function(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.scaleX=tr.b.lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalFocalPointY);}
+target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation:TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation:TimelineDisplayTransformZoomToAnimation};});'use strict';tr.exportTo('tr.ui.tracks',function(){var DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};var DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';this.appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);},get canvas(){return this.canvas_;},context:function(){return this.ctx_;},viewportChange_:function(){this.invalidate();},invalidate:function(){if(this.rafPending_)
+return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_:function(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_:function(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);var typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(var idx in typesToDraw){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
+continue;this.children[i].drawTrack(typesToDraw[idx]);}}
+var pixelRatio=window.devicePixelRatio||1;var bounds=this.canvas_.getBoundingClientRect();var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld);},updateCanvasSizeIfNeeded_:function(){var visibleChildTracks=tr.b.asArray(this.children).filter(this.visibleFilter_);var thisBounds=this.getBoundingClientRect();var firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();var lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();var innerWidth=firstChildTrackBounds.width-
+tr.ui.b.constants.HEADING_WIDTH;var innerHeight=lastChildTrackBounds.bottom-firstChildTrackBounds.top;var pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!=innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
+if(this.canvas_.height!=innerHeight*pixelRatio){this.canvas_.height=innerHeight*pixelRatio;this.canvas_.style.height=innerHeight+'px';}},visibleFilter_:function(element){if(!(element instanceof tr.ui.tracks.Track))
+return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
+continue;var trackClientRect=this.children[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
+continue;this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer:DrawingContainer,DrawType:DrawType};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);};ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){var modelItem=this.modelItem_;if(modelItem===undefined)
+return SelectionState.NONE;return modelItem.selectionState;}};return{ProxySelectableItem:ProxySelectableItem};});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){if(this.items_===undefined)
+return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var dumpRadiusView=this.dumpRadiusView;var itemRadiusWorld=dt.xViewVectorToWorld(height);var items=this.items_;var loI=tr.b.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);var oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';var drawItems=function(selected){for(var i=loI;i<items.length;++i){var item=items[i];var x=item.start;if(x-itemRadiusWorld>viewRWorld)
+break;if(item.selected!==selected)
+continue;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
+ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap:function(eventToTrackMap){if(this.items_===undefined)
+return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)
+return;var itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.items_===undefined)
+return;var items=this.items_;var index=tr.b.findFirstIndexInArray(items,function(item){return item.modelItem===event;});if(index===-1)
+return false;var newIndex=index+offset;if(newIndex>=0&&newIndex<items.length){items[newIndex].addToSelection(selection);return true;}
+return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)
+return;var item=tr.b.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)
+return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;};LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack:LetterDotTrack,LetterDot:LetterDot};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
+this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack:AlertTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Task=tr.b.Task;var ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach:function(){this.textContent='';},get tracks_(){var tracks=[];for(var i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track)
+tracks.push(this.children[i]);}
+return tracks;},drawTrack:function(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b)
+this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}
+tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i)
+this.children[i].addEventsToTrackMap(eventToTrackMap);},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.tracks_.length;i++)
+this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var task=new Task();for(var i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}}(i),this);}
+return task;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap:function(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_:function(){this.tracks_.forEach(function(track){this.removeChild(track);},this);}};return{ContainerTrack:ContainerTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartAxis(opt_min,opt_max){this.guid_=tr.b.GUID.allocate();this.bounds=new tr.b.Range();if(opt_min!==undefined)
+this.bounds.addValue(opt_min);if(opt_max!==undefined)
+this.bounds.addValue(opt_max);};ChartAxis.prototype={get guid(){return this.guid_;},valueToUnitRange:function(value){if(this.bounds.isEmpty)
+throw new Error('Chart axis bounds are empty');var bounds=this.bounds;if(bounds.range===0)
+return 0;return(value-bounds.min)/bounds.range;},autoSetFromSeries:function(series,opt_config){var range=new tr.b.Range();series.forEach(function(s){range.addRange(s.range);},this);this.autoSetFromRange(range,opt_config);},autoSetFromRange:function(range,opt_config){if(range.isEmpty)
+return;var bounds=this.bounds;if(bounds.isEmpty){bounds.addRange(range);return;}
+if(!opt_config)
+return;var useRangeMin=(opt_config.expandMin&&range.min<bounds.min||opt_config.shrinkMin&&range.min>bounds.min);var useRangeMax=(opt_config.expandMax&&range.max>bounds.max||opt_config.shrinkMax&&range.max<bounds.max);if(!useRangeMin&&!useRangeMax)
+return;if(useRangeMin&&useRangeMax){bounds.min=range.min;bounds.max=range.max;return;}
+if(useRangeMin){bounds.min=Math.min(range.min,bounds.max);}else{bounds.max=Math.max(range.max,bounds.min);}}};return{ChartAxis:ChartAxis};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.yBase=opt_yBase;};ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{ChartPoint:ChartPoint};});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var ChartSeriesType={LINE:0,AREA:1};var DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5};var LAST_POINT_WIDTH=16;var ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,axis,opt_renderingConfig){this.points=points;this.axis=axis;this.useRenderingConfig_(opt_renderingConfig);}
+ChartSeries.prototype={useRenderingConfig_:function(opt_renderingConfig){var config=opt_renderingConfig||{};tr.b.iterItems(DEFAULT_RENDERING_CONFIG,function(key,defaultValue){var value=config[key];if(value===undefined)
+value=defaultValue;this[key+'_']=value;},this);this.topPadding=this.bottomPadding=Math.max(this.selectedPointSize_,this.unselectedPointSize_)/2;},get range(){var range=new tr.b.Range();this.points.forEach(function(point){range.addValue(point.y);},this);return range;},draw:function(ctx,transform,highDetails){if(this.points===undefined||this.points.length===0)
+return;if(this.chartType_===ChartSeriesType.AREA){this.drawComponent_(ctx,transform,ChartSeriesComponent.BACKGROUND,highDetails);}
+if(this.chartType_===ChartSeriesType.LINE||highDetails){this.drawComponent_(ctx,transform,ChartSeriesComponent.LINE,highDetails);}
+this.drawComponent_(ctx,transform,ChartSeriesComponent.DOTS,highDetails);},drawComponent_:function(ctx,transform,component,highDetails){var extraPixels=0;if(component===ChartSeriesComponent.DOTS){extraPixels=Math.max(this.selectedPointSize_,this.unselectedPointSize_);}
+var leftViewX=transform.leftViewX-extraPixels*transform.pixelRatio;var rightViewX=transform.rightViewX+
+extraPixels*transform.pixelRatio;var leftTimestamp=transform.leftTimestamp-extraPixels;var rightTimestamp=transform.rightTimestamp+extraPixels;var firstVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},leftTimestamp);var lastVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},rightTimestamp);if(lastVisibleIndex>=this.points.length||this.points[lastVisibleIndex].x>rightTimestamp){lastVisibleIndex--;}
+var viewSkipDistance=this.skipDistance_*transform.pixelRatio;var circleRadius;var squareSize;var squareHalfSize;var squareOpacity;switch(component){case ChartSeriesComponent.DOTS:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=transform.pixelRatio;circleRadius=(this.selectedPointSize_/2)*transform.pixelRatio;squareSize=this.unselectedPointSize_*transform.pixelRatio;squareHalfSize=squareSize/2;if(!highDetails){squareOpacity=0;break;}
+var visibleIndexRange=lastVisibleIndex-firstVisibleIndex;if(visibleIndexRange<=0){squareOpacity=1;break;}
+var visibleViewXRange=transform.worldXToViewX(this.points[lastVisibleIndex].x)-
+transform.worldXToViewX(this.points[firstVisibleIndex].x);if(visibleViewXRange===0){squareOpacity=1;break;}
+var density=visibleIndexRange/visibleViewXRange;var clampedDensity=tr.b.clamp(density,this.unselectedPointDensityOpaque_,this.unselectedPointDensityTransparent_);var densityRange=this.unselectedPointDensityTransparent_-
+this.unselectedPointDensityOpaque_;squareOpacity=(this.unselectedPointDensityTransparent_-clampedDensity)/densityRange;break;case ChartSeriesComponent.LINE:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=this.lineWidth_*transform.pixelRatio;break;case ChartSeriesComponent.BACKGROUND:break;default:throw new Error('Invalid component: '+component);}
+var previousViewX=undefined;var previousViewY=undefined;var previousViewYBase=undefined;var lastSelectionState=undefined;var baseSteps=undefined;var startIndex=Math.max(firstVisibleIndex-1,0);for(var i=startIndex;i<this.points.length;i++){var currentPoint=this.points[i];var currentViewX=transform.worldXToViewX(currentPoint.x);if(currentViewX>rightViewX){if(previousViewX!==undefined){previousViewX=currentViewX=rightViewX;if(component===ChartSeriesComponent.BACKGROUND||component===ChartSeriesComponent.LINE){ctx.lineTo(currentViewX,previousViewY);}}
+break;}
+if(i+1<this.points.length){var nextPoint=this.points[i+1];var nextViewX=transform.worldXToViewX(nextPoint.x);if(previousViewX!==undefined&&nextViewX-previousViewX<=viewSkipDistance&&nextViewX<rightViewX){continue;}
+if(currentViewX<leftViewX){currentViewX=leftViewX;}}
+if(previousViewX!==undefined&&currentViewX-previousViewX<viewSkipDistance){currentViewX=previousViewX+viewSkipDistance;}
+var currentViewY=Math.round(transform.worldYToViewY(currentPoint.y));var currentViewYBase;if(currentPoint.yBase===undefined){currentViewYBase=transform.outerBottomViewY;}else{currentViewYBase=Math.round(transform.worldYToViewY(currentPoint.yBase));}
+var currentSelectionState=currentPoint.selectionState;switch(component){case ChartSeriesComponent.DOTS:if(currentSelectionState!==lastSelectionState){if(currentSelectionState===SelectionState.SELECTED){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState);}else if(squareOpacity>0){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,squareOpacity);}}
+if(currentSelectionState===SelectionState.SELECTED){ctx.beginPath();ctx.arc(currentViewX,currentViewY,circleRadius,0,2*Math.PI);ctx.fill();ctx.stroke();}else if(squareOpacity>0){ctx.fillRect(currentViewX-squareHalfSize,currentViewY-squareHalfSize,squareSize,squareSize);}
+break;case ChartSeriesComponent.LINE:if(previousViewX===undefined){ctx.beginPath();ctx.moveTo(currentViewX,currentViewY);}else{ctx.lineTo(currentViewX,previousViewY);}
+ctx.lineTo(currentViewX,currentViewY);break;case ChartSeriesComponent.BACKGROUND:if(previousViewX!==undefined)
+ctx.lineTo(currentViewX,previousViewY);if(currentSelectionState!==lastSelectionState){if(previousViewX!==undefined){var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+ctx.closePath();ctx.fill();}
+ctx.beginPath();ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,this.backgroundOpacity_);ctx.moveTo(currentViewX,currentViewYBase);baseSteps=[];}
+if(currentViewYBase!==previousViewYBase||currentSelectionState!==lastSelectionState){baseSteps.push({viewX:currentViewX,viewY:currentViewYBase});}
+ctx.lineTo(currentViewX,currentViewY);break;default:throw new Error('Not reachable');}
+previousViewX=currentViewX;previousViewY=currentViewY;previousViewYBase=currentViewYBase;lastSelectionState=currentSelectionState;}
+if(previousViewX!==undefined){switch(component){case ChartSeriesComponent.DOTS:break;case ChartSeriesComponent.LINE:ctx.stroke();break;case ChartSeriesComponent.BACKGROUND:var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+ctx.closePath();ctx.fill();break;default:throw new Error('Not reachable');}}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var points=this.points;function getPointWidth(point,i){if(i===points.length-1)
+return LAST_POINT_WIDTH*viewPixWidthWorld;var nextPoint=points[i+1];return nextPoint.x-point.x;}
+function selectPoint(point){point.addToSelection(selection);}
+tr.b.iterateOverIntersectingIntervals(this.points,function(point){return point.x},getPointWidth,loWX,hiWX,selectPoint);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.points===undefined)
+return false;var index=tr.b.findFirstIndexInArray(this.points,function(point){return point.modelItem===event;},this);if(index===-1)
+return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.points.length)
+return false;this.points[newIndex].addToSelection(selection);return true;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.points===undefined)
+return;var item=tr.b.findClosestElementInSortedArray(this.points,function(point){return point.x},worldX,worldMaxDist);if(!item)
+return;item.addToSelection(selection);}};return{ChartSeries:ChartSeries,ChartSeriesType:ChartSeriesType};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartTransform(displayTransform,axis,trackWidth,trackHeight,topPadding,bottomPadding,pixelRatio){this.pixelRatio=pixelRatio;this.leftViewX=0;this.rightViewX=trackWidth;this.leftTimestamp=displayTransform.xViewToWorld(this.leftViewX);this.rightTimestamp=displayTransform.xViewToWorld(this.rightViewX);this.displayTransform_=displayTransform;this.outerTopViewY=0;this.innerTopViewY=topPadding;this.innerBottomViewY=trackHeight-bottomPadding;this.outerBottomViewY=trackHeight;this.axis_=axis;this.innerHeight_=this.innerBottomViewY-this.innerTopViewY;};ChartTransform.prototype={worldXToViewX:function(worldX){return this.displayTransform_.xWorldToView(worldX);},viewXToWorldX:function(viewX){return this.displayTransform_.xViewToWorld(viewX);},worldYToViewY:function(worldY){var innerHeightCoefficient=1-this.axis_.valueToUnitRange(worldY);return innerHeightCoefficient*this.innerHeight_+this.innerTopViewY;}};return{ChartTransform:ChartTransform};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ChartTrack=tr.ui.b.define('chart-track',tr.ui.tracks.Track);ChartTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('chart-track');this.series_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get series(){return this.series_;},set series(series){this.series_=series;this.calculateAxisDataAndPadding_();this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return!!this.series&&this.series.length>0;},calculateAxisDataAndPadding_:function(){if(!this.series_){this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;return;}
+var axisGuidToAxisData={};var topPadding=0;var bottomPadding=0;this.series_.forEach(function(series){var axis=series.axis;var axisGuid=axis.guid;if(!(axisGuid in axisGuidToAxisData)){axisGuidToAxisData[axisGuid]={axis:axis,series:[]};}
+axisGuidToAxisData[axisGuid].series.push(series);topPadding=Math.max(topPadding,series.topPadding);bottomPadding=Math.max(bottomPadding,series.bottomPadding);},this);this.axisGuidToAxisData_=axisGuidToAxisData;this.topPadding_=topPadding;this.bottomPadding_=bottomPadding;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawChart_(viewLWorld,viewRWorld);break;}},drawChart_:function(viewLWorld,viewRWorld){if(!this.series_)
+return;var ctx=this.context();var displayTransform=this.viewport.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var highDetails=this.viewport.highDetails;var width=bounds.width*pixelRatio;var height=bounds.height*pixelRatio;var topPadding=this.topPadding_*pixelRatio;var bottomPadding=this.bottomPadding_*pixelRatio;ctx.save();ctx.beginPath();ctx.rect(0,0,width,height);ctx.clip();this.series_.forEach(function(series){var chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,series.axis,width,height,topPadding,bottomPadding,pixelRatio);series.draw(ctx,chartTransform,highDetails);},this);ctx.restore();},addEventsToTrackMap:function(eventToTrackMap){this.series_.forEach(function(series){series.points.forEach(function(point){point.addToTrackMap(eventToTrackMap,this);},this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){this.series_.forEach(function(series){series.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},this);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var foundItem=false;this.series_.forEach(function(series){foundItem=foundItem||series.addEventNearToProvidedEventToSelection(event,offset,selection);},this);return foundItem;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.series_.forEach(function(series){series.addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);},this);},autoSetAllAxes:function(opt_config){tr.b.iterItems(this.axisGuidToAxisData_,function(axisGuid,axisData){var axis=axisData.axis;var series=axisData.series;axis.autoSetFromSeries(series,opt_config);},this);},autoSetAxis:function(axis,opt_config){var series=this.axisGuidToAxisData_[axis.guid].series;axis.autoSetFromSeries(series,opt_config);}};return{ChartTrack:ChartTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ChartTrack=tr.ui.tracks.ChartTrack;var PowerSeriesTrack=tr.ui.b.define('power-series-track',ChartTrack);PowerSeriesTrack.prototype={__proto__:ChartTrack.prototype,decorate:function(viewport){ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('power-series-track');this.heading='Power';this.powerSeries_=undefined;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return(this.powerSeries_&&this.powerSeries_.samples.length>0);},addContainersToTrackMap:function(containerToTrackMap){containerToTrackMap.addContainer(this.powerSeries_,this);},buildChartSeries_:function(){if(!this.hasVisibleContent)
+return[];var axis=new tr.ui.tracks.ChartAxis(0,undefined);var pts=this.powerSeries_.samples.map(function(smpl){return new tr.ui.tracks.ChartPoint(smpl,smpl.start,smpl.power);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString(this.heading)};return[new tr.ui.tracks.ChartSeries(pts,axis,renderingConfig)];}};return{PowerSeriesTrack:PowerSeriesTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SpacingTrack=tr.ui.b.define('spacing-track',tr.ui.tracks.Track);SpacingTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('spacing-track');this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{SpacingTrack:SpacingTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ContainerTrack=tr.ui.tracks.ContainerTrack;var DeviceTrack=tr.ui.b.define('device-track',ContainerTrack);DeviceTrack.prototype={__proto__:ContainerTrack.prototype,decorate:function(viewport){ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('device-track');this.device_=undefined;this.powerSeriesTrack_=undefined;},get device(){return this.device_;},set device(device){this.device_=device;this.updateContents_();},get powerSeriesTrack(){return this.powerSeriesTrack_;},get hasVisibleContent(){return(this.powerSeriesTrack_&&this.powerSeriesTrack_.hasVisibleContent);},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.device,this);},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},appendPowerSeriesTrack_:function(){this.powerSeriesTrack_=new tr.ui.tracks.PowerSeriesTrack(this.viewport);this.powerSeriesTrack_.powerSeries=this.device.powerSeries;if(this.powerSeriesTrack_.hasVisibleContent){this.appendChild(this.powerSeriesTrack_);this.appendChild(new tr.ui.tracks.SpacingTrack(this.viewport));}},updateContents_:function(){this.clearTracks_();this.appendPowerSeriesTrack_();}};return{DeviceTrack:DeviceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;var LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;var DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;function addDictionary(dstDict,srcDict){tr.b.iterItems(srcDict,function(key,value){var existingValue=dstDict[key];if(existingValue===undefined)
+existingValue=0;dstDict[key]=existingValue+value;});}
+function getProcessMemoryDumpAllocatorSizes(processMemoryDump){var allocatorDumps=processMemoryDump.memoryAllocatorDumps;if(allocatorDumps===undefined)
+return{};var allocatorSizes={};allocatorDumps.forEach(function(allocatorDump){if(allocatorDump.fullName==='tracing')
+return;var allocatorSize=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(allocatorSize===undefined)
+return;var allocatorSizeValue=allocatorSize.value;if(allocatorSizeValue===undefined)
+return;allocatorSizes[allocatorDump.fullName]=allocatorSizeValue;});return allocatorSizes;};function getGlobalMemoryDumpAllocatorSizes(globalMemoryDump){var globalAllocatorSizes={};tr.b.iterItems(globalMemoryDump.processMemoryDumps,function(pid,processMemoryDump){addDictionary(globalAllocatorSizes,getProcessMemoryDumpAllocatorSizes(processMemoryDump));});return globalAllocatorSizes;}
+function buildAllocatedMemoryChartSeries(memoryDumps,memoryDumpToAllocatorSizesFn){var allocatorNameToPoints={};var dumpsData=memoryDumps.map(function(memoryDump){var allocatorSizes=memoryDumpToAllocatorSizesFn(memoryDump);tr.b.iterItems(allocatorSizes,function(allocatorName){allocatorNameToPoints[allocatorName]=[];});return{dump:memoryDump,sizes:allocatorSizes};});if(Object.keys(allocatorNameToPoints).length===0)
+return undefined;dumpsData.forEach(function(dumpData){var memoryDump=dumpData.dump;var allocatorSizes=dumpData.sizes;tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var allocatorSize=allocatorSizes[allocatorName]||0;points.push(new tr.ui.tracks.ChartPoint(memoryDump,memoryDump.start,allocatorSize));});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var colorId=ColorScheme.getColorIdForGeneralPurposeString(allocatorName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.LINE,colorId:colorId};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});return series;}
+function buildMemoryLetterDots(memoryDumps){var lightMemoryColorId=ColorScheme.getColorIdForReservedName('light_memory_dump');var detailedMemoryColorId=ColorScheme.getColorIdForReservedName('detailed_memory_dump');return memoryDumps.map(function(memoryDump){var memoryColorId;switch(memoryDump.levelOfDetail){case DETAILED:memoryColorId=detailedMemoryColorId;break;case LIGHT:default:memoryColorId=lightMemoryColorId;}
+return new tr.ui.tracks.LetterDot(memoryDump,'M',memoryColorId,memoryDump.start);});}
+function buildGlobalUsedMemoryChartSeries(globalMemoryDumps){var containsVmRegions=globalMemoryDumps.some(function(globalDump){for(var pid in globalDump.processMemoryDumps)
+if(globalDump.processMemoryDumps[pid].mostRecentVmRegions)
+return true;return false;});if(!containsVmRegions)
+return undefined;var pidToProcess={};globalMemoryDumps.forEach(function(globalDump){tr.b.iterItems(globalDump.processMemoryDumps,function(pid,processDump){pidToProcess[pid]=processDump.process;});});var pidToPoints={};tr.b.iterItems(pidToProcess,function(pid,process){pidToPoints[pid]=[];});globalMemoryDumps.forEach(function(globalDump){var pssBase=0;tr.b.iterItems(pidToPoints,function(pid,points){var processMemoryDump=globalDump.processMemoryDumps[pid];var cumulativePss=pssBase;if(processMemoryDump!==undefined){var vmRegions=processMemoryDump.mostRecentVmRegions;if(vmRegions!==undefined)
+cumulativePss+=vmRegions.byteStats.proportionalResident||0;}
+points.push(new tr.ui.tracks.ChartPoint(globalDump,globalDump.start,cumulativePss,pssBase));pssBase=cumulativePss;});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(pidToPoints,function(pid,points){var process=pidToProcess[pid];var colorId=ColorScheme.getColorIdForGeneralPurposeString(process.userFriendlyName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:colorId,backgroundOpacity:0.8};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});series.reverse();return series;}
+function buildProcessAllocatedMemoryChartSeries(processMemoryDumps){return buildAllocatedMemoryChartSeries(processMemoryDumps,getProcessMemoryDumpAllocatorSizes);}
+function buildGlobalAllocatedMemoryChartSeries(globalMemoryDumps){return buildAllocatedMemoryChartSeries(globalMemoryDumps,getGlobalMemoryDumpAllocatorSizes);}
+return{buildMemoryLetterDots:buildMemoryLetterDots,buildGlobalUsedMemoryChartSeries:buildGlobalUsedMemoryChartSeries,buildProcessAllocatedMemoryChartSeries:buildProcessAllocatedMemoryChartSeries,buildGlobalAllocatedMemoryChartSeries:buildGlobalAllocatedMemoryChartSeries};});'use strict';tr.exportTo('tr.ui.tracks',function(){var USED_MEMORY_TRACK_HEIGHT=50;var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var GlobalMemoryDumpTrack=tr.ui.b.define('global-memory-dump-track',tr.ui.tracks.ContainerTrack);GlobalMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
+return;this.appendDumpDotsTrack_();this.appendUsedMemoryTrack_();this.appendAllocatedMemoryTrack_();},appendDumpDotsTrack_:function(){var items=tr.ui.tracks.buildMemoryLetterDots(this.memoryDumps_);if(!items)
+return;var track=new tr.ui.tracks.LetterDotTrack(this.viewport);track.heading='Memory Dumps';track.items=items;this.appendChild(track);},appendUsedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalUsedMemoryChartSeries(this.memoryDumps_);if(!series)
+return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per process';track.height=USED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
+return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{GlobalMemoryDumpTrack:GlobalMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function Highlighter(viewport){if(viewport===undefined){throw new Error('viewport must be provided');}
+this.viewport_=viewport;};Highlighter.prototype={__proto__:Object.prototype,processModel:function(model){throw new Error('processModel implementation missing');},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){throw new Error('drawHighlight implementation missing');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Highlighter;tr.b.decorateExtensionRegistry(Highlighter,options);return{Highlighter:Highlighter};});'use strict';tr.exportTo('tr.model',function(){var Settings=tr.b.Settings;function ModelSettings(model){this.model=model;this.objectsByKey_=[];this.nonuniqueKeys_=[];this.buildObjectsByKeyMap_();this.removeNonuniqueKeysFromSettings_();this.ephemeralSettingsByGUID_={};}
+ModelSettings.prototype={buildObjectsByKeyMap_:function(){var objects=[];this.model.iterateAllPersistableObjects(function(o){objects.push(o);});var objectsByKey={};var NONUNIQUE_KEY='nonuniqueKey';for(var i=0;i<objects.length;i++){var object=objects[i];var objectKey=object.getSettingsKey();if(!objectKey)
+continue;if(objectsByKey[objectKey]===undefined){objectsByKey[objectKey]=object;continue;}
+objectsByKey[objectKey]=NONUNIQUE_KEY;}
+var nonuniqueKeys={};tr.b.dictionaryKeys(objectsByKey).forEach(function(objectKey){if(objectsByKey[objectKey]!==NONUNIQUE_KEY)
+return;delete objectsByKey[objectKey];nonuniqueKeys[objectKey]=true;});this.nonuniqueKeys=nonuniqueKeys;this.objectsByKey_=objectsByKey;},removeNonuniqueKeysFromSettings_:function(){var settings=Settings.get('trace_model_settings',{});var settingsChanged=false;tr.b.dictionaryKeys(settings).forEach(function(objectKey){if(!this.nonuniqueKeys[objectKey])
+return;settingsChanged=true;delete settings[objectKey];},this);if(settingsChanged)
+Settings.set('trace_model_settings',settings);},hasUniqueSettingKey:function(object){var objectKey=object.getSettingsKey();if(!objectKey)
+return false;return this.objectsByKey_[objectKey]!==undefined;},getSettingFor:function(object,objectLevelKey,defaultValue){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){var settings=this.getEphemeralSettingsFor_(object);var ephemeralValue=settings[objectLevelKey];if(ephemeralValue!==undefined)
+return ephemeralValue;return defaultValue;}
+var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
+settings[objectKey]={};var value=settings[objectKey][objectLevelKey];if(value!==undefined)
+return value;return defaultValue;},setSettingFor:function(object,objectLevelKey,value){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){this.getEphemeralSettingsFor_(object)[objectLevelKey]=value;return;}
+var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
+settings[objectKey]={};if(settings[objectKey][objectLevelKey]===value)
+return;settings[objectKey][objectLevelKey]=value;Settings.set('trace_model_settings',settings);},getEphemeralSettingsFor_:function(object){if(object.guid===undefined)
+throw new Error('Only objects with GUIDs can be persisted');if(this.ephemeralSettingsByGUID_[object.guid]===undefined)
+this.ephemeralSettingsByGUID_[object.guid]={};return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings:ModelSettings};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate:function(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem:function(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){var numSeries=counter.series.length;var totals=counter.totals;var chartAxis=new tr.ui.tracks.ChartAxis(0,undefined);var chartSeries=counter.series.map(function(series,seriesIndex){var chartPoints=series.samples.map(function(sample,sampleIndex){var total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,chartAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack:CounterTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var startCompare=function(x,y){return x.start-y.start;}
+var FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)
+return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
+FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack:FrameTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.itemsGroupedOnLastUpdateContents_=undefined;this.currentSubRows_=[];this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup:function(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateContents_();},get subRows(){return this.currentSubRows_;},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_==expanded)
+return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_:function(e){if(this.subRows.length<=1)
+return;this.expanded=!this.expanded;if(this.groupingSource_){var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
+e.stopPropagation();},updateExpandedStateFromGroupingSource_:function(){if(this.groupingSource_){var numSubRows=this.subRows.length;var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){var defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
+this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_:function(){var minH=Math.max(2,Math.ceil(18/this.children.length));var h=(this.expanded_?18:minH)+'px';for(var i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0)
+this.children[i].arrowVisible=true;this.children[i].expanded=this.expanded;}
+if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_:function(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);if(!this.itemsToGroup_){this.updateHeadingAndTooltip_();this.currentSubRows_=[];return;}
+if(this.areArrayContentsSame_(this.itemsGroupedOnLastUpdateContents_,this.itemsToGroup_)){this.updateHeadingAndTooltip_();return;}
+this.itemsGroupedOnLastUpdateContents_=this.itemsToGroup_;this.detach();if(!this.itemsToGroup_.length){this.currentSubRows_=[];return;}
+var subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRows_=subRows;for(var srI=0;srI<subRows.length;srI++){var subRow=subRows[srI];if(!subRow.length)
+continue;var track=this.addSubTrack_(subRow);track.addEventListener('heading-clicked',this.onHeadingClicked_.bind(this));}
+this.updateHeadingAndTooltip_();this.expandedStateChanged_();},updateHeadingAndTooltip_:function(){if(!this.firstChild)
+return;this.firstChild.heading=this.heading_;this.firstChild.tooltip=this.tooltip_;},buildSubRows_:function(itemsToGroup){throw new Error('Not implemented');},addSubTrack_:function(subRowItems){throw new Error('Not implemented');},areArrayContentsSame_:function(a,b){if(!a||!b)
+return false;if(!a.length||!b.length)
+return false;if(a.length!=b.length)
+return false;for(var i=0;i<a.length;++i){if(a[i]!=b[i])
+return false;}
+return true;}};return{MultiRowTrack:MultiRowTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectInstanceGroupTrack=tr.ui.b.define('object-instance-group-track',tr.ui.tracks.MultiRowTrack);ObjectInstanceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('object-instance-group-track');this.objectInstances_=undefined;},get objectInstances(){return this.itemsToGroup;},set objectInstances(objectInstances){this.setItemsToGroup(objectInstances);},addSubTrack_:function(objectInstances){var hasMultipleRows=this.subRows.length>1;var track=new tr.ui.tracks.ObjectInstanceTrack(this.viewport);track.objectInstances=objectInstances;this.appendChild(track);return track;},buildSubRows_:function(objectInstances){objectInstances.sort(function(x,y){return x.creationTs-y.creationTs;});var subRows=[];for(var i=0;i<objectInstances.length;i++){var objectInstance=objectInstances[i];var found=false;for(var j=0;j<subRows.length;j++){var subRow=subRows[j];var lastItemInSubRow=subRow[subRow.length-1];if(objectInstance.creationTs>=lastItemInSubRow.deletionTs){found=true;subRow.push(objectInstance);break;}}
+if(!found){var subRow=[objectInstance];subRows.push(subRow);}}
+return subRows;},updateHeadingAndTooltip_:function(){}};return{ObjectInstanceGroupTrack:ObjectInstanceGroupTrack};});'use strict';tr.exportTo('tr.ui.b',function(){function FastRectRenderer(ctx,minRectSize,maxMergeDist,pallette){this.ctx_=ctx;this.minRectSize_=minRectSize;this.maxMergeDist_=maxMergeDist;this.pallette_=pallette;}
+FastRectRenderer.prototype={y_:0,h_:0,merging_:false,mergeStartX_:0,mergeCurRight_:0,mergedColorId_:0,mergedAlpha_:0,setYandH:function(y,h){if(this.y_===y&&this.h_===h)
+return;this.flush();this.y_=y;this.h_=h;},fillRect:function(x,w,colorId,alpha){var r=x+w;if(w<this.minRectSize_){if(r-this.mergeStartX_>this.maxMergeDist_)
+this.flush();if(!this.merging_){this.merging_=true;this.mergeStartX_=x;this.mergeCurRight_=r;this.mergedColorId_=colorId;this.mergedAlpha_=alpha;}else{this.mergeCurRight_=r;if(this.mergedAlpha_<alpha||(this.mergedAlpha_===alpha&&this.mergedColorId_<colorId)){this.mergedAlpha_=alpha;this.mergedColorId_=colorId;}}}else{if(this.merging_)
+this.flush();this.ctx_.fillStyle=this.pallette_[colorId];this.ctx_.globalAlpha=alpha;this.ctx_.fillRect(x,this.y_,w,this.h_);}},flush:function(){if(this.merging_){this.ctx_.fillStyle=this.pallette_[this.mergedColorId_];this.ctx_.globalAlpha=this.mergedAlpha_;this.ctx_.fillRect(this.mergeStartX_,this.y_,this.mergeCurRight_-this.mergeStartX_,this.h_);this.merging_=false;}}};return{FastRectRenderer:FastRectRenderer};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RectTrack=tr.ui.b.define('rect-track',tr.ui.tracks.Track);RectTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('rect-track');this.asyncStyle_=false;this.rects_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},set selectionGenerator(generator){this.heading_.selectionGenerator=generator;},set expanded(expanded){this.heading_.expanded=!!expanded;},set arrowVisible(arrowVisible){this.heading_.arrowVisible=!!arrowVisible;},get expanded(){return this.heading_.expanded;},get asyncStyle(){return this.asyncStyle_;},set asyncStyle(v){this.asyncStyle_=!!v;},get rects(){return this.rects_;},set rects(rects){this.rects_=rects||[];this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return this.rects_.length>0;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawRects_(viewLWorld,viewRWorld);break;}},drawRects_:function(viewLWorld,viewRWorld){var ctx=this.context();ctx.save();var bounds=this.getBoundingClientRect();tr.ui.b.drawSlices(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.rects_,this.asyncStyle_);ctx.restore();if(bounds.height<=6)
+return;var fontSize,yOffset;if(bounds.height<15){fontSize=6;yOffset=1.0;}else{fontSize=10;yOffset=2.5;}
+tr.ui.b.drawLabels(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,this.rects_,this.asyncStyle_,fontSize,yOffset);},addEventsToTrackMap:function(eventToTrackMap){if(this.rects_===undefined||this.rects_===null)
+return;this.rects_.forEach(function(rect){rect.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onRect(rect){rect.addToSelection(selection);}
+onRect=onRect.bind(this);var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.rects_,function(x){return x.start;},function(x){return x.duration==0?x.duration+instantEventWidth:x.duration;},loWX,hiWX,onRect);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var index=tr.b.findFirstIndexInArray(this.rects_,function(rect){return rect.modelItem===event;});if(index===-1)
+return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.rects_.length)
+return false;this.rects_[newIndex].addToSelection(selection);return true;},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.rects_.length;++i){var modelItem=this.rects_[i].modelItem;if(!modelItem)
+continue;if(filter.matchSlice(modelItem))
+selection.push(modelItem);}},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var rect=tr.b.findClosestIntervalInSortedIntervals(this.rects_,function(x){return x.start;},function(x){return x.end;},worldX,worldMaxDist);if(!rect)
+return;rect.addToSelection(selection);}};function Rect(modelItem,title,colorId,start,duration){tr.model.ProxySelectableItem.call(this,modelItem);this.title=title;this.colorId=colorId;this.start=start;this.duration=duration;this.end=start+duration;};Rect.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{RectTrack:RectTrack,Rect:Rect};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ProcessSummaryTrack=tr.ui.b.define('process-summary-track',tr.ui.tracks.RectTrack);ProcessSummaryTrack.buildRectsFromProcess=function(process){if(!process)
+return[];var ops=[];var pushOp=function(isStart,time,slice){ops.push({isStart:isStart,time:time,slice:slice});};for(var tid in process.threads){var sliceGroup=process.threads[tid].sliceGroup;sliceGroup.topLevelSlices.forEach(function(slice){pushOp(true,slice.start,undefined);pushOp(false,slice.end,undefined);});sliceGroup.slices.forEach(function(slice){if(slice.important){pushOp(true,slice.start,slice);pushOp(false,slice.end,slice);}});}
+ops.sort(function(a,b){return a.time-b.time;});var rects=[];var genericColorId=ColorScheme.getColorIdForReservedName('generic_work');var pushRect=function(start,end,slice){rects.push(new tr.ui.tracks.Rect(slice,slice?slice.title:'',slice?slice.colorId:genericColorId,start,end-start));}
+var depth=0;var currentSlice=undefined;var lastStart=undefined;ops.forEach(function(op){depth+=op.isStart?1:-1;if(currentSlice){if(!op.isStart&&op.slice==currentSlice){pushRect(lastStart,op.time,currentSlice);lastStart=depth>=1?op.time:undefined;currentSlice=undefined;}}else{if(op.isStart){if(depth==1){lastStart=op.time;currentSlice=op.slice;}else if(op.slice){if(op.time!=lastStart){pushRect(lastStart,op.time,undefined);lastStart=op.time;}
+currentSlice=op.slice;}}else{if(depth==0){pushRect(lastStart,op.time,undefined);lastStart=undefined;}}}});return rects;};ProcessSummaryTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get process(){return this.process_;},set process(process){this.process_=process;this.rects=ProcessSummaryTrack.buildRectsFromProcess(process);}};return{ProcessSummaryTrack:ProcessSummaryTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceTrack=tr.ui.b.define('slice-track',tr.ui.tracks.RectTrack);SliceTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get slices(){return this.rects;},set slices(slices){this.rects=slices;}};return{SliceTrack:SliceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AsyncSliceGroupTrack=tr.ui.b.define('async-slice-group-track',tr.ui.tracks.MultiRowTrack);AsyncSliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('async-slice-group-track');this.group_=undefined;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);track.asyncStyle=true;return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices,opt_skipSort){if(!opt_skipSort){slices.sort(function(x,y){return x.start-y.start;});}
+var findLevel=function(sliceToPut,rows,n){if(n>=rows.length)
+return true;var subRow=rows[n];var lastSliceInSubRow=subRow[subRow.length-1];if(sliceToPut.start>=lastSliceInSubRow.end){if(sliceToPut.subSlices===undefined||sliceToPut.subSlices.length===0){return true;}
+for(var i=0;i<sliceToPut.subSlices.length;i++){if(!findLevel(sliceToPut.subSlices[i],rows,n+1))
+return false;}
+return true;}
+return false;};var subRows=[];for(var i=0;i<slices.length;i++){var slice=slices[i];var found=false;var index=subRows.length;for(var j=0;j<subRows.length;j++){if(findLevel(slice,subRows,j)){found=true;index=j;break;}}
+if(!found)
+subRows.push([]);subRows[index].push(slice);var fitSubSlicesRecursively=function(subSlices,level,rows){if(subSlices===undefined||subSlices.length===0)
+return;if(level===rows.length)
+rows.push([]);for(var h=0;h<subSlices.length;h++){rows[level].push(subSlices[h]);fitSubSlicesRecursively(subSlices[h].subSlices,level+1,rows);}};fitSubSlicesRecursively(slice.subSlices,index+1,subRows);}
+return subRows;}};return{AsyncSliceGroupTrack:AsyncSliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SampleTrack=tr.ui.b.define('sample-track',tr.ui.tracks.RectTrack);SampleTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get samples(){return this.rects;},set samples(samples){this.rects=samples;}};return{SampleTrack:SampleTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceGroupTrack=tr.ui.b.define('slice-group-track',tr.ui.tracks.MultiRowTrack);SliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('slice-group-track');this.group_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=100;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices){var precisionUnit=this.group.model.intrinsicTimeUnit;if(!slices.length)
+return[];var ops=[];for(var i=0;i<slices.length;i++){if(slices[i].subSlices)
+slices[i].subSlices.splice(0,slices[i].subSlices.length);ops.push(i);}
+ops.sort(function(ix,iy){var x=slices[ix];var y=slices[iy];if(x.start!=y.start)
+return x.start-y.start;return ix-iy;});var subRows=[[]];this.badSlices_=[];for(var i=0;i<ops.length;i++){var op=ops[i];var slice=slices[op];var inserted=false;for(var j=subRows.length-1;j>=0;j--){if(subRows[j].length==0)
+continue;var insertedSlice=subRows[j][subRows[j].length-1];if(slice.start<insertedSlice.start){this.badSlices_.push(slice);inserted=true;}
+if(insertedSlice.bounds(slice,precisionUnit)){while(subRows.length<=j+1)
+subRows.push([]);subRows[j+1].push(slice);if(insertedSlice.subSlices)
+insertedSlice.subSlices.push(slice);inserted=true;break;}}
+if(inserted)
+continue;subRows[0].push(slice);}
+return subRows;}};return{SliceGroupTrack:SliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ThreadTrack=tr.ui.b.define('thread-track',tr.ui.tracks.ContainerTrack);ThreadTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('thread-track');},get thread(){return this.thread_;},set thread(thread){this.thread_=thread;this.updateContents_();},get hasVisibleContent(){return this.tracks_.length>0;},get eventContainer(){return this.thread;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.thread,this);},updateContents_:function(){this.detach();if(!this.thread_)
+return;this.heading=this.thread_.userFriendlyName+': ';this.tooltip=this.thread_.userFriendlyDetails;if(this.thread_.asyncSliceGroup.length)
+this.appendAsyncSliceTracks_();this.appendThreadSamplesTracks_();if(this.thread_.timeSlices){var timeSlicesTrack=new tr.ui.tracks.SliceTrack(this.viewport);timeSlicesTrack.heading='';timeSlicesTrack.height=tr.ui.b.THIN_SLICE_HEIGHT+'px';timeSlicesTrack.slices=this.thread_.timeSlices;if(timeSlicesTrack.hasVisibleContent)
+this.appendChild(timeSlicesTrack);}
+if(this.thread_.sliceGroup.length){var track=new tr.ui.tracks.SliceGroupTrack(this.viewport);track.heading=this.thread_.userFriendlyName;track.tooltip=this.thread_.userFriendlyDetails;track.group=this.thread_.sliceGroup;if(track.hasVisibleContent)
+this.appendChild(track);}},appendAsyncSliceTracks_:function(){var subGroups=this.thread_.asyncSliceGroup.viewSubGroups;subGroups.forEach(function(subGroup){var asyncTrack=new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport);var title=subGroup.slices[0].viewSubGroupTitle;asyncTrack.group=subGroup;asyncTrack.heading=title;if(asyncTrack.hasVisibleContent)
+this.appendChild(asyncTrack);},this);},appendThreadSamplesTracks_:function(){var threadSamples=this.thread_.samples;if(threadSamples===undefined||threadSamples.length===0)
+return;var samplesByTitle={};threadSamples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
+samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SampleTrack(this.viewport);samplesTrack.group=this.thread_;samplesTrack.samples=samples;samplesTrack.heading=this.thread_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.thread_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.samples.length;i++){selection.push(samplesTrack.samples[i]);}
+return selection;};this.appendChild(samplesTrack);},this);},collapsedDidChange:function(collapsed){if(collapsed){var h=parseInt(this.tracks[0].height);for(var i=0;i<this.tracks.length;++i){if(h>2){this.tracks[i].height=Math.floor(h)+'px';}else{this.tracks[i].style.display='none';}
+h=h*0.5;}}else{for(var i=0;i<this.tracks.length;++i){this.tracks[i].height=this.tracks[0].height;this.tracks[i].style.display='';}}}};return{ThreadTrack:ThreadTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectSnapshotView=tr.ui.analysis.ObjectSnapshotView;var ObjectInstanceView=tr.ui.analysis.ObjectInstanceView;var SpacingTrack=tr.ui.tracks.SpacingTrack;var ProcessTrackBase=tr.ui.b.define('process-track-base',tr.ui.tracks.ContainerTrack);ProcessTrackBase.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.processBase_=undefined;this.classList.add('process-track-base');this.classList.add('expanded');this.processNameEl_=tr.ui.b.createSpan();this.processNameEl_.classList.add('process-track-name');this.headerEl_=tr.ui.b.createDiv({className:'process-track-header'});this.headerEl_.appendChild(this.processNameEl_);this.headerEl_.addEventListener('click',this.onHeaderClick_.bind(this));this.appendChild(this.headerEl_);},get processBase(){return this.processBase_;},set processBase(processBase){this.processBase_=processBase;if(this.processBase_){var modelSettings=new tr.model.ModelSettings(this.processBase_.model);var defaultValue=this.processBase_.important;this.expanded=modelSettings.getSettingFor(this.processBase_,'expanded',defaultValue);}
+this.updateContents_();},get expanded(){return this.classList.contains('expanded');},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)
+return;this.classList.toggle('expanded');this.viewport_.dispatchChangeEvent();if(!this.processBase_)
+return;var modelSettings=new tr.model.ModelSettings(this.processBase_.model);modelSettings.setSettingFor(this.processBase_,'expanded',expanded);this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},get hasVisibleContent(){if(this.expanded)
+return this.children.length>1;return true;},onHeaderClick_:function(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},updateContents_:function(){this.clearTracks_();if(!this.processBase_)
+return;this.processNameEl_.textContent=this.processBase_.userFriendlyName;this.headerEl_.title=this.processBase_.userFriendlyDetails;this.willAppendTracks_();if(this.expanded){this.appendMemoryDumpTrack_();this.appendObjectInstanceTracks_();this.appendCounterTracks_();this.appendFrameTrack_();this.appendThreadTracks_();}else{this.appendSummaryTrack_();}
+this.didAppendTracks_();},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},willAppendTracks_:function(){},didAppendTracks_:function(){},appendMemoryDumpTrack_:function(){},appendSummaryTrack_:function(){var track=new tr.ui.tracks.ProcessSummaryTrack(this.viewport);track.process=this.process;if(!track.hasVisibleContent)
+return;this.appendChild(track);},appendFrameTrack_:function(){var frames=this.process?this.process.frames:undefined;if(!frames||!frames.length)
+return;var track=new tr.ui.tracks.FrameTrack(this.viewport);track.frames=frames;this.appendChild(track);},appendObjectInstanceTracks_:function(){var instancesByTypeName=this.processBase_.objects.getAllInstancesByTypeName();var instanceTypeNames=tr.b.dictionaryKeys(instancesByTypeName);instanceTypeNames.sort();var didAppendAtLeastOneTrack=false;instanceTypeNames.forEach(function(typeName){var allInstances=instancesByTypeName[typeName];var instanceViewInfo=ObjectInstanceView.getTypeInfo(undefined,typeName);var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(instanceViewInfo&&!instanceViewInfo.metadata.showInTrackView)
+instanceViewInfo=undefined;if(snapshotViewInfo&&!snapshotViewInfo.metadata.showInTrackView)
+snapshotViewInfo=undefined;var hasViewInfo=instanceViewInfo||snapshotViewInfo;var visibleInstances=[];for(var i=0;i<allInstances.length;i++){var instance=allInstances[i];if(instance.snapshots.length===0)
+continue;if(instance.hasImplicitSnapshots&&!hasViewInfo)
+continue;visibleInstances.push(instance);}
+if(visibleInstances.length===0)
+return;var trackConstructor=tr.ui.tracks.ObjectInstanceTrack.getConstructor(undefined,typeName);if(!trackConstructor){var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(snapshotViewInfo&&snapshotViewInfo.metadata.showInstances){trackConstructor=tr.ui.tracks.ObjectInstanceGroupTrack;}else{trackConstructor=tr.ui.tracks.ObjectInstanceTrack;}}
+var track=new trackConstructor(this.viewport);track.objectInstances=visibleInstances;this.appendChild(track);didAppendAtLeastOneTrack=true;},this);if(didAppendAtLeastOneTrack)
+this.appendChild(new SpacingTrack(this.viewport));},appendCounterTracks_:function(){var counters=tr.b.dictionaryValues(this.processBase.counters);counters.sort(tr.model.Counter.compare);counters.forEach(function(counter){var track=new tr.ui.tracks.CounterTrack(this.viewport);track.counter=counter;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));},appendThreadTracks_:function(){var threads=tr.b.dictionaryValues(this.processBase.threads);threads.sort(tr.model.Thread.compare);threads.forEach(function(thread){var track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)
+return;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));}};return{ProcessTrackBase:ProcessTrackBase};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CpuTrack=tr.ui.b.define('cpu-track',tr.ui.tracks.ContainerTrack);CpuTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('cpu-track');this.detailedMode_=true;},get cpu(){return this.cpu_;},set cpu(cpu){this.cpu_=cpu;this.updateContents_();},get detailedMode(){return this.detailedMode_;},set detailedMode(detailedMode){this.detailedMode_=detailedMode;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(value){this.tooltip_=value;this.updateContents_();},get hasVisibleContent(){if(this.cpu_===undefined)
+return false;var cpu=this.cpu_;if(cpu.slices.length)
+return true;if(cpu.samples&&cpu.samples.length)
+return true;if(tr.b.dictionaryLength(cpu.counters)>0)
+return true;return false;},updateContents_:function(){this.detach();if(!this.cpu_)
+return;var slices=this.cpu_.slices;if(slices.length){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;track.heading=this.cpu_.userFriendlyName+':';this.appendChild(track);}
+if(this.detailedMode_){this.appendSamplesTracks_();for(var counterName in this.cpu_.counters){var counter=this.cpu_.counters[counterName];track=new tr.ui.tracks.CounterTrack(this.viewport);track.heading=this.cpu_.userFriendlyName+' '+
+counter.name+':';track.counter=counter;this.appendChild(track);}}},appendSamplesTracks_:function(){var samples=this.cpu_.samples;if(samples===undefined||samples.length===0)
+return;var samplesByTitle={};samples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
+samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SliceTrack(this.viewport);samplesTrack.group=this.cpu_;samplesTrack.slices=samples;samplesTrack.heading=this.cpu_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.cpu_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.slices.length;i++){selection.push(samplesTrack.slices[i]);}
+return selection;};this.appendChild(samplesTrack);},this);}};return{CpuTrack:CpuTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Cpu=tr.model.Cpu;var CpuTrack=tr.ui.tracks.cpu_track;var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var SpacingTrack=tr.ui.tracks.SpacingTrack;var KernelTrack=tr.ui.b.define('kernel-track',ProcessTrackBase);KernelTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){ProcessTrackBase.prototype.decorate.call(this,viewport);},set kernel(kernel){this.processBase=kernel;},get kernel(){return this.processBase;},get eventContainer(){return this.kernel;},get hasVisibleContent(){return this.children.length>1;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.kernel,this);},willAppendTracks_:function(){var cpus=tr.b.dictionaryValues(this.kernel.cpus);cpus.sort(tr.model.Cpu.compare);var didAppendAtLeastOneTrack=false;for(var i=0;i<cpus.length;++i){var cpu=cpus[i];var track=new tr.ui.tracks.CpuTrack(this.viewport);track.detailedMode=this.expanded;track.cpu=cpu;if(!track.hasVisibleContent)
+continue;this.appendChild(track);didAppendAtLeastOneTrack=true;}
+if(didAppendAtLeastOneTrack)
+this.appendChild(new SpacingTrack(this.viewport));}};return{KernelTrack:KernelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var InteractionTrack=tr.ui.b.define('interaction-track',tr.ui.tracks.MultiRowTrack);InteractionTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.heading='Interactions';this.subRows_=[];},set model(model){this.setItemsToGroup(model.userModel.expectations,{guid:tr.b.GUID.allocate(),model:model,getSettingsKey:function(){return undefined;}});},buildSubRows_:function(slices){if(this.subRows_.length)
+return this.subRows_;this.subRows_.push.apply(this.subRows_,tr.ui.tracks.AsyncSliceGroupTrack.prototype.buildSubRows_.call({},slices,true));return this.subRows_;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;}};return{InteractionTrack:InteractionTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
+return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
+return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{ProcessMemoryDumpTrack:ProcessMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack:function(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0)
+break;var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
+tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_:function(){var ctx=this.context();var canvasBounds=ctx.canvas.getBoundingClientRect();var pixelRatio=window.devicePixelRatio||1;var draw=false;ctx.fillStyle='#eee';for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack))
+continue;draw=!draw;if(!draw)
+continue;var bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_:function(){var processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){var pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;this.appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack:ProcessTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('model-track');var typeInfos=tr.ui.tracks.Highlighter.getAllRegisteredTypeInfos();this.highlighters_=typeInfos.map(function(typeInfo){return new typeInfo.constructor(viewport);});this.upperMode_=false;this.annotationViews_=[];},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach:function(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_:function(){this.textContent='';if(!this.model_)
+return;if(this.upperMode_)
+this.updateContentsForUpperMode_();else
+this.updateContentsForLowerMode_();},updateContentsForUpperMode_:function(){},updateContentsForLowerMode_:function(){if(this.model_.userModel.expectations.length){var mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;this.appendChild(mrt);}
+if(this.model_.alerts.length){var at=new tr.ui.tracks.AlertTrack(this.viewport_);at.alerts=this.model_.alerts;this.appendChild(at);}
+if(this.model_.globalMemoryDumps.length){var gmdt=new tr.ui.tracks.GlobalMemoryDumpTrack(this.viewport_);gmdt.memoryDumps=this.model_.globalMemoryDumps;this.appendChild(gmdt);}
+this.appendDeviceTrack_();this.appendKernelTrack_();var processes=this.model_.getAllProcesses();processes.sort(tr.model.Process.compare);for(var i=0;i<processes.length;++i){var process=processes[i];var track=new tr.ui.tracks.ProcessTrack(this.viewport);track.process=process;if(!track.hasVisibleContent)
+continue;this.appendChild(track);}
+this.viewport_.rebuildEventToTrackMap();this.viewport_.rebuildContainerToTrackMap();for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].processModel(this.model_);}
+this.updateAnnotations_();},updateAnnotations_:function(){this.annotationViews_=[];var annotations=this.model_.getAllAnnotations();for(var i=0;i<annotations.length;i++){this.annotationViews_.push(annotations[i].getOrCreateView(this.viewport_));}
+this.invalidateDrawingContainer();},addEventsToTrackMap:function(eventToTrackMap){if(!this.model_)
+return;var tracks=this.children;for(var i=0;i<tracks.length;++i)
+tracks[i].addEventsToTrackMap(eventToTrackMap);if(this.instantEvents===undefined)
+return;var vp=this.viewport_;this.instantEvents.forEach(function(ev){eventToTrackMap.addEvent(ev,this);}.bind(this));},appendDeviceTrack_:function(){var device=this.model.device;var track=new tr.ui.tracks.DeviceTrack(this.viewport);track.device=this.model.device;if(!track.hasVisibleContent)
+return;this.appendChild(track);},appendKernelTrack_:function(){var kernel=this.model.kernel;var track=new tr.ui.tracks.KernelTrack(this.viewport);track.kernel=this.model.kernel;if(!track.hasVisibleContent)
+return;this.appendChild(track);},drawTrack:function(type){var ctx=this.context();if(!this.model_)
+return;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);switch(type){case tr.ui.tracks.DrawType.GRID:this.viewport.drawMajorMarkLines(ctx);ctx.restore();return;case tr.ui.tracks.DrawType.FLOW_ARROWS:if(this.model_.flowIntervalTree.size===0){ctx.restore();return;}
+this.drawFlowArrows_(viewLWorld,viewRWorld);ctx.restore();return;case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.model_.instantEvents||this.model_.instantEvents.length===0)
+break;tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.model_.instantEvents,4);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(ctx,viewLWorld,viewRWorld);this.viewport.interestRange.drawIndicators(ctx,viewLWorld,viewRWorld);}
+ctx.restore();return;case tr.ui.tracks.DrawType.HIGHLIGHTS:for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].drawHighlight(ctx,dt,viewLWorld,viewRWorld,bounds.height);}
+ctx.restore();return;case tr.ui.tracks.DrawType.ANNOTATIONS:for(var i=0;i<this.annotationViews_.length;i++){this.annotationViews_[i].draw(ctx);}
+ctx.restore();return;}
+ctx.restore();tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawFlowArrows_:function(viewLWorld,viewRWorld){var ctx=this.context();var dt=this.viewport.currentDisplayTransform;dt.applyTransformToCanvas(ctx);var pixWidth=dt.xViewVectorToWorld(1);ctx.strokeStyle='rgba(0, 0, 0, 0.4)';ctx.fillStyle='rgba(0, 0, 0, 0.4)';ctx.lineWidth=pixWidth>1.0?1:pixWidth;var events=this.model_.flowIntervalTree.findIntersection(viewLWorld,viewRWorld);var onlyHighlighted=!this.viewport.showFlowEvents;var canvasBounds=ctx.canvas.getBoundingClientRect();for(var i=0;i<events.length;++i){if(onlyHighlighted&&events[i].selectionState!==SelectionState.SELECTED&&events[i].selectionState!==SelectionState.HIGHLIGHTED)
+continue;this.drawFlowArrow_(ctx,events[i],canvasBounds,pixWidth);}},drawFlowArrow_:function(ctx,flowEvent,canvasBounds,pixWidth){var pixelRatio=window.devicePixelRatio||1;var startTrack=this.viewport.trackForEvent(flowEvent.startSlice);var endTrack=this.viewport.trackForEvent(flowEvent.endSlice);if(startTrack===undefined||endTrack===undefined)
+return;var startBounds=startTrack.getBoundingClientRect();var endBounds=endTrack.getBoundingClientRect();if(flowEvent.selectionState==SelectionState.SELECTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.HIGHLIGHTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.DIMMED){ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.2)';}else{var hasBoost=false;var startSlice=flowEvent.startSlice;hasBoost|=startSlice.selectionState===SelectionState.SELECTED;hasBoost|=startSlice.selectionState===SelectionState.HIGHLIGHTED;var endSlice=flowEvent.endSlice;hasBoost|=endSlice.selectionState===SelectionState.SELECTED;hasBoost|=endSlice.selectionState===SelectionState.HIGHLIGHTED;if(hasBoost){ctx.shadowBlur=1;ctx.shadowColor='rgba(255, 0, 0, 0.4)';ctx.shadowOffsety=2;ctx.strokeStyle='rgba(255, 0, 0, 0.4)';}else{ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.4)';}}
+var startSize=startBounds.left+startBounds.top+
+startBounds.bottom+startBounds.right;var endSize=endBounds.left+endBounds.top+
+endBounds.bottom+endBounds.right;if(startSize===0&&endSize===0)
+return;var startY=this.calculateTrackY_(startTrack,canvasBounds);var endY=this.calculateTrackY_(endTrack,canvasBounds);var pixelStartY=pixelRatio*startY;var pixelEndY=pixelRatio*endY;var half=(flowEvent.end-flowEvent.start)/2;ctx.beginPath();ctx.moveTo(flowEvent.start,pixelStartY);ctx.bezierCurveTo(flowEvent.start+half,pixelStartY,flowEvent.start+half,pixelEndY,flowEvent.end,pixelEndY);ctx.stroke();var arrowWidth=5*pixWidth*pixelRatio;var distance=flowEvent.end-flowEvent.start;if(distance<=(2*arrowWidth))
+return;var tipX=flowEvent.end;var tipY=pixelEndY;var arrowHeight=(endBounds.height/4)*pixelRatio;tr.ui.b.drawTriangle(ctx,tipX,tipY,tipX-arrowWidth,tipY-arrowHeight,tipX-arrowWidth,tipY+arrowHeight);ctx.fill();},calculateTrackY_:function(track,canvasBounds){var bounds=track.getBoundingClientRect();var size=bounds.left+bounds.top+bounds.bottom+bounds.right;if(size===0)
+return this.calculateTrackY_(track.parentNode,canvasBounds);return bounds.top-canvasBounds.top+(bounds.height/2);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+var instantEventWidth=3*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.model_.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.model_.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ModelTrack:ModelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RulerTrack=tr.ui.b.define('ruler-track',tr.ui.tracks.Track);var logOf10=Math.log(10);function log10(x){return Math.log(x)/logOf10;}
+RulerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('ruler-track');this.strings_secs_=[];this.strings_msecs_=[];this.strings_usecs_=[];this.strings_nsecs_=[];this.viewportChange_=this.viewportChange_.bind(this);viewport.addEventListener('change',this.viewportChange_);var heading=document.createElement('tr-ui-heading');heading.arrowVisible=false;this.appendChild(heading);},detach:function(){tr.ui.tracks.Track.prototype.detach.call(this);this.viewport.removeEventListener('change',this.viewportChange_);},viewportChange_:function(){if(this.viewport.interestRange.isEmpty)
+this.classList.remove('tall-mode');else
+this.classList.add('tall-mode');},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GRID:this.drawGrid_(viewLWorld,viewRWorld);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty)
+this.viewport.interestRange.draw(this.context(),viewLWorld,viewRWorld);break;}},drawGrid_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var canvasBounds=ctx.canvas.getBoundingClientRect();var trackBounds=this.getBoundingClientRect();var width=canvasBounds.width*pixelRatio;var height=trackBounds.height*pixelRatio;var hasInterestRange=!this.viewport.interestRange.isEmpty;var rulerHeight=hasInterestRange?(height*2)/5:height;var vp=this.viewport;var dt=vp.currentDisplayTransform;var idealMajorMarkDistancePix=150*pixelRatio;var idealMajorMarkDistanceWorld=dt.xViewVectorToWorld(idealMajorMarkDistancePix);var majorMarkDistanceWorld;var conservativeGuess=Math.pow(10,Math.ceil(log10(idealMajorMarkDistanceWorld)));var divisors=[10,5,2,1];for(var i=0;i<divisors.length;++i){var tightenedGuess=conservativeGuess/divisors[i];if(dt.xWorldVectorToView(tightenedGuess)<idealMajorMarkDistancePix)
+continue;majorMarkDistanceWorld=conservativeGuess/divisors[i-1];break;}
+var unit;var unitDivisor;var tickLabels=undefined;if(majorMarkDistanceWorld<0.0001){unit='ns';unitDivisor=0.000001;tickLabels=this.strings_nsecs_;}else if(majorMarkDistanceWorld<0.1){unit='us';unitDivisor=0.001;tickLabels=this.strings_usecs_;}else if(majorMarkDistanceWorld<100){unit='ms';unitDivisor=1;tickLabels=this.strings_msecs_;}else{unit='s';unitDivisor=1000;tickLabels=this.strings_secs_;}
+var numTicksPerMajor=5;var minorMarkDistanceWorld=majorMarkDistanceWorld/numTicksPerMajor;var minorMarkDistancePx=dt.xWorldVectorToView(minorMarkDistanceWorld);var firstMajorMark=Math.floor(viewLWorld/majorMarkDistanceWorld)*majorMarkDistanceWorld;var minorTickH=Math.floor(rulerHeight*0.25);ctx.save();var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);var crispLineCorrection=(ctx.lineWidth%2)/2;ctx.translate(crispLineCorrection,-crispLineCorrection);ctx.fillStyle='rgb(0, 0, 0)';ctx.strokeStyle='rgb(0, 0, 0)';ctx.textAlign='left';ctx.textBaseline='top';ctx.font=(9*pixelRatio)+'px sans-serif';vp.majorMarkPositions=[];ctx.beginPath();for(var curX=firstMajorMark;curX<viewRWorld;curX+=majorMarkDistanceWorld){var curXView=Math.floor(dt.xWorldToView(curX));var unitValue=curX/unitDivisor;var roundedUnitValue=Math.round(unitValue*100000)/100000;if(!tickLabels[roundedUnitValue])
+tickLabels[roundedUnitValue]=roundedUnitValue+' '+unit;ctx.fillText(tickLabels[roundedUnitValue],curXView+(2*pixelRatio),0);vp.majorMarkPositions.push(curXView);tr.ui.b.drawLine(ctx,curXView,0,curXView,rulerHeight);for(var i=1;i<numTicksPerMajor;++i){var xView=Math.floor(curXView+minorMarkDistancePx*i);tr.ui.b.drawLine(ctx,xView,rulerHeight-minorTickH,xView,rulerHeight);}}
+ctx.strokeStyle='rgb(0, 0, 0)';tr.ui.b.drawLine(ctx,0,height,width,height);ctx.stroke();if(!hasInterestRange)
+return;tr.ui.b.drawLine(ctx,0,rulerHeight,width,rulerHeight);ctx.stroke();var displayDistance;var displayTextColor='rgb(0,0,0)';var arrowSpacing=10*pixelRatio;var arrowColor='rgb(128,121,121)';var arrowPosY=rulerHeight*1.75;var arrowWidthView=3*pixelRatio;var arrowLengthView=10*pixelRatio;var spaceForArrowsView=2*(arrowWidthView+arrowSpacing);ctx.textBaseline='middle';ctx.font=(14*pixelRatio)+'px sans-serif';var textPosY=arrowPosY;var interestRange=vp.interestRange;if(interestRange.range===0){var markerWorld=interestRange.min;var markerView=dt.xWorldToView(markerWorld);var displayValue=markerWorld/unitDivisor;displayValue=Math.abs((Math.round(displayValue*1000)/1000));var textToDraw=displayValue+' '+unit;var textLeftView=markerView+4*pixelRatio;var textWidthView=ctx.measureText(textToDraw).width;if(textLeftView+textWidthView>width)
+textLeftView=markerView-4*pixelRatio-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);return;}
+var leftMarker=interestRange.min;var rightMarker=interestRange.max;var leftMarkerView=dt.xWorldToView(leftMarker);var rightMarkerView=dt.xWorldToView(rightMarker);var distanceBetweenMarkers=interestRange.range;var distanceBetweenMarkersView=dt.xWorldVectorToView(distanceBetweenMarkers);var positionInMiddleOfMarkersView=leftMarkerView+(distanceBetweenMarkersView/2);if(distanceBetweenMarkers<0.0001){unit='ns';unitDivisor=0.000001;}else if(distanceBetweenMarkers<0.1){unit='us';unitDivisor=0.001;}else if(distanceBetweenMarkers<100){unit='ms';unitDivisor=1;}else{unit='s';unitDivisor=1000;}
+displayDistance=distanceBetweenMarkers/unitDivisor;var roundedDisplayDistance=Math.abs((Math.round(displayDistance*1000)/1000));var textToDraw=roundedDisplayDistance+' '+unit;var textWidthView=ctx.measureText(textToDraw).width;var spaceForArrowsAndTextView=textWidthView+spaceForArrowsView+arrowSpacing;var textLeftView=positionInMiddleOfMarkersView-textWidthView/2;var textRightView=textLeftView+textWidthView;if(spaceForArrowsAndTextView>distanceBetweenMarkersView){textLeftView=rightMarkerView+2*arrowSpacing;if(textLeftView+textWidthView>width)
+textLeftView=leftMarkerView-2*arrowSpacing-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);ctx.strokeStyle=arrowColor;ctx.beginPath();tr.ui.b.drawLine(ctx,leftMarkerView,arrowPosY,rightMarkerView,arrowPosY);ctx.stroke();ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftMarkerView-1.5*arrowSpacing,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightMarkerView+1.5*arrowSpacing,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}else if(spaceForArrowsView<=distanceBetweenMarkersView){var leftArrowStart;var rightArrowStart;if(spaceForArrowsAndTextView<=distanceBetweenMarkersView){ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);leftArrowStart=textLeftView-arrowSpacing;rightArrowStart=textRightView+arrowSpacing;}else{leftArrowStart=positionInMiddleOfMarkersView;rightArrowStart=positionInMiddleOfMarkersView;}
+ctx.strokeStyle=arrowColor;ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftArrowStart,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightArrowStart,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}
+ctx.restore();},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{RulerTrack:RulerTrack};});'use strict';Polymer('tr-ui-timeline-track-view',{ready:function(){this.displayTransform_=new tr.ui.TimelineDisplayTransform();this.model_=undefined;this.timelineView_=undefined;this.viewport_=new tr.ui.TimelineViewport(this);this.viewportDisplayTransformAtMouseDown_=undefined;this.brushingStateController_=undefined;this.rulerTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.rulerTrackContainer_);this.rulerTrackContainer_.invalidate();this.rulerTrack_=new tr.ui.tracks.RulerTrack(this.viewport_);this.rulerTrackContainer_.appendChild(this.rulerTrack_);this.upperModelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.upperModelTrack_.upperMode=true;this.rulerTrackContainer_.appendChild(this.upperModelTrack_);this.modelTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.modelTrackContainer_);this.modelTrackContainer_.style.display='block';this.modelTrackContainer_.invalidate();this.viewport_.modelTrackContainer=this.modelTrackContainer_;this.modelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.modelTrackContainer_.appendChild(this.modelTrack_);this.timingTool_=new tr.ui.b.TimingTool(this.viewport_,this);this.initMouseModeSelector();this.hideDragBox_();this.initHintText_();this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.addEventListener('dblclick',this.onDblClick_);this.onMouseWheel_=this.onMouseWheel_.bind(this);this.addEventListener('mousewheel',this.onMouseWheel_);this.onMouseDown_=this.onMouseDown_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.onMouseMove_=this.onMouseMove_.bind(this);this.addEventListener('mousemove',this.onMouseMove_);this.onTouchStart_=this.onTouchStart_.bind(this);this.addEventListener('touchstart',this.onTouchStart_);this.onTouchMove_=this.onTouchMove_.bind(this);this.addEventListener('touchmove',this.onTouchMove_);this.onTouchEnd_=this.onTouchEnd_.bind(this);this.addEventListener('touchend',this.onTouchEnd_);this.addHotKeys_();this.mouseViewPosAtMouseDown_={x:0,y:0};this.lastMouseViewPos_={x:0,y:0};this.lastTouchViewPositions_=[];this.alert_=undefined;this.isPanningAndScanning_=false;this.isZooming_=false;},initMouseModeSelector:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this;this.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.addEventListener('beginpan',this.onBeginPanScan_.bind(this));this.mouseModeSelector_.addEventListener('updatepan',this.onUpdatePanScan_.bind(this));this.mouseModeSelector_.addEventListener('endpan',this.onEndPanScan_.bind(this));this.mouseModeSelector_.addEventListener('beginselection',this.onBeginSelection_.bind(this));this.mouseModeSelector_.addEventListener('updateselection',this.onUpdateSelection_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onEndSelection_.bind(this));this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));this.mouseModeSelector_.addEventListener('entertiming',this.timingTool_.onEnterTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('begintiming',this.timingTool_.onBeginTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('updatetiming',this.timingTool_.onUpdateTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('endtiming',this.timingTool_.onEndTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('exittiming',this.timingTool_.onExitTiming.bind(this.timingTool_));var m=tr.ui.b.MOUSE_SELECTOR_MODE;this.mouseModeSelector_.supportedModeMask=m.SELECTION|m.PANSCAN|m.ZOOM|m.TIMING;this.mouseModeSelector_.settingsKey='timelineTrackView.mouseModeSelector';this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN,'2'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION,'1'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM,'3'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.TIMING,'4'.charCodeAt(0));this.mouseModeSelector_.setModifierForAlternateMode(m.SELECTION,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(m.PANSCAN,tr.ui.b.MODIFIER.SPACE);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController_){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}},set timelineView(view){this.timelineView_=view;},onSelectionChanged_:function(){this.showHintText_('Press \'m\' to mark current selection');this.viewport_.dispatchChangeEvent();},set selection(selection){throw new Error('DO NOT CALL THIS');},set highlight(highlight){throw new Error('DO NOT CALL THIS');},detach:function(){this.modelTrack_.detach();this.upperModelTrack_.detach();this.viewport_.detach();},get viewport(){return this.viewport_;},get model(){return this.model_;},set model(model){if(!model)
+throw new Error('Model cannot be undefined');var modelInstanceChanged=this.model_!==model;this.model_=model;this.modelTrack_.model=model;this.upperModelTrack_.model=model;if(modelInstanceChanged)
+this.viewport_.setWhenPossible(this.setInitialViewport_.bind(this));},get hasVisibleContent(){return this.modelTrack_.hasVisibleContent||this.upperModelTrack_.hasVisibleContent;},setInitialViewport_:function(){this.modelTrackContainer_.updateCanvasSizeIfNeeded_();var w=this.modelTrackContainer_.canvas.width;var min;var range;if(this.model_.bounds.isEmpty){min=0;range=1000;}else if(this.model_.bounds.range===0){min=this.model_.bounds.min;range=1000;}else{min=this.model_.bounds.min;range=this.model_.bounds.range;}
+var boost=range*0.15;this.displayTransform_.set(this.viewport_.currentDisplayTransform);this.displayTransform_.xSetWorldBounds(min-boost,min+range+boost,w);this.viewport_.setDisplayTransformImmediately(this.displayTransform_);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var modelTrack=this.modelTrack_;var firstT=modelTrack.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);var lastT=firstT.after(function(){this.upperModelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);},this);return firstT;},onMouseMove_:function(e){if(this.isZooming_)
+return;this.storeLastMousePos_(e);},onTouchStart_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},onTouchMove_:function(e){e.preventDefault();this.onUpdateTransformForTouch_(e);},onTouchEnd_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},addHotKeys_:function(){this.addKeyDownHotKeys_();this.addKeyPressHotKeys_();},addKeyPressHotKeys_:function(){var addBinding=function(dict){dict.eventType='keypress';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCodes:['w'.charCodeAt(0),','.charCodeAt(0)],callback:function(e){this.zoomBy_(1.5,true);e.stopPropagation();}});addBinding({keyCodes:['s'.charCodeAt(0),'o'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/1.5,true);e.stopPropagation();}});addBinding({keyCode:'g'.charCodeAt(0),callback:function(e){this.onGridToggle_(true);e.stopPropagation();}});addBinding({keyCode:'G'.charCodeAt(0),callback:function(e){this.onGridToggle_(false);e.stopPropagation();}});addBinding({keyCodes:['W'.charCodeAt(0),'<'.charCodeAt(0)],callback:function(e){this.zoomBy_(10,true);e.stopPropagation();}});addBinding({keyCodes:['S'.charCodeAt(0),'O'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/10,true);e.stopPropagation();}});addBinding({keyCode:'a'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(this.viewWidth_*0.3,0);e.stopPropagation();}});addBinding({keyCodes:['d'.charCodeAt(0),'e'.charCodeAt(0)],callback:function(e){this.queueSmoothPan_(this.viewWidth_*-0.3,0);e.stopPropagation();}});addBinding({keyCode:'A'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*0.5,0);e.stopPropagation();}});addBinding({keyCode:'D'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*-0.5,0);e.stopPropagation();}});addBinding({keyCode:'0'.charCodeAt(0),callback:function(e){this.setInitialViewport_();e.stopPropagation();}});addBinding({keyCode:'f'.charCodeAt(0),callback:function(e){this.zoomToSelection();e.stopPropagation();}});addBinding({keyCode:'m'.charCodeAt(0),callback:function(e){this.setCurrentSelectionAsInterestRange_();e.stopPropagation();}});addBinding({keyCode:'h'.charCodeAt(0),callback:function(e){this.toggleHighDetails_();e.stopPropagation();}});},get viewWidth_(){return this.modelTrackContainer_.canvas.clientWidth;},addKeyDownHotKeys_:function(){var addBinding=function(dict){dict.eventType='keydown';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCode:37,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,-1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});addBinding({keyCode:39,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(-this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});},onDblClick_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
+return;var curSelection=this.brushingStateController_.selection;if(!curSelection.length||!curSelection[0].title)
+return;var selection=new tr.model.EventSet();var filter=new tr.c.ExactTitleFilter(curSelection[0].title);this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);this.brushingStateController.changeSelectionFromTimeline(selection);},onMouseWheel_:function(e){if(!e.altKey)
+return;var delta=e.wheelDelta/120;var zoomScale=Math.pow(1.5,delta);this.zoomBy_(zoomScale);e.preventDefault();},onMouseDown_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
+return;if(e.target!==this.rulerTrack_)
+return;this.dragBeginEvent_=undefined;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
+var dt=this.viewport_.currentDisplayTransform;tr.ui.b.trackMouseMovesUntilMouseUp(function(e){if(e.target===this.rulerTrack_)
+return;var relativePosition=this.extractRelativeMousePosition_(e);var loc=tr.model.Location.fromViewCoordinates(this.viewport_,relativePosition.x,relativePosition.y);if(!loc)
+return;if(this.guideLineAnnotation_===undefined){this.guideLineAnnotation_=new tr.model.XMarkerAnnotation(loc.xWorld);this.model.addAnnotation(this.guideLineAnnotation_);}else{this.guideLineAnnotation_.timestamp=loc.xWorld;this.modelTrackContainer_.invalidate();}
+var state=new tr.ui.b.UIState(loc,this.viewport_.currentDisplayTransform.scaleX);this.timelineView_.setFindCtlText(state.toUserFriendlyString(this.viewport_));}.bind(this),undefined,function onKeyUpDuringDrag(){if(this.dragBeginEvent_){this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);}}.bind(this));},queueSmoothPan_:function(viewDeltaX,deltaY){var deltaX=this.viewport_.currentDisplayTransform.xViewVectorToWorld(viewDeltaX);var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,deltaY);this.viewport_.queueDisplayTransformAnimation(animation);},zoomBy_:function(scale,smooth){if(scale<=0){return;}
+smooth=!!smooth;var vp=this.viewport_;var pixelRatio=window.devicePixelRatio||1;var goalFocalPointXView=this.lastMouseViewPos_.x*pixelRatio;var goalFocalPointXWorld=vp.currentDisplayTransform.xViewToWorld(goalFocalPointXView);if(smooth){var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,vp.currentDisplayTransform.panY,scale);vp.queueDisplayTransformAnimation(animation);}else{this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=scale;this.displayTransform_.xPanWorldPosToViewPos(goalFocalPointXWorld,goalFocalPointXView,this.viewWidth_);vp.setDisplayTransformImmediately(this.displayTransform_);}},zoomToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
+return;var bounds=this.brushingStateController.selectionOfInterest.bounds;if(!bounds.range)
+return;var worldCenter=bounds.center;var viewCenter=this.modelTrackContainer_.canvas.width/2;var adjustedWorldRange=bounds.range*1.25;var newScale=this.modelTrackContainer_.canvas.width/adjustedWorldRange;var zoomInRatio=newScale/this.viewport_.currentDisplayTransform.scaleX;var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);},panToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
+return;var bounds=this.brushingStateController.selectionOfInterest.bounds;var worldCenter=bounds.center;var viewWidth=this.viewWidth_;var dt=this.viewport_.currentDisplayTransform;if(false&&!bounds.range){if(dt.xWorldToView(bounds.center)<0||dt.xWorldToView(bounds.center)>viewWidth){this.displayTransform_.set(dt);this.displayTransform_.xPanWorldPosToViewPos(worldCenter,'center',viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);}
+return;}
+this.displayTransform_.set(dt);this.displayTransform_.xPanWorldBoundsIntoView(bounds.min,bounds.max,viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);},navToPosition:function(uiState,showNavLine){var location=uiState.location;var scaleX=uiState.scaleX;var track=location.getContainingTrack(this.viewport_);var worldCenter=location.xWorld;var viewCenter=this.modelTrackContainer_.canvas.width/5;var zoomInRatio=scaleX/this.viewport_.currentDisplayTransform.scaleX;track.scrollIntoViewIfNeeded();var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);if(!showNavLine)
+return;if(this.xNavStringMarker_)
+this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=new tr.model.XMarkerAnnotation(worldCenter);this.model.addAnnotation(this.xNavStringMarker_);},setCurrentSelectionAsInterestRange_:function(){var selectionBounds=this.brushingStateController_.selection.bounds;if(selectionBounds.empty){this.viewport_.interestRange.reset();return;}
+if(this.viewport_.interestRange.min==selectionBounds.min&&this.viewport_.interestRange.max==selectionBounds.max)
+this.viewport_.interestRange.reset();else
+this.viewport_.interestRange.set(selectionBounds);},toggleHighDetails_:function(){this.viewport_.highDetails=!this.viewport_.highDetails;},hideDragBox_:function(){this.$.drag_box.style.left='-1000px';this.$.drag_box.style.top='-1000px';this.$.drag_box.style.width=0;this.$.drag_box.style.height=0;},setDragBoxPosition_:function(xStart,yStart,xEnd,yEnd){var loY=Math.min(yStart,yEnd);var hiY=Math.max(yStart,yEnd);var loX=Math.min(xStart,xEnd);var hiX=Math.max(xStart,xEnd);var modelTrackRect=this.modelTrack_.getBoundingClientRect();var dragRect={left:loX,top:loY,width:hiX-loX,height:hiY-loY};dragRect.right=dragRect.left+dragRect.width;dragRect.bottom=dragRect.top+dragRect.height;var modelTrackContainerRect=this.modelTrackContainer_.getBoundingClientRect();var clipRect={left:modelTrackContainerRect.left,top:modelTrackContainerRect.top,right:modelTrackContainerRect.right,bottom:modelTrackContainerRect.bottom};var headingWidth=window.getComputedStyle(this.querySelector('tr-ui-heading')).width;var trackTitleWidth=parseInt(headingWidth);clipRect.left=clipRect.left+trackTitleWidth;var intersectRect_=function(r1,r2){if(r2.left>r1.right||r2.right<r1.left||r2.top>r1.bottom||r2.bottom<r1.top)
+return false;var results={};results.left=Math.max(r1.left,r2.left);results.top=Math.max(r1.top,r2.top);results.right=Math.min(r1.right,r2.right);results.bottom=Math.min(r1.bottom,r2.bottom);results.width=results.right-results.left;results.height=results.bottom-results.top;return results;};var finalDragBox=intersectRect_(clipRect,dragRect);this.$.drag_box.style.left=finalDragBox.left+'px';this.$.drag_box.style.width=finalDragBox.width+'px';this.$.drag_box.style.top=finalDragBox.top+'px';this.$.drag_box.style.height=finalDragBox.height+'px';this.$.drag_box.style.whiteSpace='nowrap';var pixelRatio=window.devicePixelRatio||1;var canv=this.modelTrackContainer_.canvas;var dt=this.viewport_.currentDisplayTransform;var loWX=dt.xViewToWorld((loX-canv.offsetLeft)*pixelRatio);var hiWX=dt.xViewToWorld((hiX-canv.offsetLeft)*pixelRatio);this.$.drag_box.textContent=tr.v.Unit.byName.timeDurationInMs.format(hiWX-loWX);var e=new tr.b.Event('selectionChanging');e.loWX=loWX;e.hiWX=hiWX;this.dispatchEvent(e);},onGridToggle_:function(left){var selection=this.brushingStateController_.selection;var tb=left?selection.bounds.min:selection.bounds.max;if(this.viewport_.gridEnabled&&this.viewport_.gridSide===left&&this.viewport_.gridInitialTimebase===tb){this.viewport_.gridside=undefined;this.viewport_.gridEnabled=false;this.viewport_.gridInitialTimebase=undefined;return;}
+var numIntervalsSinceStart=Math.ceil((tb-this.model_.bounds.min)/this.viewport_.gridStep_);this.viewport_.gridEnabled=true;this.viewport_.gridSide=left;this.viewport_.gridInitialTimebase=tb;this.viewport_.gridTimebase=tb-
+(numIntervalsSinceStart+1)*this.viewport_.gridStep_;},storeLastMousePos_:function(e){this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);},storeLastTouchPositions_:function(e){this.lastTouchViewPositions_=this.extractRelativeTouchPositions_(e);},extractRelativeMousePosition_:function(e){var canv=this.modelTrackContainer_.canvas;return{x:e.clientX-canv.offsetLeft,y:e.clientY-canv.offsetTop};},extractRelativeTouchPositions_:function(e){var canv=this.modelTrackContainer_.canvas;var touches=[];for(var i=0;i<e.touches.length;++i){touches.push({x:e.touches[i].clientX-canv.offsetLeft,y:e.touches[i].clientY-canv.offsetTop});}
+return touches;},storeInitialMouseDownPos_:function(e){var position=this.extractRelativeMousePosition_(e);this.mouseViewPosAtMouseDown_.x=position.x;this.mouseViewPosAtMouseDown_.y=position.y;},focusElements_:function(){this.$.hotkey_controller.childRequestsGeneralFocus(this);},storeInitialInteractionPositionsAndFocus_:function(e){this.storeInitialMouseDownPos_(e);this.storeLastMousePos_(e);this.focusElements_();},onBeginPanScan_:function(e){var vp=this.viewport_;this.viewportDisplayTransformAtMouseDown_=vp.currentDisplayTransform.clone();this.isPanningAndScanning_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdatePanScan_:function(e){if(!this.isPanningAndScanning_)
+return;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDeltaView=pixelRatio*(this.lastMouseViewPos_.x-
+this.mouseViewPosAtMouseDown_.x);var yDelta=this.lastMouseViewPos_.y-
+this.mouseViewPosAtMouseDown_.y;this.displayTransform_.set(this.viewportDisplayTransformAtMouseDown_);this.displayTransform_.incrementPanXInViewUnits(xDeltaView);this.displayTransform_.panY-=yDelta;this.viewport_.setDisplayTransformImmediately(this.displayTransform_);e.preventDefault();e.stopPropagation();this.storeLastMousePos_(e);},onEndPanScan_:function(e){this.isPanningAndScanning_=false;this.storeLastMousePos_(e);if(!e.isClick)
+e.preventDefault();},onBeginSelection_:function(e){var canv=this.modelTrackContainer_.canvas;var rect=this.modelTrack_.getBoundingClientRect();var canvRect=canv.getBoundingClientRect();var inside=rect&&e.clientX>=rect.left&&e.clientX<rect.right&&e.clientY>=rect.top&&e.clientY<rect.bottom&&e.clientX>=canvRect.left&&e.clientX<canvRect.right;if(!inside)
+return;this.dragBeginEvent_=e;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateSelection_:function(e){if(!this.dragBeginEvent_)
+return;this.dragBoxXStart_=this.dragBeginEvent_.clientX;this.dragBoxXEnd_=e.clientX;this.dragBoxYStart_=this.dragBeginEvent_.clientY;this.dragBoxYEnd_=e.clientY;this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);},onEndSelection_:function(e){e.preventDefault();if(!this.dragBeginEvent_)
+return;this.hideDragBox_();var eDown=this.dragBeginEvent_;this.dragBeginEvent_=undefined;var loY=Math.min(eDown.clientY,e.clientY);var hiY=Math.max(eDown.clientY,e.clientY);var loX=Math.min(eDown.clientX,e.clientX);var hiX=Math.max(eDown.clientX,e.clientX);var canv=this.modelTrackContainer_.canvas;var worldOffset=canv.getBoundingClientRect().left;var loVX=loX-worldOffset;var hiVX=hiX-worldOffset;var selection=new tr.model.EventSet();if(eDown.appendSelection){var previousSelection=this.brushingStateController_.selection;if(previousSelection!==undefined)
+selection.addEventSet(previousSelection);}
+this.modelTrack_.addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);this.brushingStateController_.changeSelectionFromTimeline(selection);},onBeginZoom_:function(e){this.isZooming_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
+return;var newPosition=this.extractRelativeMousePosition_(e);var zoomScaleValue=1+(this.lastMouseViewPos_.y-
+newPosition.y)*0.01;this.zoomBy_(zoomScaleValue,false);this.storeLastMousePos_(e);},onEndZoom_:function(e){this.isZooming_=false;if(!e.isClick)
+e.preventDefault();},computeTouchCenter_:function(positions){var xSum=0;var ySum=0;for(var i=0;i<positions.length;++i){xSum+=positions[i].x;ySum+=positions[i].y;}
+return{x:xSum/positions.length,y:ySum/positions.length};},computeTouchSpan_:function(positions){var xMin=Number.MAX_VALUE;var yMin=Number.MAX_VALUE;var xMax=Number.MIN_VALUE;var yMax=Number.MIN_VALUE;for(var i=0;i<positions.length;++i){xMin=Math.min(xMin,positions[i].x);yMin=Math.min(yMin,positions[i].y);xMax=Math.max(xMax,positions[i].x);yMax=Math.max(yMax,positions[i].y);}
+return Math.sqrt((xMin-xMax)*(xMin-xMax)+
+(yMin-yMax)*(yMin-yMax));},onUpdateTransformForTouch_:function(e){var newPositions=this.extractRelativeTouchPositions_(e);var currentPositions=this.lastTouchViewPositions_;var newCenter=this.computeTouchCenter_(newPositions);var currentCenter=this.computeTouchCenter_(currentPositions);var newSpan=this.computeTouchSpan_(newPositions);var currentSpan=this.computeTouchSpan_(currentPositions);var vp=this.viewport_;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDelta=pixelRatio*(newCenter.x-currentCenter.x);var yDelta=newCenter.y-currentCenter.y;var zoomScaleValue=currentSpan>10?newSpan/currentSpan:1;var viewFocus=pixelRatio*newCenter.x;var worldFocus=vp.currentDisplayTransform.xViewToWorld(viewFocus);this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=zoomScaleValue;this.displayTransform_.xPanWorldPosToViewPos(worldFocus,viewFocus,viewWidth);this.displayTransform_.incrementPanXInViewUnits(xDelta);this.displayTransform_.panY-=yDelta;vp.setDisplayTransformImmediately(this.displayTransform_);this.storeLastTouchPositions_(e);},initHintText_:function(){this.$.hint_text.style.display='none';this.pendingHintTextClearTimeout_=undefined;},showHintText_:function(text){if(this.pendingHintTextClearTimeout_){window.clearTimeout(this.pendingHintTextClearTimeout_);this.pendingHintTextClearTimeout_=undefined;}
+this.pendingHintTextClearTimeout_=setTimeout(this.hideHintText_.bind(this),1000);this.$.hint_text.textContent=text;this.$.hint_text.style.display='';},hideHintText_:function(){this.pendingHintTextClearTimeout_=undefined;this.$.hint_text.style.display='none';}});'use strict';Polymer('tr-ui-find-control',{filterKeyDown:function(e){if(e.keyCode===27){var hkc=tr.b.getHotkeyControllerForElement(this);if(hkc){hkc.childRequestsBlur(this);}else{this.blur();}
+e.preventDefault();e.stopPropagation();return;}else if(e.keyCode===13){if(e.shiftKey)
+this.findPrevious();else
+this.findNext();}},filterBlur:function(e){this.updateHitCountEl();},filterFocus:function(e){this.$.filter.select();},filterMouseUp:function(e){e.preventDefault();},get controller(){return this.controller_;},set controller(c){this.controller_=c;this.updateHitCountEl();},focus:function(){this.$.filter.focus();},get hasFocus(){return this===document.activeElement;},filterTextChanged:function(){this.$.hitCount.textContent='';this.$.spinner.style.visibility='visible';this.controller.startFiltering(this.$.filter.value).then(function(){this.$.spinner.style.visibility='hidden';this.updateHitCountEl();}.bind(this));},findNext:function(){if(this.controller)
+this.controller.findNext();this.updateHitCountEl();},findPrevious:function(){if(this.controller)
+this.controller.findPrevious();this.updateHitCountEl();},updateHitCountEl:function(){if(!this.controller||!this.hasFocus){this.$.hitCount.textContent='';return;}
+var n=this.controller.filterHits.length;var i=n===0?-1:this.controller.currentHitIndex;this.$.hitCount.textContent=(i+1)+' of '+n;},setText:function(string){this.$.filter.value=string;}});'use strict';tr.exportTo('tr.e.tquery',function(){function Context(){this.event=undefined;this.ancestors=[];}
+Context.prototype={push:function(event){var ctx=new Context();ctx.ancestors=this.ancestors.slice();ctx.ancestors.push(event);return ctx;},pop:function(event){var ctx=new Context();ctx.event=this.ancestors[this.ancestors.length-1];ctx.ancestors=this.ancestors.slice(0,this.ancestors.length-1);return ctx;}};return{Context:Context};});'use strict';tr.exportTo('tr.e.tquery',function(){function Filter(){tr.c.ScriptingObject.call(this);}
+Filter.normalizeFilterExpression=function(filterExpression){if(filterExpression instanceof String||typeof(filterExpression)=='string'||filterExpression instanceof RegExp){var filter=new tr.e.tquery.FilterHasTitle(filterExpression);return filter;}
+return filterExpression;};Filter.prototype={__proto__:tr.c.ScriptingObject.prototype,evaluate:function(context){throw new Error('Not implemented');},matchValue_:function(value,expected){if(expected instanceof RegExp)
+return expected.test(value);else if(expected instanceof Function)
+return expected(value);return value===expected;}};return{Filter:Filter};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAllOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
+FilterAllOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
+return true;for(var i=0;i<this.subExpressions.length;i++){if(!this.subExpressions[i].evaluate(context))
+return false;}
+return true;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=[];for(var i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
+return new FilterAllOf(exprs);},{name:'allOf'});return{FilterAllOf:FilterAllOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterNot(subExpression){tr.e.tquery.Filter.call(this);this.subExpression=subExpression;}
+FilterNot.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){return!this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);if(exprs.length!==1)
+throw new Error('not() must have exactly one subexpression');return new FilterNot(exprs[0]);},{name:'not'});return{FilterNot:FilterNot};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAnyOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];};FilterAnyOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
+return true;for(var i=0;i<this.subExpressions.length;i++){if(this.subExpressions[i].evaluate(context))
+return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);return new FilterAnyOf(exprs);},{name:'anyOf'});tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);return new tr.e.tquery.FilterNot(new FilterAnyOf(exprs));},{name:'noneOf'});return{FilterAnyOf:FilterAnyOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasAncestor(opt_subExpression){this.subExpression=opt_subExpression;};FilterHasAncestor.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(!this.subExpression)
+return context.ancestors.length>0;while(context.ancestors.length){context=context.pop();if(this.subExpression.evaluate(context))
+return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterHasAncestor(subExpression);},{name:'hasAncestor'});return{FilterHasAncestor:FilterHasAncestor};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasDuration(minValueOrExpected,opt_maxValue){if(minValueOrExpected!==undefined&&opt_maxValue!==undefined){this.minValue=minValueOrExpected;this.maxValue=opt_maxValue;}else{this.expected=minValueOrExpected;}};FilterHasDuration.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){if(context.event.duration===undefined)
+return false;if(this.minValue!==undefined&&this.maxValue!==undefined){return context.event.duration>=this.minValue&&context.event.duration<=this.maxValue;}
+return this.matchValue_(context.event.duration,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(minValueOrExpected,opt_maxValue){return new FilterHasDuration(minValueOrExpected,opt_maxValue);},{name:'hasDuration'});return{FilterHasDuration:FilterHasDuration};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasTitle(expected){tr.e.tquery.Filter.call(this);this.expected=expected;}
+FilterHasTitle.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){return this.matchValue_(context.event.title,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(expected){var filter=new tr.e.tquery.FilterHasTitle(expected);return filter;},{name:'hasTitle'});return{FilterHasTitle:FilterHasTitle};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterIsTopLevel(opt_subExpression){this.subExpression=opt_subExpression;}
+FilterIsTopLevel.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(context.ancestors.length>0)
+return false;if(!this.subExpression)
+return true;return this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterIsTopLevel(subExpression);},{name:'isTopLevel'});return{FilterIsTopLevel:FilterIsTopLevel};});'use strict';tr.exportTo('tr.e.tquery',function(){function addEventTreeToSelection(selection,event){selection.push(event);if(!event.subSlices)
+return;event.subSlices.forEach(addEventTreeToSelection.bind(undefined,selection));}
+function TQuery(model){tr.c.ScriptingObject.call(this);this.model_=model;this.parent_=undefined;this.filterExpression_=undefined;this.selection_=undefined;};TQuery.prototype={__proto__:tr.c.ScriptingObject.prototype,onModelChanged:function(model){this.model_=model;this.selection_=undefined;},get brushingStateController(){return this.brushingStateController_;},filter:function(filterExpression){var result=new TQuery(this.model_);result.parent_=this;result.filterExpression_=tr.e.tquery.Filter.normalizeFilterExpression(filterExpression);return result;},createFilterTaskGraph_:function(){var nodes=[];var node=this;while(node!==undefined){nodes.push(node);node=node.parent_;}
+var rootTask=new tr.b.Task();var lastTask=rootTask;for(var i=nodes.length-1;i>=0;i--){var node=nodes[i];if(node.selection_!==undefined)
+continue;node.selection_=new tr.model.EventSet();if(node.parent_===undefined){lastTask=lastTask.after(this.selectEverythingAsTask_(node.selection_));}else{var prevNode=nodes[i+1];lastTask=this.createFilterTaskForNode_(lastTask,node,prevNode);}}
+return{rootTask:rootTask,lastTask:lastTask,lastNode:node};},createFilterTaskForNode_:function(lastTask,node,prevNode){return lastTask.after(function(){node.evaluateFilterExpression_(prevNode.selection_,node.selection_);},this);},evaluateFilterExpression_:function(inputSelection,outputSelection){var seenEvents={};inputSelection.forEach(function(event){var context=new tr.e.tquery.Context();context.event=event;this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}.bind(this));},evaluateFilterExpressionForEvent_:function(context,inputSelection,outputSelection,seenEvents){var event=context.event;if(inputSelection.contains(event)&&!seenEvents[event.guid]){seenEvents[event.guid]=true;if(!this.filterExpression_||this.filterExpression_.evaluate(context))
+outputSelection.push(event);}
+if(!event.subSlices)
+return;context=context.push(event);for(var i=0;i<event.subSlices.length;i++){context.event=event.subSlices[i];this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}},selectEverythingAsTask_:function(selection){var filterTask=new tr.b.Task();this.model_.iterateAllEventContainers(function(container){filterTask.subTask(function(){container.iterateAllEventsInThisContainer(function(){return true;},addEventTreeToSelection.bind(undefined,selection));},this);},this);return filterTask;},ready:function(){return new Promise(function(resolve,reject){var graph=this.createFilterTaskGraph_();graph.lastTask=graph.lastTask.after(function(){resolve(this.selection_);},this);tr.b.Task.RunWhenIdle(graph.rootTask);}.bind(this));},get selection(){if(this.selection_===undefined){var graph=this.createFilterTaskGraph_();tr.b.Task.RunSynchronously(graph.rootTask);}
+return this.selection_;}};tr.c.ScriptingObjectRegistry.register(new TQuery(),{name:'$t'});return{TQuery:TQuery};});'use strict';Polymer('tr-ui-scripting-control',{_isEnterKey:function(event){return event.keyCode!==229&&event.keyIdentifier==='Enter';},_setFocused:function(focused){var promptEl=this.$.prompt;if(focused){promptEl.focus();this.$.root.classList.add('focused');if(promptEl.innerText.length>0){var sel=window.getSelection();sel.collapse(promptEl.firstChild,promptEl.innerText.length);}}else{promptEl.blur();this.$.root.classList.remove('focused');var parent=promptEl.parentElement;var nextEl=promptEl.nextSibling;promptEl.remove();parent.insertBefore(promptEl,nextEl);}},onConsoleFocus:function(e){e.stopPropagation();this._setFocused(true);},onConsoleBlur:function(e){e.stopPropagation();this._setFocused(false);},promptKeyDown:function(e){e.stopPropagation();if(!this._isEnterKey(e))
+return;e.preventDefault();var promptEl=this.$.prompt;var command=promptEl.innerText;if(command.length===0)
+return;promptEl.innerText='';this.addLine_(String.fromCharCode(187)+' '+command);try{var result=this.controller_.executeCommand(command);}catch(e){result=e.stack||e.stackTrace;}
+if(result instanceof tr.e.tquery.TQuery){result.ready().then(function(selection){this.addLine_(selection.length+' matches');this.controller_.brushingStateController.showScriptControlSelection(selection);}.bind(this));}else{this.addLine_(result);}
+promptEl.scrollIntoView();},addLine_:function(line){var historyEl=this.$.history;if(historyEl.innerText.length!==0)
+historyEl.innerText+='\n';historyEl.innerText+=line;},promptKeyPress:function(e){e.stopPropagation();},toggleVisibility:function(){var root=this.$.root;if(!this.visible){root.classList.remove('hidden');this._setFocused(true);}else{root.classList.add('hidden');this._setFocused(false);}},get hasFocus(){return this===document.activeElement;},get visible(){var root=this.$.root;return!root.classList.contains('hidden');},get controller(){return this.controller_;},set controller(c){this.controller_=c;}});'use strict';Polymer('tr-ui-side-panel-container',{ready:function(){this.activePanelContainer_=this.$.active_panel_container;this.tabStrip_=this.$.tab_strip;this.rangeOfInterest_=new tr.b.Range();this.brushingStateController_=undefined;this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onModelChanged_=this.onModelChanged_.bind(this);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);this.brushingStateController_.removeEventListener('model-changed',this.onModelChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);this.brushingStateController_.addEventListener('model-changed',this.onModelChanged_);}},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(){if(this.activePanel)
+this.activePanel.selection=this.selection;},get model(){return this.brushingStateController_.model;},onModelChanged_:function(){this.activePanelType_=undefined;this.updateContents_();},get expanded(){this.hasAttribute('expanded');},get activePanel(){if(this.activePanelContainer_.children.length===0)
+return undefined;return this.activePanelContainer_.children[0];},get activePanelType(){return this.activePanelType_;},set activePanelType(panelType){if(this.model===undefined)
+throw new Error('Cannot activate panel without a model');var panel=undefined;if(panelType)
+panel=document.createElement(panelType);if(panel!==undefined&&!panel.supportsModel(this.model))
+throw new Error('Cannot activate panel: does not support this model');if(this.activePanelType){this.getLabelElementForPanelType_(this.activePanelType).removeAttribute('selected');}
+this.activePanelContainer_.textContent='';if(panelType===undefined){this.removeAttribute('expanded');this.activePanelType_=undefined;return;}
+this.getLabelElementForPanelType_(panelType).setAttribute('selected',true);this.setAttribute('expanded',true);this.activePanelContainer_.appendChild(panel);panel.rangeOfInterest=this.rangeOfInterest_;panel.selection=this.selection_;panel.model=this.model;this.activePanelType_=panelType;},getPanelTypeForConstructor_:function(constructor){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType.constructor==constructor)
+return this.tabStrip_.children[i].panelType;}},getLabelElementForPanelType_:function(panelType){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType==panelType)
+return this.tabStrip_.children[i];}
+return undefined;},updateContents_:function(){var previouslyActivePanelType=this.activePanelType;this.tabStrip_.textContent='';var supportedPanelTypes=[];var panelTypes=tr.ui.b.getPolymerElementsThatSubclass('tr-ui-side-panel');panelTypes.forEach(function(panelType){var labelEl=document.createElement('tab-strip-label');var panel=document.createElement(panelType);labelEl.textContent=panel.textLabel;labelEl.panelType=panelType;var supported=panel.supportsModel(this.model);if(this.model&&supported.supported){supportedPanelTypes.push(panelType);labelEl.setAttribute('enabled',true);labelEl.addEventListener('click',function(){this.activePanelType=this.activePanelType===panelType?undefined:panelType;}.bind(this));}else{labelEl.title='Not supported for the current trace: '+
+supported.reason;labelEl.style.display='none';}
+this.tabStrip_.appendChild(labelEl);},this);if(previouslyActivePanelType&&supportedPanelTypes.indexOf(previouslyActivePanelType)!=-1){this.activePanelType=previouslyActivePanelType;this.setAttribute('expanded',true);}else{this.activePanelContainer_.textContent='';this.removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range==undefined)
+throw new Error('Must not be undefined');this.rangeOfInterest_=range;if(this.activePanel)
+this.activePanel.rangeOfInterest=range;}});'use strict';Polymer('tr-ui-timeline-view-help-overlay',{ready:function(){var mod=tr.isMac?'cmd ':'ctrl';var spans=this.shadowRoot.querySelectorAll('span.mod');for(var i=0;i<spans.length;i++){spans[i].textContent=mod;}}});'use strict';tr.exportTo('tr.v',function(){function GenericTable(items){if(items!==undefined)
+this.items=items;else
+this.items=[];};GenericTable.prototype={};return{GenericTable:GenericTable};});'use strict';tr.exportTo('tr.v.ui',function(){var ArrayOfNumbersSummaryModes={AVERAGE_MODE:'average-mode',TOTAL_MODE:'total-mode'};return{ArrayOfNumbersSummaryModes:ArrayOfNumbersSummaryModes};});'use strict';Polymer('tr-v-ui-array-of-numbers-span',{created:function(){this.numbers_=undefined;this.summaryMode_=tr.v.ui.ArrayOfNumbersSummaryModes.AVERAGE_MODE;},get summaryMode(){return this.summaryMode_;},set summaryMode(summaryMode){this.summaryMode_=summaryMode;this.updateContents_();},get numbers(){return this.numbers_;},set numbers(numbers){if(numbers===undefined){this.numbers_=undefined;this.updateContents_();return;}
+if(!(numbers instanceof Array))
+throw new Error('Must provide an array');this.numbers_=numbers;this.updateContents_();},updateContents_:function(){if(this.numbers_===undefined){this.shadowRoot.textContent='-';return;}
+var ArrayOfNumbersSummaryModes=tr.v.ui.ArrayOfNumbersSummaryModes;var value;if(this.summaryMode_===ArrayOfNumbersSummaryModes.AVERAGE_MODE)
+value=tr.b.Statistics.mean(this.numbers_);else
+value=tr.b.Statistics.sum(this.numbers_);var valueRounded=Math.round(value*1000.0)/1000.0;this.shadowRoot.textContent=valueRounded;}});'use strict';tr.exportTo('tr.v.ui',function(){var TEXT_COLUMN_MODE=1;var NUMERIC_COLUMN_MODE=2;var ELEMENT_COLUMN_MODE=3;function isNumeric(value){if((typeof value)==='number')
+return true;else if(value instanceof Number)
+return true;return false;}
+function GenericTableViewTotalsItem(opt_values){if(opt_values!==undefined)
+this.values=opt_values;else
+this.values=[];}
+function GenericTableViewColumnDescriptor(fieldName,firstFieldValue){this.title=fieldName;this.fieldName=fieldName;this.updateModeGivenValue(firstFieldValue);}
+GenericTableViewColumnDescriptor.prototype={get columnMode(){return this.columnMode_;},get isInNumericMode(){return this.columnMode_===NUMERIC_COLUMN_MODE;},cmp:function(a,b){if(this.columnMode_===ELEMENT_COLUMN_MODE)
+return 0;return tr.b.comparePossiblyUndefinedValues(a,b,function(a,b){var vA=a[this.fieldName];var vB=b[this.fieldName];return tr.b.comparePossiblyUndefinedValues(vA,vB,function(vA,vB){if(vA.localeCompare)
+return vA.localeCompare(vB);return vA-vB;},this);},this);},updateModeGivenValue:function(fieldValue){if(this.columnMode_===undefined){if(fieldValue===undefined||fieldValue===null)
+return;if(isNumeric(fieldValue)){this.columnMode_=NUMERIC_COLUMN_MODE;return;}
+if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
+this.columnMode_=TEXT_COLUMN_MODE;return;}
+if(fieldValue===undefined||fieldValue===null)
+return;if(isNumeric(fieldValue))
+return;if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
+if(this.columnMode_===NUMERIC_COLUMN_MODE)
+this.columnMode_=TEXT_COLUMN_MODE;},value:function(item){var fieldValue=item[this.fieldName];if(fieldValue instanceof GenericTableViewTotalsItem){var span=document.createElement('tr-v-ui-array-of-numbers-span');span.summaryMode=tr.v.ui.ArrayOfNumbersSummaryModes.TOTAL_MODE;span.numbers=fieldValue.values;return span;}
+if(fieldValue===undefined)
+return'-';if(fieldValue instanceof HTMLElement)
+return fieldValue;if(fieldValue instanceof Object){var gov=document.createElement('tr-ui-a-generic-object-view');gov.object=fieldValue;return gov;}
+return fieldValue;}};Polymer('tr-v-ui-generic-table-view',{created:function(){this.items_=undefined;this.importantColumNames_=[];},get items(){return this.items_;},set items(itemsOrGenericTable){if(itemsOrGenericTable===undefined){this.items_=undefined;}else if(itemsOrGenericTable instanceof Array){this.items_=itemsOrGenericTable;}else if(itemsOrGenericTable instanceof tr.v.GenericTable){this.items_=itemsOrGenericTable.items;}
+this.updateContents_();},get importantColumNames(){return this.importantColumNames_;},set importantColumNames(importantColumNames){this.importantColumNames_=importantColumNames;this.updateContents_();},createColumns_:function(){var columnsByName={};this.items_.forEach(function(item){tr.b.iterItems(item,function(itemFieldName,itemFieldValue){var colDesc=columnsByName[itemFieldName];if(colDesc!==undefined){colDesc.updateModeGivenValue(itemFieldValue);return;}
+colDesc=new GenericTableViewColumnDescriptor(itemFieldName,itemFieldValue);columnsByName[itemFieldName]=colDesc;},this);},this);var columns=tr.b.dictionaryValues(columnsByName);if(columns.length===0)
+return undefined;var isColumnNameImportant={};var importantColumNames=this.importantColumNames||[];importantColumNames.forEach(function(icn){isColumnNameImportant[icn]=true;});columns.sort(function(a,b){var iA=isColumnNameImportant[a.title]?1:0;var iB=isColumnNameImportant[b.title]?1:0;if((iB-iA)!==0)
+return iB-iA;return a.title.localeCompare(b.title);});var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';columns[0].width='250px';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;return columns;},createFooterRowsIfNeeded_:function(columns){var hasColumnThatIsNumeric=columns.some(function(column){return column.isInNumericMode;});if(!hasColumnThatIsNumeric)
+return[];var totalsItems={};columns.forEach(function(column){if(!column.isInNumericMode)
+return;var totalsItem=new GenericTableViewTotalsItem();this.items_.forEach(function(item){var fieldValue=item[column.fieldName];if(fieldValue===undefined||fieldValue===null)
+return;totalsItem.values.push(fieldValue);});totalsItems[column.fieldName]=totalsItem;},this);return[totalsItems];},updateContents_:function(){var columns;if(this.items_!==undefined)
+columns=this.createColumns_();if(!columns){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.footerRows=[];return;}
+this.$.table.tableColumns=columns;this.$.table.tableRows=this.items_;this.$.table.footerRows=this.createFooterRowsIfNeeded_(columns);this.$.table.rebuild();},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;}});return{GenericTableViewTotalsItem:GenericTableViewTotalsItem,GenericTableViewColumnDescriptor:GenericTableViewColumnDescriptor};});'use strict';Polymer('tr-ui-timeline-view-metadata-overlay',{created:function(){this.metadata_=undefined;},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.gtv.items=this.metadata_;}});'use strict';Polymer('tr-v-ui-preferred-display-unit',{ready:function(){this.preferredTimeDisplayMode_=undefined;},attached:function(){tr.v.Unit.didPreferredTimeDisplayUnitChange();},detached:function(){tr.v.Unit.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)
+return;this.preferredTimeDisplayMode_=v;tr.v.Unit.didPreferredTimeDisplayUnitChange();}});'use strict';Polymer('tr-ui-timeline-view',{ready:function(){this.tabIndex=0;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.metrics&&window.tr.metrics.sh&&window.tr.metrics.sh.SystemHealthMetric){this.railScoreSpan_=document.createElement('tr-metrics-ui-sh-system-health-span');this.rightControls.appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
+this.optionsDropdown_=this.$.view_options_dropdown;this.optionsDropdown_.iconElement.textContent='View Options';this.showFlowEvents_=false;this.optionsDropdown_.appendChild(tr.ui.b.createCheckBox(this,'showFlowEvents','tr.ui.TimelineView.showFlowEvents',false,'Flow events'));this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');this.optionsDropdown_.appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();this.collapsingControls.appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){var sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},domReady:function(){this.trackViewContainer_=this.querySelector('#track_view_container');},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},updateDocumentFavicon:function(){var hue;if(!this.model)
+hue='blue';else
+hue=this.model.faviconHue;var faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined)
+faviconData=tr.ui.b.FaviconsByHue['blue'];var link=document.head.querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';document.head.appendChild(link);}
+link.href=faviconData;},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;if(!this.trackView_)
+return;this.trackView_.viewport.showFlowEvents=showFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)
+return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_:function(){var helpButtonEl=this.$.view_help_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));dlg.visible=true;e.stopPropagation();}
+helpButtonEl.addEventListener('click',onClick.bind(this));},initConsoleButton_:function(){var toggleEl=this.$.view_console_button;function onClick(e){this.scriptingCtl_.toggleVisibility();e.stopPropagation();return false;}
+toggleEl.addEventListener('click',onClick.bind(this));},initMetadataButton_:function(){var showEl=this.$.view_metadata_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Metadata for trace';var metadataOverlay=document.createElement('tr-ui-timeline-view-metadata-overlay');metadataOverlay.metadata=this.model.metadata;dlg.appendChild(metadataOverlay);dlg.visible=true;e.stopPropagation();return false;}
+showEl.addEventListener('click',onClick.bind(this));this.updateMetadataButtonVisibility_();},updateMetadataButtonVisibility_:function(){var showEl=this.$.view_metadata_button;showEl.style.display=(this.model&&this.model.metadata.length)?'':'none';},get leftControls(){return this.leftControlsEl_;},get rightControls(){return this.rightControlsEl_;},get collapsingControls(){return this.collapsingControlsEl_;},get viewTitle(){return this.titleEl_.textContent.substring(this.titleEl_.textContent.length-2);},set viewTitle(text){if(text===undefined){this.titleEl_.textContent='';this.titleEl_.hidden=true;return;}
+this.titleEl_.hidden=false;this.titleEl_.textContent=text;},get model(){if(this.trackView_)
+return this.trackView_.model;return undefined;},set model(model){var modelInstanceChanged=model!=this.model;var modelValid=model&&!model.bounds.isEmpty;var importWarningsEl=this.shadowRoot.querySelector('#import-warnings');importWarningsEl.textContent='';if(modelInstanceChanged){if(this.railScoreSpan_)
+this.railScoreSpan_.model=undefined;this.trackViewContainer_.textContent='';if(this.trackView_){this.trackView_.viewport.removeEventListener('change',this.onViewportChanged_);this.trackView_.brushingStateController=undefined;this.trackView_.detach();this.trackView_=undefined;}
+this.brushingStateController_.modelWillChange();}
+if(modelValid&&!this.trackView_){this.trackView_=document.createElement('tr-ui-timeline-track-view');this.trackView_.timelineView=this;this.trackView.brushingStateController=this.brushingStateController_;this.trackViewContainer_.appendChild(this.trackView_);this.trackView_.viewport.addEventListener('change',this.onViewportChanged_);}
+if(modelValid){this.trackView_.model=model;this.trackView_.viewport.showFlowEvents=this.showFlowEvents;this.trackView_.viewport.highlightVSync=this.highlightVSync;if(this.railScoreSpan_)
+this.railScoreSpan_.model=model;this.$.display_unit.preferredTimeDisplayMode=model.intrinsicTimeUnit;}
+if(model){model.importWarningsThatShouldBeShownToUser.forEach(function(importWarning){importWarningsEl.addMessage('Import Warning: '+importWarning.type+': '+
+importWarning.message);},this);}
+if(modelInstanceChanged){this.updateMetadataButtonVisibility_();this.brushingStateController_.modelDidChange();this.onViewportChanged_();}},get brushingStateController(){return this.brushingStateController_;},get trackView(){return this.trackView_;},get settings(){if(!this.settings_)
+this.settings_=new tr.b.Settings();return this.settings_;},set focusElement(value){throw new Error('This is deprecated. Please set globalMode to true.');},bindKeyListeners_:function(){var hkc=this.hotkeyController;hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'`'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){this.scriptingCtl_.toggleVisibility();if(!this.scriptingCtl_.hasFocus)
+this.focus();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'/'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){if(this.scriptingCtl_.hasFocus)
+return;if(this.findCtl_.hasFocus)
+this.focus();else
+this.findCtl_.focus();e.preventDefault();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'?'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.$.view_help_button.click();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'v'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.toggleHighlightVSync_();e.stopPropagation();}}));},onViewportChanged_:function(e){var spc=this.sidePanelContainer_;if(!this.trackView_){spc.rangeOfInterest.reset();return;}
+var vr=this.trackView_.viewport.interestRange.asRangeObject();if(!spc.rangeOfInterest.equals(vr))
+spc.rangeOfInterest=vr;if(this.railScoreSpan_&&this.model)
+this.railScoreSpan_.model=this.model;},toggleHighlightVSync_:function(){this.highlightVSyncCheckbox_.checked=!this.highlightVSyncCheckbox_.checked;},setFindCtlText:function(string){this.findCtl_.setText(string);}});'use strict';tr.exportTo('tr.ui.e.highlighter',function(){var Highlighter=tr.ui.tracks.Highlighter;function VSyncHighlighter(viewport){Highlighter.call(this,viewport);this.times_=[];}
 VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR=new tr.b.Color(0,0,255);VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA=0.1;VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT=0.20;VSyncHighlighter.VSYNC_DENSITY_OPAQUE=0.10;VSyncHighlighter.VSYNC_DENSITY_RANGE=VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT-
 VSyncHighlighter.VSYNC_DENSITY_OPAQUE;VSyncHighlighter.generateStripes=function(times,minTime,maxTime){if(times.length===0)
 return[];var stripes=[];var lowIndex=tr.b.findLowIndexInSortedArray(times,function(time){return time;},minTime);var highIndex=lowIndex-1;while(times[highIndex+1]<=maxTime){highIndex++;}
@@ -7105,7 +7577,40 @@
 VSyncHighlighter.prototype={__proto__:Highlighter.prototype,processModel:function(model){this.times_=model.device.vSyncTimestamps;},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){if(!this.viewport_.highlightVSync){return;}
 var stripes=VSyncHighlighter.generateStripes(this.times_,viewLWorld,viewRWorld);if(stripes.length==0){return;}
 var stripeRange=stripes[stripes.length-1][1]-stripes[0][0];var stripeDensity=stripes.length/(dt.scaleX*stripeRange);var clampedStripeDensity=tr.b.clamp(stripeDensity,VSyncHighlighter.VSYNC_DENSITY_OPAQUE,VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT);var opacity=(VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT-clampedStripeDensity)/VSyncHighlighter.VSYNC_DENSITY_RANGE;if(opacity==0){return;}
-var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var c=VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR;ctx.fillStyle=c.toStringWithAlphaOverride(VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA*opacity);for(var i=0;i<stripes.length;i++){var xLeftView=dt.xWorldToView(stripes[i][0]);var xRightView=dt.xWorldToView(stripes[i][1]);ctx.fillRect(xLeftView,0,xRightView-xLeftView,height);}}};tr.ui.tracks.Highlighter.register(VSyncHighlighter);return{VSyncHighlighter:VSyncHighlighter};});
+var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var c=VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR;ctx.fillStyle=c.toStringWithAlphaOverride(VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA*opacity);for(var i=0;i<stripes.length;i++){var xLeftView=dt.xWorldToView(stripes[i][0]);var xRightView=dt.xWorldToView(stripes[i][1]);ctx.fillRect(xLeftView,0,xRightView-xLeftView,height);}}};tr.ui.tracks.Highlighter.register(VSyncHighlighter);return{VSyncHighlighter:VSyncHighlighter};});'use strict';tr.exportTo('tr.ui.b',function(){function Row(title,data,groupingKeyFuncs,rowStatsConstructor){this.title=title;this.data_=data;if(groupingKeyFuncs===undefined)
+groupingKeyFuncs=[];this.groupingKeyFuncs_=groupingKeyFuncs;this.rowStatsConstructor_=rowStatsConstructor;this.subRowsBuilt_=false;this.subRows_=undefined;this.rowStats_=undefined;}
+Row.prototype={getCurrentGroupingKeyFunc_:function(){if(this.groupingKeyFuncs_.length===0)
+return undefined;return this.groupingKeyFuncs_[0];},get data(){return this.data_;},get rowStats(){if(this.rowStats_===undefined){this.rowStats_=new this.rowStatsConstructor_(this);}
+return this.rowStats_;},rebuildSubRowsIfNeeded_:function(){if(this.subRowsBuilt_)
+return;this.subRowsBuilt_=true;var groupingKeyFunc=this.getCurrentGroupingKeyFunc_();if(groupingKeyFunc===undefined){this.subRows_=undefined;return;}
+var dataByKey={};var hasValues=false;this.data_.forEach(function(datum){var key=groupingKeyFunc(datum);hasValues=hasValues||(key!==undefined);if(dataByKey[key]===undefined)
+dataByKey[key]=[];dataByKey[key].push(datum);});if(!hasValues){this.subRows_=undefined;return;}
+this.subRows_=[];for(var key in dataByKey){var row=new Row(key,dataByKey[key],this.groupingKeyFuncs_.slice(1),this.rowStatsConstructor_);this.subRows_.push(row);}},get isExpanded(){return(this.subRows&&(this.subRows.length>0)&&(this.subRows.length<5));},get subRows(){this.rebuildSubRowsIfNeeded_();return this.subRows_;}};Polymer('tr-ui-b-grouping-table',{created:function(){this.dataToGroup_=undefined;this.groupBy_=undefined;this.rowStatsConstructor_=undefined;},get tableColumns(){return this.$.table.tableColumns;},set tableColumns(tableColumns){this.$.table.tableColumns=tableColumns;},get tableRows(){return this.$.table.tableRows;},get sortColumnIndex(){return this.$.table.sortColumnIndex;},set sortColumnIndex(sortColumnIndex){this.$.table.sortColumnIndex=sortColumnIndex;},get sortDescending(){return this.$.table.sortDescending;},set sortDescending(sortDescending){this.$.table.sortDescending=sortDescending;},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;},get selectedColumnIndex(){return this.$.table.selectedColumnIndex;},set selectedColumnIndex(selectedColumnIndex){this.$.table.selectedColumnIndex=selectedColumnIndex;},get selectedTableRow(){return this.$.table.selectedTableRow;},set selectedTableRow(selectedTableRow){this.$.table.selectedTableRow=selectedTableRow;},get groupBy(){return this.groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;this.updateContents_();},get dataToGroup(){return this.dataToGroup_;},set dataToGroup(dataToGroup){this.dataToGroup_=dataToGroup;this.updateContents_();},get rowStatsConstructor(){return this.rowStatsConstructor_;},set rowStatsConstructor(rowStatsConstructor){this.rowStatsConstructor_=rowStatsConstructor;this.updateContents_();},rebuild:function(){this.$.table.rebuild();},updateContents_:function(){var groupBy=this.groupBy_||[];var dataToGroup=this.dataToGroup_||[];var rowStatsConstructor=this.rowStatsConstructor_||function(){};var superRow=new Row('',dataToGroup,groupBy,rowStatsConstructor);this.$.table.tableRows=superRow.subRows||[];}});return{};});'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document._currentScript.ownerDocument;Polymer('tr-ui-b-grouping-table-groupby-picker',{created:function(){this.needsInit_=true;this.defaultGroupKeys_=undefined;this.possibleGroups_=[];this.settingsKey_=[];this.currentGroupKeys_=undefined;this.dragging_=false;},get defaultGroupKeys(){return this.defaultGroupKeys_;},set defaultGroupKeys(defaultGroupKeys){if(!this.needsInit_)
+throw new Error('Already initialized.');this.defaultGroupKeys_=defaultGroupKeys;this.maybeInit_();},get possibleGroups(){return this.possibleGroups_;},set possibleGroups(possibleGroups){if(!this.needsInit_)
+throw new Error('Already initialized.');this.possibleGroups_=possibleGroups;this.maybeInit_();},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){if(!this.needsInit_)
+throw new Error('Already initialized.');this.settingsKey_=settingsKey;this.maybeInit_();},maybeInit_:function(){if(!this.needsInit_)
+return;if(this.settingsKey_===undefined)
+return;if(this.defaultGroupKeys_===undefined)
+return;if(this.possibleGroups_===undefined)
+return;this.needsInit_=false;var addGroupEl=this.shadowRoot.querySelector('#add-group');addGroupEl.iconElement.textContent='Add another...';this.currentGroupKeys=tr.b.Settings.get(this.settingsKey_,this.defaultGroupKeys_);},get currentGroupKeys(){return this.currentGroupKeys_;},get currentGroups(){var groupsByKey={};this.possibleGroups_.forEach(function(group){groupsByKey[group.key]=group;});return this.currentGroupKeys_.map(function(groupKey){return groupsByKey[groupKey];});},set currentGroupKeys(currentGroupKeys){if(this.currentGroupKeys_===currentGroupKeys)
+return;if(!(currentGroupKeys instanceof Array))
+throw new Error('Must be array');this.currentGroupKeys_=currentGroupKeys;this.updateGroups_();tr.b.Settings.set(this.settingsKey_,this.currentGroupKeys_);var e=new tr.b.Event('current-groups-changed');this.dispatchEvent(e);},updateGroups_:function(){var groupsEl=this.shadowRoot.querySelector('groups');var addGroupEl=this.shadowRoot.querySelector('#add-group');groupsEl.textContent='';addGroupEl.textContent='';var unusedGroups={};var groupsByKey={};this.possibleGroups_.forEach(function(group){unusedGroups[group.key]=group;groupsByKey[group.key]=group;});this.currentGroupKeys_.forEach(function(key){delete unusedGroups[key];});var groupTemplateEl=THIS_DOC.querySelector('#tr-ui-b-grouping-table-groupby-picker-group-template');this.currentGroupKeys_.forEach(function(key,index){var group=groupsByKey[key];var groupEl=document.createElement('group');groupEl.groupKey=key;groupEl.appendChild(document.importNode(groupTemplateEl.content,true));groupEl.querySelector('#key').textContent=group.label;groupsEl.appendChild(groupEl);this.configureRemoveButtonForGroup_(groupEl);this.configureDragAndDropForGroup_(groupEl);},this);tr.b.iterItems(unusedGroups,function(key,group){var groupEl=document.createElement('possible-group');groupEl.textContent=group.label;groupEl.addEventListener('click',function(){var newKeys=this.currentGroupKeys.slice();newKeys.push(key);this.currentGroupKeys=newKeys;addGroupEl.close();}.bind(this));addGroupEl.appendChild(groupEl);},this);if(tr.b.dictionaryLength(unusedGroups)==0){addGroupEl.style.display='none';}else{addGroupEl.style.display='';}},configureRemoveButtonForGroup_:function(groupEl){var removeEl=groupEl.querySelector('#remove');removeEl.addEventListener('click',function(){var newKeys=this.currentGroupKeys.slice();var i=newKeys.indexOf(groupEl.groupKey);newKeys.splice(i,1);this.currentGroupKeys=newKeys;}.bind(this));groupEl.addEventListener('mouseenter',function(){removeEl.setAttribute('hovered',true);});groupEl.addEventListener('mouseleave',function(){removeEl.removeAttribute('hovered');});},configureDragAndDropForGroup_:function(groupEl){var groupsEl=groupEl.parentElement;groupEl.setAttribute('draggable',true);groupEl.addEventListener('dragstart',function(e){e.dataTransfer.setData('groupKey',groupEl.groupKey);groupEl.querySelector('#remove').removeAttribute('hovered');groupEl.classList.add('dragging');this.dragging_=true;}.bind(this));groupEl.addEventListener('dragend',function(e){console.log(e.type,groupEl.groupKey);for(var i=0;i<groupsEl.children.length;i++)
+groupsEl.children[i].classList.remove('drop-targeted');groupEl.classList.remove('dragging');this.dragging_=false;}.bind(this));groupEl.addEventListener('dragenter',function(e){if(!this.dragging_)
+return;groupEl.classList.add('drop-targeted');if(this.dragging_)
+e.preventDefault();}.bind(this));groupEl.addEventListener('dragleave',function(e){if(!this.dragging_)
+return;groupEl.classList.remove('drop-targeted');e.preventDefault();}.bind(this));groupEl.addEventListener('dragover',function(e){if(!this.dragging_)
+return;e.preventDefault();groupEl.classList.add('drop-targeted');}.bind(this));groupEl.addEventListener('drop',function(e){if(!this.dragging_)
+return;var srcKey=e.dataTransfer.getData('groupKey');var dstKey=groupEl.groupKey;if(srcKey===dstKey)
+return;var newKeys=this.currentGroupKeys_.slice();var srcIndex=this.currentGroupKeys_.indexOf(srcKey);newKeys.splice(srcIndex,1);var dstIndex=this.currentGroupKeys_.indexOf(dstKey);newKeys.splice(dstIndex,0,srcKey);this.currentGroupKeys=newKeys;e.dataTransfer.clearData();e.preventDefault();e.stopPropagation();}.bind(this));}});return{};});'use strict';(function(){Polymer('tr-ui-sp-file-size-stats-side-panel',{ready:function(){this.model_=undefined;this.selection_=new tr.model.EventSet();this.$.picker.settingsKey='tr-ui-sp-file-size-stats-side-panel-picker';this.$.picker.possibleGroups=[{key:'phase',label:'Event Type',dataFn:function(eventStat){return eventStat.phase;}},{key:'category',label:'Category',dataFn:function(eventStat){return eventStat.category;}},{key:'title',label:'Title',dataFn:function(eventStat){return eventStat.title;}}];this.$.picker.defaultGroupKeys=['phase','title'];this.$.picker.addEventListener('current-groups-changed',this.updateContents_.bind(this));},get textLabel(){return'File Size Stats';},supportsModel:function(m){if(!m){return{supported:false,reason:'No stats were collected for this file.'};}
+if(m.stats.allTraceEventStats.length===0){return{supported:false,reason:'No stats were collected for this file.'};}
+return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;},createColumns_:function(stats){var columns=[{title:'Title',value:function(row){var titleEl=document.createElement('span');titleEl.textContent=row.title;titleEl.style.textOverflow='ellipsis';return titleEl;},cmp:function(a,b){return a.title.localeCompare(b.title);},width:'400px'},{title:'Num Events',textAlign:'right',value:function(row){return row.rowStats.numEvents;},cmp:function(a,b){return a.rowStats.numEvents-b.rowStats.numEvents;},width:'80px'}];if(stats&&stats.hasEventSizesinBytes){columns.push({title:'Bytes',textAlign:'right',value:function(row){var value=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes,row.rowStats.totalEventSizeinBytes);var spanEl=tr.v.ui.createScalarSpan(value);return spanEl;},cmp:function(a,b){return a.rowStats.totalEventSizeinBytes-
+b.rowStats.totalEventSizeinBytes;},width:'80px'});}
+return columns;},updateContents_:function(){var table=this.$.table;var columns=this.createColumns_(this.model.stats);table.rowStatsConstructor=function ModelStatsRowStats(row){var sum=tr.b.Statistics.sum(row.data,function(x){return x.numEvents;});var totalEventSizeinBytes=tr.b.Statistics.sum(row.data,function(x){return x.totalEventSizeinBytes;});return{numEvents:sum,totalEventSizeinBytes:totalEventSizeinBytes};};table.tableColumns=columns;table.sortColumnIndex=1;table.sortDescending=true;table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.groupBy=this.$.picker.currentGroups.map(function(group){return group.dataFn;});if(!this.model){table.dataToGroup=[];}else{table.dataToGroup=this.model.stats.allTraceEventStats;}
+this.$.table.rebuild();}});})();'use strict';Polymer('tr-ui-e-s-alerts-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},set selection(selection){},set rangeOfInterest(rangeOfInterest){},selectAlertsOfType:function(alertTypeString){var alertsOfType=this.model_.alerts.filter(function(alert){return alert.title===alertTypeString;});var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(alertsOfType);this.dispatchEvent(event);},alertsByType_:function(alerts){var alertsByType={};alerts.forEach(function(alert){if(!alertsByType[alert.title])
+alertsByType[alert.title]=[];alertsByType[alert.title].push(alert);});return alertsByType;},alertsTableRows_:function(alertsByType){return Object.keys(alertsByType).map(function(key){return{alertType:key,count:alertsByType[key].length};});},alertsTableColumns_:function(){return[{title:'Alert type',value:function(row){return row.alertType;},width:'180px'},{title:'Count',width:'100%',value:function(row){return row.count;}}];},createAlertsTable_:function(alerts){var alertsByType=this.alertsByType_(alerts);var table=document.createElement('tr-ui-b-table');table.tableColumns=this.alertsTableColumns_();table.tableRows=this.alertsTableRows_(alertsByType);table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.addEventListener('selection-changed',function(e){var row=table.selectedTableRow;if(row)
+this.selectAlertsOfType(row.alertType);}.bind(this));return table;},updateContents_:function(){this.$.result_area.textContent='';if(this.model_===undefined)
+return;var panel=this.createAlertsTable_(this.model_.alerts);this.$.result_area.appendChild(panel);},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}else if(m.alerts.length===0){return{supported:false,reason:'No alerts in tracing model'};}
+return{supported:true};},get textLabel(){return'Alerts';}});
 </script>
 </head>
   <body>
diff --git a/runtime/observatory/web/timeline.js b/runtime/observatory/web/timeline.js
index 402723d..dea5542 100644
--- a/runtime/observatory/web/timeline.js
+++ b/runtime/observatory/web/timeline.js
@@ -2,6 +2,18 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// Used to delay the initial timeline load until the timeline has finished
+// loading.
+timeline_loaded = false;
+timeline_vm_address = undefined;
+timeline_isolates = undefined;
+
+function registerForMessages() {
+  window.addEventListener("message", onMessage, false);
+}
+
+registerForMessages();
+
 function onModelLoaded() {
   viewer.globalMode = true;
   viewer.model = model;
@@ -26,9 +38,7 @@
   p.then(onModelLoaded, onImportFail);
 }
 
-function registerForMessages() {
-  window.addEventListener("message", onMessage, false);
-}
+
 
 function fetchUri(uri, onLoad, onError) {
   var xhr = new XMLHttpRequest();
@@ -196,7 +206,13 @@
   var params = request['params'];
   switch (method) {
     case 'refresh':
-      fetchTimeline(params['vmAddress'], params['isolateIds']);
+      if (!timeline_loaded) {
+        timeline_vm_address = params['vmAddress'];
+        timeline_isolates = params['isolateIds'];
+        console.log('Delaying timeline refresh until loaded.');
+      } else {
+        fetchTimeline(params['vmAddress'], params['isolateIds']);
+      }
     break;
     case 'clear':
       clearTimeline();
@@ -221,7 +237,13 @@
   viewer.id = 'trace-viewer';
   viewer.globalMode = true;
   document.body.appendChild(viewer);
-  registerForMessages();
+  timeline_loaded = true;
+  if (timeline_vm_address != undefined) {
+    console.log('Triggering delayed timeline refresh.');
+    fetchTimeline(timeline_vm_address, timeline_isolates);
+    timeline_vm_address = undefined;
+    timeline_isolates = undefined;
+  }
 });
 
 console.log('loaded');
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index d1c6ef6..82f5719 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -102,6 +102,9 @@
 // the value defined in TargetConditionals.h
 #define TARGET_OS_MACOS 1
 #if TARGET_OS_IPHONE
+// Test for this #define by saying '#if TARGET_OS_IOS' rather than the usual
+// '#if defined(TARGET_OS_IOS)'. TARGET_OS_IOS is defined to be 0 in
+// XCode >= 7.0. See Issue #24453.
 #define TARGET_OS_IOS 1
 #endif
 
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index 1e72f79..c39f74c 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -1311,40 +1311,6 @@
 }
 
 
-// Use CHA to determine if the call needs a class check: if the callee's
-// receiver is the same as the caller's receiver and there are no overriden
-// callee functions, then no class check is needed.
-bool AotOptimizer::InstanceCallNeedsClassCheck(
-    InstanceCallInstr* call, RawFunction::Kind kind) const {
-  if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) {
-    // Even if class or function are private, lazy class finalization
-    // may later add overriding methods.
-    return true;
-  }
-  Definition* callee_receiver = call->ArgumentAt(0);
-  ASSERT(callee_receiver != NULL);
-  const Function& function = flow_graph_->function();
-  if (function.IsDynamicFunction() &&
-      callee_receiver->IsParameter() &&
-      (callee_receiver->AsParameter()->index() == 0)) {
-    const String& name = (kind == RawFunction::kMethodExtractor)
-        ? String::Handle(Z, Field::NameFromGetter(call->function_name()))
-        : call->function_name();
-    const Class& cls = Class::Handle(Z, function.Owner());
-    if (!thread()->cha()->HasOverride(cls, name)) {
-      if (FLAG_trace_cha) {
-        THR_Print("  **(CHA) Instance call needs no check, "
-            "no overrides of '%s' '%s'\n",
-            name.ToCString(), cls.ToCString());
-      }
-      thread()->cha()->AddToLeafClasses(cls);
-      return false;
-    }
-  }
-  return true;
-}
-
-
 bool AotOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
   ASSERT(call->HasICData());
   const ICData& ic_data = *call->ic_data();
@@ -1359,7 +1325,8 @@
       Field::ZoneHandle(Z, GetField(class_ids[0], field_name));
   ASSERT(!field.IsNull());
 
-  if (InstanceCallNeedsClassCheck(call, RawFunction::kImplicitGetter)) {
+  if (flow_graph()->InstanceCallNeedsClassCheck(
+          call, RawFunction::kImplicitGetter)) {
     return false;
   }
   LoadFieldInstr* load = new(Z) LoadFieldInstr(
@@ -2470,7 +2437,8 @@
   if (has_one_target) {
     RawFunction::Kind function_kind =
         Function::Handle(Z, unary_checks.GetTargetAt(0)).kind();
-    if (!InstanceCallNeedsClassCheck(instr, function_kind)) {
+    if (!flow_graph()->InstanceCallNeedsClassCheck(
+            instr, function_kind)) {
       PolymorphicInstanceCallInstr* call =
           new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
                                               /* with_checks = */ false);
@@ -2771,7 +2739,8 @@
       Field::ZoneHandle(Z, GetField(class_id, field_name));
   ASSERT(!field.IsNull());
 
-  if (InstanceCallNeedsClassCheck(instr, RawFunction::kImplicitSetter)) {
+  if (flow_graph()->InstanceCallNeedsClassCheck(
+          instr, RawFunction::kImplicitSetter)) {
     return false;
   }
 
diff --git a/runtime/vm/assembler.cc b/runtime/vm/assembler.cc
index 318881c..fe775bf 100644
--- a/runtime/vm/assembler.cc
+++ b/runtime/vm/assembler.cc
@@ -244,6 +244,7 @@
 
 intptr_t ObjectPoolWrapper::AddObject(const Object& obj,
                                       Patchability patchable) {
+  ASSERT(obj.IsNotTemporaryScopedHandle());
   return AddObject(ObjectPoolWrapperEntry(&obj), patchable);
 }
 
@@ -255,6 +256,10 @@
 
 intptr_t ObjectPoolWrapper::AddObject(ObjectPoolWrapperEntry entry,
                                       Patchability patchable) {
+  ASSERT((entry.type_ != ObjectPool::kTaggedObject) ||
+         (entry.obj_->IsNotTemporaryScopedHandle() &&
+          (entry.equivalence_ == NULL ||
+           entry.equivalence_->IsNotTemporaryScopedHandle())));
   object_pool_.Add(entry);
   if (patchable == kNotPatchable) {
     // The object isn't patchable. Record the index for fast lookup.
@@ -275,7 +280,6 @@
       return idx;
     }
   }
-
   return AddObject(entry, patchable);
 }
 
@@ -288,8 +292,7 @@
 
 intptr_t ObjectPoolWrapper::FindObject(const Object& obj,
                                        const Object& equivalence) {
-  return FindObject(ObjectPoolWrapperEntry(&obj, &equivalence),
-                    kNotPatchable);
+  return FindObject(ObjectPoolWrapperEntry(&obj, &equivalence), kNotPatchable);
 }
 
 
diff --git a/runtime/vm/assembler.h b/runtime/vm/assembler.h
index 5d20c01..65820fe 100644
--- a/runtime/vm/assembler.h
+++ b/runtime/vm/assembler.h
@@ -247,16 +247,8 @@
   ObjIndexPair(Key key, Value value) : value_(value) {
     key_.type_ = key.type_;
     if (key.type_ == ObjectPool::kTaggedObject) {
-      if (key.obj_->IsNotTemporaryScopedHandle()) {
-        key_.obj_ = key.obj_;
-      } else {
-        key_.obj_ = &Object::ZoneHandle(key.obj_->raw());
-      }
-      if (key.equivalence_->IsNotTemporaryScopedHandle()) {
-        key_.equivalence_ = key.equivalence_;
-      } else {
-        key_.equivalence_ = &Object::ZoneHandle(key.equivalence_->raw());
-      }
+      key_.obj_ = key.obj_;
+      key_.equivalence_ = key.equivalence_;
     } else {
       key_.raw_value_ = key.raw_value_;
     }
@@ -273,20 +265,12 @@
     if (key.obj_->IsSmi()) {
       return Smi::Cast(*key.obj_).Value();
     }
-    if (key.obj_->IsDouble()) {
-      return static_cast<intptr_t>(
-          bit_cast<int32_t, float>(
-              static_cast<float>(Double::Cast(*key.obj_).value())));
-    }
-    if (key.obj_->IsMint()) {
-      return static_cast<intptr_t>(Mint::Cast(*key.obj_).value());
-    }
-    if (key.obj_->IsString()) {
-      return String::Cast(*key.obj_).Hash();
-    }
-    // TODO(fschneider): Add hash function for other classes commonly used as
-    // compile-time constants.
-    return key.obj_->GetClassId();
+    // TODO(asiva) For now we assert that the object is from Old space
+    // and use the address of the raw object, once the weak_entry_table code
+    // in heap allows for multiple thread access we should switch this code
+    // to create a temporary raw obj => id mapping and use that.
+    ASSERT(key.obj_->IsOld());
+    return reinterpret_cast<intptr_t>(key.obj_->raw());
   }
 
   static inline bool IsKeyEqual(Pair kv, Key key) {
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 6f8cf47..41ba7f5 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -2720,7 +2720,7 @@
                        Patchability patchable,
                        Register pp,
                        Condition cond) {
-  const Code& target_code = Code::Handle(stub_entry.code());
+  const Code& target_code = Code::ZoneHandle(stub_entry.code());
   const int32_t offset = ObjectPool::element_offset(
       object_pool_wrapper_.FindObject(target_code, patchable));
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, pp, cond);
@@ -2744,7 +2744,7 @@
 
 void Assembler::BranchLink(const StubEntry& stub_entry,
                            Patchability patchable) {
-  const Code& code = Code::Handle(stub_entry.code());
+  const Code& code = Code::ZoneHandle(stub_entry.code());
   BranchLink(code, patchable);
 }
 
@@ -2763,7 +2763,7 @@
 
 void Assembler::BranchLinkWithEquivalence(const StubEntry& stub_entry,
                                           const Object& equivalence) {
-  const Code& target = Code::Handle(stub_entry.code());
+  const Code& target = Code::ZoneHandle(stub_entry.code());
   // Make sure that class CallPattern is able to patch the label referred
   // to by this code sequence.
   // For added code robustness, use 'blx lr' in a patchable sequence and
@@ -2783,7 +2783,7 @@
 
 
 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) {
-  BranchLinkPatchable(Code::Handle(stub_entry.code()));
+  BranchLinkPatchable(Code::ZoneHandle(stub_entry.code()));
 }
 
 
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index a481b7b..28dc872 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -583,7 +583,7 @@
 void Assembler::Branch(const StubEntry& stub_entry,
                        Register pp,
                        Patchability patchable) {
-  const Code& target = Code::Handle(stub_entry.code());
+  const Code& target = Code::ZoneHandle(stub_entry.code());
   const int32_t offset = ObjectPool::element_offset(
       object_pool_wrapper_.FindObject(target, patchable));
   LoadWordFromPoolOffset(CODE_REG, offset, pp);
@@ -598,7 +598,7 @@
 
 void Assembler::BranchLink(const StubEntry& stub_entry,
                            Patchability patchable) {
-  const Code& target = Code::Handle(stub_entry.code());
+  const Code& target = Code::ZoneHandle(stub_entry.code());
   const int32_t offset = ObjectPool::element_offset(
       object_pool_wrapper_.FindObject(target, patchable));
   LoadWordFromPoolOffset(CODE_REG, offset);
@@ -621,7 +621,7 @@
 
 void Assembler::BranchLinkWithEquivalence(const StubEntry& stub_entry,
                                           const Object& equivalence) {
-  const Code& target = Code::Handle(stub_entry.code());
+  const Code& target = Code::ZoneHandle(stub_entry.code());
   const int32_t offset = ObjectPool::element_offset(
       object_pool_wrapper_.FindObject(target, equivalence));
   LoadWordFromPoolOffset(CODE_REG, offset);
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 98aebcb..68794ed 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -493,9 +493,9 @@
 
 void Assembler::Branch(const StubEntry& stub_entry, Register pp) {
   ASSERT(!in_delay_slot_);
-  const Code& target_code = Code::Handle(stub_entry.code());
+  const Code& target_code = Code::ZoneHandle(stub_entry.code());
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target_code, kPatchable));
+      object_pool_wrapper_.AddObject(target_code, kPatchable));
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, pp);
   lw(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
   jr(TMP);
@@ -524,12 +524,12 @@
 
 void Assembler::BranchLink(const StubEntry& stub_entry,
                            Patchability patchable) {
-  BranchLink(Code::Handle(stub_entry.code()), patchable);
+  BranchLink(Code::ZoneHandle(stub_entry.code()), patchable);
 }
 
 
 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) {
-  BranchLink(Code::Handle(stub_entry.code()), kPatchable);
+  BranchLink(Code::ZoneHandle(stub_entry.code()), kPatchable);
 }
 
 
@@ -542,7 +542,7 @@
 
 void Assembler::BranchLinkWithEquivalence(const StubEntry& stub_entry,
                                           const Object& equivalence) {
-  const Code& target = Code::Handle(stub_entry.code());
+  const Code& target = Code::ZoneHandle(stub_entry.code());
   ASSERT(!in_delay_slot_);
   const int32_t offset = ObjectPool::element_offset(
       object_pool_wrapper_.FindObject(target, equivalence));
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 1418548..478c2ae 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -83,10 +83,10 @@
 
 void Assembler::CallPatchable(const StubEntry& stub_entry) {
   ASSERT(constant_pool_allowed());
-  const Code& target = Code::Handle(stub_entry.code());
+  const Code& target = Code::ZoneHandle(stub_entry.code());
   intptr_t call_start = buffer_.GetPosition();
-  const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target, kPatchable));
+  const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable);
+  const int32_t offset = ObjectPool::element_offset(idx);
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
   movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
   call(TMP);
@@ -97,9 +97,9 @@
 void Assembler::CallWithEquivalence(const StubEntry& stub_entry,
                                     const Object& equivalence) {
   ASSERT(constant_pool_allowed());
-  const Code& target = Code::Handle(stub_entry.code());
-  const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target, equivalence));
+  const Code& target = Code::ZoneHandle(stub_entry.code());
+  const intptr_t idx = object_pool_wrapper_.FindObject(target, equivalence);
+  const int32_t offset = ObjectPool::element_offset(idx);
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
   movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
   call(TMP);
@@ -108,9 +108,9 @@
 
 void Assembler::Call(const StubEntry& stub_entry) {
   ASSERT(constant_pool_allowed());
-  const Code& target = Code::Handle(stub_entry.code());
-  const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target, kNotPatchable));
+  const Code& target = Code::ZoneHandle(stub_entry.code());
+  const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable);
+  const int32_t offset = ObjectPool::element_offset(idx);
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
   movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
   call(TMP);
@@ -2584,9 +2584,9 @@
 
 void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) {
   ASSERT((pp != PP) || constant_pool_allowed());
-  const Code& target = Code::Handle(stub_entry.code());
-  const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target, kPatchable));
+  const Code& target = Code::ZoneHandle(stub_entry.code());
+  const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable);
+  const int32_t offset = ObjectPool::element_offset(idx);
   movq(CODE_REG, Address::AddressBaseImm32(pp, offset - kHeapObjectTag));
   movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
   jmp(TMP);
@@ -2595,9 +2595,9 @@
 
 void Assembler::Jmp(const StubEntry& stub_entry, Register pp) {
   ASSERT((pp != PP) || constant_pool_allowed());
-  const Code& target = Code::Handle(stub_entry.code());
-  const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target, kNotPatchable));
+  const Code& target = Code::ZoneHandle(stub_entry.code());
+  const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable);
+  const int32_t offset = ObjectPool::element_offset(idx);
   movq(CODE_REG, FieldAddress(pp, offset));
   movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
   jmp(TMP);
@@ -2797,9 +2797,10 @@
   if (Thread::CanLoadFromThread(object)) {
     movq(dst, Address(THR, Thread::OffsetFromThread(object)));
   } else if (CanLoadFromObjectPool(object)) {
-    const int32_t offset = ObjectPool::element_offset(
+    const intptr_t idx =
         is_unique ? object_pool_wrapper_.AddObject(object)
-                  : object_pool_wrapper_.FindObject(object));
+                  : object_pool_wrapper_.FindObject(object);
+    const int32_t offset = ObjectPool::element_offset(idx);
     LoadWordFromPoolOffset(dst, offset - kHeapObjectTag);
   } else {
     ASSERT(object.IsSmi() || object.InVMHeap());
@@ -2814,8 +2815,8 @@
                                            Register new_pp) {
   ASSERT(!constant_pool_allowed());
   ASSERT(new_pp != PP);
-  const int32_t offset =
-      ObjectPool::element_offset(object_pool_wrapper_.FindObject(function));
+  const intptr_t idx = object_pool_wrapper_.FindObject(function, kNotPatchable);
+  const int32_t offset = ObjectPool::element_offset(idx);
   movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag));
 }
 
@@ -2867,8 +2868,8 @@
   if (Thread::CanLoadFromThread(object)) {
     cmpq(reg, Address(THR, Thread::OffsetFromThread(object)));
   } else if (CanLoadFromObjectPool(object)) {
-    const int32_t offset =
-        ObjectPool::element_offset(object_pool_wrapper_.FindObject(object));
+    const intptr_t idx = object_pool_wrapper_.FindObject(object, kNotPatchable);
+    const int32_t offset =  ObjectPool::element_offset(idx);
     cmpq(reg, Address(PP, offset-kHeapObjectTag));
   } else {
     ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses);
diff --git a/runtime/vm/atomic.h b/runtime/vm/atomic.h
index fc6257e..026762f 100644
--- a/runtime/vm/atomic.h
+++ b/runtime/vm/atomic.h
@@ -26,6 +26,7 @@
   // NOTE: Not to be used for any atomic operations involving memory locations
   // that are accessed by generated code.
   static void IncrementBy(intptr_t* p, intptr_t value);
+  static void IncrementInt64By(int64_t* p, int64_t value);
 
   // Atomically fetch the value at p and decrement the value at p.
   // Returns the original value at p.
diff --git a/runtime/vm/atomic_android.h b/runtime/vm/atomic_android.h
index c3727af..b994343 100644
--- a/runtime/vm/atomic_android.h
+++ b/runtime/vm/atomic_android.h
@@ -26,6 +26,11 @@
 }
 
 
+inline void AtomicOperations::IncrementInt64By(int64_t* p, int64_t value) {
+  __sync_fetch_and_add(p, value);
+}
+
+
 inline uintptr_t AtomicOperations::FetchAndDecrement(uintptr_t* p) {
   return __sync_fetch_and_sub(p, 1);
 }
diff --git a/runtime/vm/atomic_linux.h b/runtime/vm/atomic_linux.h
index 15f0396..615004a 100644
--- a/runtime/vm/atomic_linux.h
+++ b/runtime/vm/atomic_linux.h
@@ -26,6 +26,11 @@
 }
 
 
+inline void AtomicOperations::IncrementInt64By(int64_t* p, int64_t value) {
+  __sync_fetch_and_add(p, value);
+}
+
+
 inline uintptr_t AtomicOperations::FetchAndDecrement(uintptr_t* p) {
   return __sync_fetch_and_sub(p, 1);
 }
diff --git a/runtime/vm/atomic_macos.h b/runtime/vm/atomic_macos.h
index fd5af87..ae5da3a 100644
--- a/runtime/vm/atomic_macos.h
+++ b/runtime/vm/atomic_macos.h
@@ -26,6 +26,11 @@
 }
 
 
+inline void AtomicOperations::IncrementInt64By(int64_t* p, int64_t value) {
+  __sync_fetch_and_add(p, value);
+}
+
+
 inline uintptr_t AtomicOperations::FetchAndDecrement(uintptr_t* p) {
   return __sync_fetch_and_sub(p, 1);
 }
diff --git a/runtime/vm/atomic_win.h b/runtime/vm/atomic_win.h
index 1563035..38ec10a 100644
--- a/runtime/vm/atomic_win.h
+++ b/runtime/vm/atomic_win.h
@@ -41,6 +41,16 @@
 }
 
 
+inline void AtomicOperations::IncrementInt64By(int64_t* p, int64_t value) {
+#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
+  InterlockedExchangeAdd64(reinterpret_cast<LONGLONG*>(p),
+                           static_cast<LONGLONG>(value));
+#else
+#error Unsupported host architecture.
+#endif
+}
+
+
 inline uintptr_t AtomicOperations::FetchAndDecrement(uintptr_t* p) {
 #if defined(HOST_ARCH_X64)
   return static_cast<uintptr_t>(
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 1c59f8d..7750375 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -138,7 +138,7 @@
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
   TransitionNativeToVM transition(thread);
-  CompilerStats* stats = thread->isolate()->compiler_stats();
+  CompilerStats* stats = thread->isolate()->aggregate_compiler_stats();
   ASSERT(stats != NULL);
   stats->EnableBenchmark();
   Timer timer(true, "Compiler stats compiling all of Core lib");
@@ -174,7 +174,7 @@
         reinterpret_cast<Dart_NativeEntryResolver>(NativeResolver));
     EXPECT_VALID(lib);
   }
-  CompilerStats* stats = thread->isolate()->compiler_stats();
+  CompilerStats* stats = thread->isolate()->aggregate_compiler_stats();
   ASSERT(stats != NULL);
   stats->EnableBenchmark();
   Timer timer(true, "Compile all of dart2js benchmark");
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 1a256cd..9497eab 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -2427,7 +2427,12 @@
     // fields because type parameters are parsed before the class body. Since
     // 'ResolveAndFinalizeMemberTypes(cls)' has not been called yet, unfinalized
     // member types could choke the snapshotter.
-    ASSERT(Array::Handle(cls.functions()).Length() == 0);
+    // Or
+    // if the class is being refinalized because a patch is being applied
+    // after the class has been finalized then it is ok for the class to have
+    // functions.
+    ASSERT((Array::Handle(cls.functions()).Length() == 0) ||
+           cls.is_refinalize_after_patch());
   }
 }
 
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index bf5eac5..26e51fe 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1109,6 +1109,7 @@
                                        bool optimized,
                                        intptr_t osr_id) {
   ASSERT(!FLAG_precompiled_mode);
+  ASSERT(!optimized || function.was_compiled());
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     Thread* const thread = Thread::Current();
@@ -1165,7 +1166,11 @@
     }
 
     const bool success = helper.Compile(pipeline);
-    if (!success) {
+    if (success) {
+      if (!optimized) {
+        function.set_was_compiled(true);
+      }
+    } else {
       if (optimized) {
         if (Compiler::IsBackgroundCompilation()) {
           // Try again later, background compilation may abort because of
@@ -1375,15 +1380,20 @@
   ASSERT(var_descs.IsNull());
   // IsIrregexpFunction have eager var descriptors generation.
   ASSERT(!function.IsIrregexpFunction());
-  // Parser should not produce any errors, therefore no LongJumpScope needed.
-  // (exception is background compilation).
-  ASSERT(!Compiler::IsBackgroundCompilation());
-  Parser::ParseFunction(parsed_function);
-  parsed_function->AllocateVariables();
-  var_descs = parsed_function->node_sequence()->scope()->
-      GetVarDescriptors(function);
-  ASSERT(!var_descs.IsNull());
-  code.set_var_descriptors(var_descs);
+  // In background compilation, parser can produce 'errors": bailouts
+  // if state changed while compiling in background.
+  LongJumpScope jump;
+  if (setjmp(*jump.Set()) == 0) {
+    Parser::ParseFunction(parsed_function);
+    parsed_function->AllocateVariables();
+    var_descs = parsed_function->node_sequence()->scope()->
+        GetVarDescriptors(function);
+    ASSERT(!var_descs.IsNull());
+    code.set_var_descriptors(var_descs);
+  } else {
+    // Only possible with background compilation.
+    ASSERT(Compiler::IsBackgroundCompilation());
+  }
 }
 
 
@@ -1676,6 +1686,8 @@
       Function& function = Function::Handle(zone);
       function = function_queue()->PeekFunction();
       while (running_ && !function.IsNull()) {
+        // Check that we have aggregated and cleared the stats.
+        ASSERT(thread->compiler_stats()->IsCleared());
         const Error& error = Error::Handle(zone,
             Compiler::CompileOptimizedFunction(thread,
                                                function,
@@ -1685,6 +1697,14 @@
         // unoptimized code. Any issues while optimizing are flagged by
         // making the result invalid.
         ASSERT(error.IsNull());
+#ifndef PRODUCT
+        Isolate* isolate = thread->isolate();
+        // We cannot aggregate stats if isolate is shutting down.
+        if (isolate->HasMutatorThread()) {
+          isolate->aggregate_compiler_stats()->Add(*thread->compiler_stats());
+        }
+        thread->compiler_stats()->Clear();
+#endif  // PRODUCT
         QueueElement* qelem = function_queue()->Remove();
         delete qelem;
         function = function_queue()->PeekFunction();
@@ -1763,10 +1783,12 @@
   // compilation.
   Class& cls = Class::Handle(thread->zone(),
       Library::LookupCoreClass(Symbols::NoSuchMethodError()));
+  ASSERT(!cls.IsNull());
   Error& error = Error::Handle(thread->zone(),
       cls.EnsureIsFinalized(thread));
   ASSERT(error.IsNull());
   cls = Library::LookupCoreClass(Symbols::_Mint());
+  ASSERT(!cls.IsNull());
   error = cls.EnsureIsFinalized(thread);
   ASSERT(error.IsNull());
 
diff --git a/runtime/vm/compiler_stats.cc b/runtime/vm/compiler_stats.cc
index d7950c1..d23e6f0 100644
--- a/runtime/vm/compiler_stats.cc
+++ b/runtime/vm/compiler_stats.cc
@@ -51,38 +51,15 @@
 
 CompilerStats::CompilerStats(Isolate* isolate)
     : isolate_(isolate),
-      parser_timer(true, "parser timer"),
-      scanner_timer(true, "scanner timer"),
-      codegen_timer(true, "codegen timer"),
-      graphbuilder_timer(true, "flow graph builder timer"),
-      ssa_timer(true, "flow graph SSA timer"),
-      graphinliner_timer(true, "flow graph inliner timer"),
-      graphinliner_parse_timer(true, "inliner parsing timer"),
-      graphinliner_build_timer(true, "inliner building timer"),
-      graphinliner_ssa_timer(true, "inliner SSA timer"),
-      graphinliner_opt_timer(true, "inliner optimization timer"),
-      graphinliner_subst_timer(true, "inliner substitution timer"),
-      graphoptimizer_timer(true, "flow graph optimizer timer"),
-      graphcompiler_timer(true, "flow graph compiler timer"),
-      codefinalizer_timer(true, "code finalization timer"),
-      num_tokens_total(0),
-      num_tokens_scanned(0),
-      num_tokens_consumed(0),
-      num_cached_consts(0),
-      num_const_cache_hits(0),
-      num_classes_parsed(0),
-      num_class_tokens(0),
-      num_functions_parsed(0),
-      num_functions_compiled(0),
-      num_functions_optimized(0),
-      num_func_tokens_compiled(0),
-      num_implicit_final_getters(0),
-      num_method_extractors(0),
-      src_length(0),
-      total_code_size(0),
-      total_instr_size(0),
-      pc_desc_size(0),
-      vardesc_size(0),
+#define INITIALIZE_TIMER(timer_name, description)                              \
+      timer_name(true, description),
+STAT_TIMERS(INITIALIZE_TIMER)
+#undef INITIALIZE_TIMER
+
+#define INITIALIZE_COUNTERS(counter_name)                                      \
+      counter_name(0),
+STAT_COUNTERS(INITIALIZE_COUNTERS)
+#undef INITIALIZE_COUNTERS
       text(NULL),
       use_benchmark_output(false) {
 }
@@ -90,6 +67,54 @@
 
 #ifndef PRODUCT
 
+
+// Used to aggregate stats. Must be atomic.
+void CompilerStats::Add(const CompilerStats& other) {
+#define ADD_TOTAL(timer_name, literal)                                         \
+  timer_name.AddTotal(other.timer_name);
+
+  STAT_TIMERS(ADD_TOTAL)
+#undef ADD_TOTAL
+
+#define ADD_COUNTER(counter_name)                                              \
+  AtomicOperations::IncrementInt64By(&counter_name, other.counter_name);
+
+  STAT_COUNTERS(ADD_COUNTER)
+#undef ADD_COUNTER
+}
+
+
+void CompilerStats::Clear() {
+#define CLEAR_TIMER(timer_name, literal)                                       \
+  timer_name.Reset();
+
+  STAT_TIMERS(CLEAR_TIMER)
+#undef CLEAR_TIMER
+
+#define CLEAR_COUNTER(counter_name)                                            \
+  counter_name = 0;
+
+  STAT_COUNTERS(CLEAR_COUNTER)
+#undef CLEAR_COUNTER
+}
+
+
+bool CompilerStats::IsCleared() const {
+#define CHECK_TIMERS(timer_name, literal)                                      \
+  if (!timer_name.IsReset()) return false;
+
+  STAT_TIMERS(CHECK_TIMERS)
+#undef CHECK_TIMERS
+
+#define CHECK_COUNTERS(counter_name)                                           \
+  if (counter_name != 0) return false;
+
+  STAT_COUNTERS(CHECK_COUNTERS)
+#undef CHECK_COUNTERS
+  return true;
+}
+
+
 // This function is used as a callback in the log object to which the
 // compiler stats are printed. It will be called only once, to print
 // the accumulated text when all of the compiler stats values are
@@ -98,7 +123,7 @@
 static void PrintToStats(const char* format, ...) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
-  CompilerStats* stats = isolate->compiler_stats();
+  CompilerStats* stats = isolate->aggregate_compiler_stats();
   Zone* zone = thread->zone();
   ASSERT(stats != NULL);
   va_list args;
diff --git a/runtime/vm/compiler_stats.h b/runtime/vm/compiler_stats.h
index 9b9e67b..5ed7537 100644
--- a/runtime/vm/compiler_stats.h
+++ b/runtime/vm/compiler_stats.h
@@ -6,6 +6,7 @@
 #define VM_COMPILER_STATS_H_
 
 #include "vm/allocation.h"
+#include "vm/atomic.h"
 #include "vm/flags.h"
 #include "vm/isolate.h"
 #include "vm/timer.h"
@@ -13,10 +14,47 @@
 
 namespace dart {
 
-
 DECLARE_FLAG(bool, compiler_stats);
 DECLARE_FLAG(bool, compiler_benchmark);
 
+
+#define STAT_TIMERS(V)                                                         \
+  V(parser_timer, "parser timer")                                              \
+  V(scanner_timer, "scanner timer")                                            \
+  V(codegen_timer, "codegen timer")                                            \
+  V(graphbuilder_timer, "flow graph builder timer")                            \
+  V(ssa_timer, "flow graph SSA timer")                                         \
+  V(graphinliner_timer, "flow graph inliner timer")                            \
+  V(graphinliner_parse_timer, "inliner parsing timer")                         \
+  V(graphinliner_build_timer, "inliner building timer")                        \
+  V(graphinliner_ssa_timer, "inliner SSA timer")                               \
+  V(graphinliner_opt_timer, "inliner optimization timer")                      \
+  V(graphinliner_subst_timer, "inliner substitution timer")                    \
+  V(graphoptimizer_timer, "flow graph optimizer timer")                        \
+  V(graphcompiler_timer, "flow graph compiler timer")                          \
+  V(codefinalizer_timer, "code finalization timer")                            \
+
+
+#define STAT_COUNTERS(V)                                                       \
+  V(num_tokens_total)                                                          \
+  V(num_tokens_scanned)                                                        \
+  V(num_tokens_consumed)                                                       \
+  V(num_cached_consts)                                                         \
+  V(num_const_cache_hits)                                                      \
+  V(num_classes_parsed)                                                        \
+  V(num_class_tokens)                                                          \
+  V(num_functions_parsed)                                                      \
+  V(num_functions_compiled)                                                    \
+  V(num_functions_optimized)                                                   \
+  V(num_func_tokens_compiled)                                                  \
+  V(num_implicit_final_getters)                                                \
+  V(num_method_extractors)                                                     \
+  V(src_length)                                                                \
+  V(total_code_size)                                                           \
+  V(total_instr_size)                                                          \
+  V(pc_desc_size)                                                              \
+  V(vardesc_size)                                                              \
+
 class CompilerStats {
  public:
   explicit CompilerStats(Isolate* isolate);
@@ -24,6 +62,8 @@
 
   Isolate* isolate_;
 
+  // We could use STAT_TIMERS and STAT_COUNTERS to declare fields, but then
+  // we would be losing the comments.
   Timer parser_timer;         // Cumulative runtime of parser.
   Timer scanner_timer;        // Cumulative runtime of scanner.
   Timer codegen_timer;        // Cumulative runtime of code generator.
@@ -63,28 +103,38 @@
   char* text;
   bool use_benchmark_output;
 
-  // Update stats that are computed, e.g. token count.
-  void Update();
 
   void EnableBenchmark();
   char* BenchmarkOutput();
   char* PrintToZone();
+
+  // Used to aggregate stats.
+  void Add(const CompilerStats& other);
+  void Clear();
+
+  bool IsCleared() const;
+
+ private:
+  // Update stats that are computed, e.g. token count.
+  void Update();
 };
 
+// Make increment atomic in case it occurs in parallel with aggregation from
+// other thread.
 #define INC_STAT(thread, counter, incr)                                        \
   if (FLAG_support_compiler_stats && FLAG_compiler_stats) {                    \
-    MutexLocker ml((thread)->isolate()->mutex());                              \
-    (thread)->isolate()->compiler_stats()->counter += (incr);                  \
+    AtomicOperations::IncrementInt64By(                                        \
+        &(thread)->compiler_stats()->counter, (incr));                         \
   }
 
 #define STAT_VALUE(thread, counter)                                            \
   ((FLAG_support_compiler_stats && FLAG_compiler_stats) ?                      \
-      (thread)->isolate()->compiler_stats()->counter : 0)
+      (thread)->compiler_stats()->counter : 0)
 
 #define CSTAT_TIMER_SCOPE(thr, t)                                              \
   TimerScope timer(FLAG_support_compiler_stats && FLAG_compiler_stats,         \
       (FLAG_support_compiler_stats && FLAG_compiler_stats) ?                   \
-      &((thr)->isolate()->compiler_stats()->t) : NULL,                         \
+      &((thr)->compiler_stats()->t) : NULL,                                    \
       thr);
 
 
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 8dd7c2f..3eda03d 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -174,7 +174,9 @@
   String& expr_text = String::Handle();
   expr_text = String::New("apa + ' ${calc(10)}' + dot");
   Object& val = Object::Handle();
-  val = Instance::Cast(obj).Evaluate(expr_text,
+  const Class& receiver_cls = Class::Handle(obj.clazz());
+  val = Instance::Cast(obj).Evaluate(receiver_cls,
+                                     expr_text,
                                      Array::empty_array(),
                                      Array::empty_array());
   EXPECT(!val.IsNull());
diff --git a/runtime/vm/custom_isolate_test.cc b/runtime/vm/custom_isolate_test.cc
index 1995ee6..1f55a8e 100644
--- a/runtime/vm/custom_isolate_test.cc
+++ b/runtime/vm/custom_isolate_test.cc
@@ -323,6 +323,10 @@
   FLAG_verify_handles = true;
 #ifdef DEBUG
   FLAG_verify_on_transition = true;
+  // Cannot verify heap while running compilation in background. Issue #26149.
+  FLAG_background_compilation = false;
+  // Issue #26150.
+  FLAG_use_osr = false;
 #endif
   event_queue = new EventQueue();
 
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index d8367fe..0041d9a 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -180,6 +180,13 @@
       if (!error.IsNull()) {
         return error.ToCString();
       }
+      NOT_IN_PRODUCT(if (tds.enabled()) {
+        tds.SetNumArguments(2);
+        tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length());
+        tds.FormatArgument(1, "heapSize", "%" Pd64,
+                           vm_isolate_->heap()->UsedInWords(Heap::kOld) *
+                           kWordSize);
+      });
       if (FLAG_trace_isolates) {
         OS::Print("Size of vm isolate snapshot = %" Pd "\n",
                   snapshot->length());
@@ -444,6 +451,12 @@
     if (!error.IsNull()) {
       return error.raw();
     }
+    NOT_IN_PRODUCT(if (tds.enabled()) {
+      tds.SetNumArguments(2);
+      tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length());
+      tds.FormatArgument(1, "heapSize", "%" Pd64,
+                         I->heap()->UsedInWords(Heap::kOld) * kWordSize);
+    });
     if (FLAG_trace_isolates) {
       I->heap()->PrintSizes();
       MegamorphicCacheTable::PrintSizes(I);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 5f314a6..fd0050d 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1483,6 +1483,8 @@
     return state;
   }
   I->heap()->CollectAllGarbage();
+  I->StopBackgroundCompiler();
+
 #if defined(DEBUG)
   FunctionVisitor check_canonical(T);
   I->heap()->IterateObjects(&check_canonical);
@@ -5947,7 +5949,7 @@
 
 DART_EXPORT void Dart_TimelineEvent(const char* label,
                                     int64_t timestamp0,
-                                    int64_t timestamp1,
+                                    int64_t timestamp1_or_async_id,
                                     Dart_Timeline_Event_Type type,
                                     intptr_t argument_count,
                                     const char** argument_names,
@@ -5958,7 +5960,7 @@
   if (type < Dart_Timeline_Event_Begin) {
     return;
   }
-  if (type > Dart_Timeline_Event_Duration) {
+  if (type > Dart_Timeline_Event_Counter) {
     return;
   }
   TimelineStream* stream = Timeline::GetEmbedderStream();
@@ -5978,7 +5980,19 @@
       event->Instant(label, timestamp0);
     break;
     case Dart_Timeline_Event_Duration:
-      event->Duration(label, timestamp0, timestamp1);
+      event->Duration(label, timestamp0, timestamp1_or_async_id);
+    break;
+    case Dart_Timeline_Event_Async_Begin:
+      event->AsyncBegin(label, timestamp1_or_async_id, timestamp0);
+    break;
+    case Dart_Timeline_Event_Async_End:
+      event->AsyncEnd(label, timestamp1_or_async_id, timestamp0);
+    break;
+    case Dart_Timeline_Event_Async_Instant:
+      event->AsyncInstant(label, timestamp1_or_async_id, timestamp0);
+    break;
+    case Dart_Timeline_Event_Counter:
+      event->Counter(label, timestamp0);
     break;
     default:
       FATAL("Unknown Dart_Timeline_Event_Type");
@@ -5991,115 +6005,16 @@
 }
 
 
-DART_EXPORT void Dart_TimelineDuration(const char* label,
-                                       int64_t start_micros,
-                                       int64_t end_micros) {
-  if (!FLAG_support_timeline) {
+DART_EXPORT void Dart_SetThreadName(const char* name) {
+  OSThread* thread = OSThread::Current();
+  if (thread == NULL) {
+    // VM is shutting down.
     return;
   }
-  if (start_micros > end_micros) {
-    FATAL1("%s: start_micros must be <= end_micros", CURRENT_FUNC);
-  }
-  if (label == NULL) {
-    return;
-  }
-  TimelineStream* stream = Timeline::GetEmbedderStream();
-  ASSERT(stream != NULL);
-  TimelineEvent* event = stream->StartEvent();
-  if (event != NULL) {
-    event->Duration(label, start_micros, end_micros);
-    event->Complete();
-  }
+  thread->SetName(name);
 }
 
 
-DART_EXPORT void Dart_TimelineInstant(const char* label) {
-  if (!FLAG_support_timeline) {
-    return;
-  }
-  if (label == NULL) {
-    return;
-  }
-  TimelineStream* stream = Timeline::GetEmbedderStream();
-  ASSERT(stream != NULL);
-  TimelineEvent* event = stream->StartEvent();
-  if (event != NULL) {
-    event->Instant(label);
-    event->Complete();
-  }
-  return;
-}
-
-
-DART_EXPORT void Dart_TimelineAsyncBegin(const char* label,
-                                         int64_t* async_id) {
-  if (!FLAG_support_timeline) {
-    return;
-  }
-  if (label == NULL) {
-    return;
-  }
-  if (async_id == NULL) {
-    return;
-  }
-  *async_id = -1;
-  TimelineStream* stream = Timeline::GetEmbedderStream();
-  ASSERT(stream != NULL);
-  TimelineEvent* event = stream->StartEvent();
-  if (event != NULL) {
-    TimelineEventRecorder* recorder = Timeline::recorder();
-    ASSERT(recorder != NULL);
-    *async_id = recorder->GetNextAsyncId();
-    event->AsyncBegin(label, *async_id);
-    event->Complete();
-  }
-  return;
-}
-
-
-DART_EXPORT void Dart_TimelineAsyncInstant(const char* label,
-                                           int64_t async_id) {
-  if (!FLAG_support_timeline) {
-    return;
-  }
-  if (async_id < 0) {
-    return;
-  }
-  if (label == NULL) {
-    return;
-  }
-  TimelineStream* stream = Timeline::GetEmbedderStream();
-  ASSERT(stream != NULL);
-  TimelineEvent* event = stream->StartEvent();
-  if (event != NULL) {
-    event->AsyncInstant(label, async_id);
-    event->Complete();
-  }
-  return;
-}
-
-
-DART_EXPORT void Dart_TimelineAsyncEnd(const char* label,
-                                       int64_t async_id) {
-  if (!FLAG_support_timeline) {
-    return;
-  }
-  if (async_id < 0) {
-    return;
-  }
-  if (label == NULL) {
-    return;
-  }
-  TimelineStream* stream = Timeline::GetEmbedderStream();
-  ASSERT(stream != NULL);
-  TimelineEvent* event = stream->StartEvent();
-  if (event != NULL) {
-    event->AsyncEnd(label, async_id);
-    event->Complete();
-  }
-  return;
-}
-
 // The precompiler is included in dart_bootstrap and dart_noopt, and
 // excluded from dart and dart_precompiled_runtime.
 #if !defined(DART_PRECOMPILER)
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index d8d4fb0..7ccf6a0 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "bin/builtin.h"
+#include "vm/compiler.h"
 #include "include/dart_api.h"
 #include "include/dart_mirrors_api.h"
 #include "include/dart_native_api.h"
@@ -9195,7 +9196,11 @@
   // Make sure it is enabled.
   stream->set_enabled(true);
   // Add a duration event.
-  Dart_TimelineDuration("testDurationEvent", 0, 1);
+  Dart_TimelineEvent("testDurationEvent",
+                     0,
+                     1,
+                     Dart_Timeline_Event_Duration,
+                     0, NULL, NULL);
   // Check that it is in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
   Timeline::ReclaimCachedBlocksFromThreads();
@@ -9212,7 +9217,11 @@
   TimelineStream* stream = Timeline::GetEmbedderStream();
   // Make sure it is enabled.
   stream->set_enabled(true);
-  Dart_TimelineInstant("testInstantEvent");
+  Dart_TimelineEvent("testInstantEvent",
+                     0,
+                     1,
+                     Dart_Timeline_Event_Instant,
+                     0, NULL, NULL);
   // Check that it is in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
   Timeline::ReclaimCachedBlocksFromThreads();
@@ -9228,12 +9237,12 @@
   TimelineStream* stream = Timeline::GetEmbedderStream();
   // Make sure it is disabled.
   stream->set_enabled(false);
-  int64_t async_id = -1;
-  Dart_TimelineAsyncBegin("testAsyncEvent", &async_id);
-  // Expect that the |async_id| is negative because the stream is disabled.
-  EXPECT(async_id < 0);
-  // Call Dart_TimelineAsyncEnd with a negative async_id.
-  Dart_TimelineAsyncEnd("testAsyncEvent", async_id);
+  int64_t async_id = 99;
+  Dart_TimelineEvent("testAsyncEvent",
+                     0,
+                     async_id,
+                     Dart_Timeline_Event_Async_Begin,
+                     0, NULL, NULL);
   // Check that testAsync is not in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
   Timeline::ReclaimCachedBlocksFromThreads();
@@ -9250,12 +9259,12 @@
   TimelineStream* stream = Timeline::GetEmbedderStream();
   // Make sure it is enabled.
   stream->set_enabled(true);
-  int64_t async_id = -1;
-  Dart_TimelineAsyncBegin("testAsyncEvent", &async_id);
-  // Expect that the |async_id| is >= 0.
-  EXPECT(async_id >= 0);
-
-  Dart_TimelineAsyncEnd("testAsyncEvent", async_id);
+  int64_t async_id = 99;
+  Dart_TimelineEvent("testAsyncEvent",
+                     0,
+                     async_id,
+                     Dart_Timeline_Event_Async_Begin,
+                     0, NULL, NULL);
 
   // Check that it is in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
@@ -9539,6 +9548,15 @@
                        1,
                        &arg_names[0],
                        &arg_values[0]);
+    // Add counter to the embedder stream.
+    Dart_TimelineEvent("COUNTER_EVENT",
+                       Dart_TimelineGetMicros(),
+                       0,
+                       Dart_Timeline_Event_Counter,
+                       0,
+                       NULL,
+                       NULL);
+    Dart_SetThreadName("CUSTOM THREAD NAME");
   }
 
   // Invoke main, which will be compiled resulting in a compiler event in
@@ -9583,6 +9601,8 @@
   EXPECT_SUBSTRING("TRACE_EVENT", buffer);
   EXPECT_SUBSTRING("arg0", buffer);
   EXPECT_SUBSTRING("value0", buffer);
+  EXPECT_SUBSTRING("COUNTER_EVENT", buffer);
+  EXPECT_SUBSTRING("CUSTOM THREAD NAME", buffer);
 
   // Free buffer allocated by AppendStreamConsumer
   free(data.buffer);
@@ -9827,6 +9847,164 @@
   EXPECT(stop_called);
 }
 
+
+TEST_CASE(Dart_LoadLibraryPatch_1) {
+  const char* kScriptChars1 =
+      "class A {\n"
+      "  int foo() { return 10; }\n"
+      "  external int zoo();\n"
+      "  external static int moo();\n"
+      "}\n"
+      "main() { new A().foo(); }\n"
+      "foozoo() { new A().zoo(); }\n"
+      "foomoo() { A.moo(); }\n";
+
+  const char* kScriptChars2 =
+      "patch class A {\n"
+      "  /* patch */ int zoo() { return 1; }\n"
+      "  /* patch */ static int moo() { return 1; }\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
+  Dart_Handle result = Dart_Invoke(lib,
+                                   NewString("main"),
+                                   0,
+                                   NULL);
+  EXPECT_VALID(result);
+  Dart_Handle url = NewString("test-lib-patch");
+  Dart_Handle source = NewString(kScriptChars2);
+  result = Dart_LibraryLoadPatch(lib, url, source);
+  EXPECT_VALID(result);
+  result = Dart_FinalizeLoading(false);
+  EXPECT_VALID(result);
+  result = Dart_Invoke(lib,
+                       NewString("foozoo"),
+                       0,
+                       NULL);
+  EXPECT_VALID(result);
+  result = Dart_Invoke(lib,
+                       NewString("foomoo"),
+                       0,
+                       NULL);
+  EXPECT_VALID(result);
+}
+
+
+TEST_CASE(Dart_LoadLibraryPatch_Error1) {
+  const char* kScriptChars1 =
+      "class A {\n"
+      "  int foo() { return 10; }\n"
+      "  external int zoo();\n"
+      "}\n"
+      "main() { new A().foo(); }\n"
+      "foozoo() { new A().zoo(); }\n";
+
+  const char* kScriptChars2 =
+      "patch class A {\n"
+      "  /* patch */ int zoo() { return 1; }\n"
+      "  /* patch */ int fld1;\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
+  Dart_Handle result = Dart_Invoke(lib,
+                                   NewString("main"),
+                                   0,
+                                   NULL);
+  EXPECT_VALID(result);
+  Dart_Handle url = NewString("test-lib-patch");
+  Dart_Handle source = NewString(kScriptChars2);
+  // We don't expect to be able to patch in this case as new fields
+  // are being added.
+  result = Dart_LibraryLoadPatch(lib, url, source);
+  EXPECT_VALID(result);
+  result = Dart_FinalizeLoading(false);
+  EXPECT_VALID(result);
+  result = Dart_Invoke(lib,
+                       NewString("foozoo"),
+                       0,
+                       NULL);
+  EXPECT(Dart_IsError(result));
+}
+
+
+TEST_CASE(Dart_LoadLibraryPatch_Error2) {
+  const char* kScriptChars1 =
+      "class A {\n"
+      "  int foo() { return 10; }\n"
+      "  int zoo() { return 20; }\n"
+      "}\n"
+      "main() { new A().foo(); }\n"
+      "foozoo() { new A().zoo(); }\n";
+
+  const char* kScriptChars2 =
+      "patch class A {\n"
+      "  /* patch */ int zoo() { return 1; }\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
+  Dart_Handle result = Dart_Invoke(lib,
+                                   NewString("main"),
+                                   0,
+                                   NULL);
+  EXPECT_VALID(result);
+  Dart_Handle url = NewString("test-lib-patch");
+  Dart_Handle source = NewString(kScriptChars2);
+  // We don't expect to be able to patch in this case as a non external
+  // method is being patched.
+  result = Dart_LibraryLoadPatch(lib, url, source);
+  EXPECT_VALID(result);
+  result = Dart_FinalizeLoading(false);
+  EXPECT_VALID(result);
+  result = Dart_Invoke(lib,
+                       NewString("foozoo"),
+                       0,
+                       NULL);
+  EXPECT(Dart_IsError(result));
+  OS::Print("Patched class executed\n");
+}
+
+
+TEST_CASE(Dart_LoadLibraryPatch_Error3) {
+  const char* kScriptChars1 =
+      "class A {\n"
+      "  int foo() { return 10; }\n"
+      "  external int zoo();\n"
+      "}\n"
+      "main() { new A().foo(); }\n"
+      "foozoo() { new A().zoo(); }\n";
+
+  const char* kScriptChars2 =
+      "patch class A {\n"
+      "  /* patch */ int zoo() { return 1; }\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
+  Dart_Handle result = Dart_Invoke(lib,
+                                   NewString("main"),
+                                   0,
+                                   NULL);
+  // We invoke the foozoo method to ensure that code for 'zoo' is generated
+  // which throws NoSuchMethod.
+  result = Dart_Invoke(lib,
+                       NewString("foozoo"),
+                       0,
+                       NULL);
+  EXPECT(Dart_IsError(result));
+  Dart_Handle url = NewString("test-lib-patch");
+  Dart_Handle source = NewString(kScriptChars2);
+  // We don't expect to be able to patch in this case as the function being
+  // patched has already executed.
+  result = Dart_LibraryLoadPatch(lib, url, source);
+  EXPECT_VALID(result);
+  result = Dart_FinalizeLoading(false);
+  EXPECT_VALID(result);
+  result = Dart_Invoke(lib,
+                       NewString("foozoo"),
+                       0,
+                       NULL);
+  EXPECT(Dart_IsError(result));
+}
+
 #endif  // !PRODUCT
 
 }  // namespace dart
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index b30a331..13a9175 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1071,12 +1071,14 @@
                         Array::Handle(Array::MakeArray(param_values)));
   } else {
     const Object& receiver = Object::Handle(GetReceiver());
+    const Class& method_cls = Class::Handle(function().origin());
     ASSERT(receiver.IsInstance() || receiver.IsNull());
     if (!(receiver.IsInstance() || receiver.IsNull())) {
       return Object::null();
     }
     const Instance& inst = Instance::Cast(receiver);
-    return inst.Evaluate(expr,
+    return inst.Evaluate(method_cls,
+                         expr,
                          Array::Handle(Array::MakeArray(param_names)),
                          Array::Handle(Array::MakeArray(param_values)));
   }
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 829f0f5..f98b60a 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -568,7 +568,9 @@
                                           Array::empty_array()));
   } else if (target.IsInstance()) {
     const Instance& inst = Instance::Cast(target);
-    return Api::NewHandle(T, inst.Evaluate(expr,
+    const Class& receiver_cls = Class::Handle(Z, inst.clazz());
+    return Api::NewHandle(T, inst.Evaluate(receiver_cls,
+                                           expr,
                                            Array::empty_array(),
                                            Array::empty_array()));
   } else if (target.IsLibrary()) {
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index fffd667..ecef279 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -1183,11 +1183,11 @@
     MaterializeObjectInstr* mat = materializations_[i];
     // Class of the instance to allocate.
     AddConstant(mat->cls(), dest_index++);
-    AddConstant(Smi::Handle(Smi::New(mat->num_variables())), dest_index++);
+    AddConstant(Smi::ZoneHandle(Smi::New(mat->num_variables())), dest_index++);
     for (intptr_t i = 0; i < mat->InputCount(); i++) {
       if (!mat->InputAt(i)->BindsToConstantNull()) {
         // Emit offset-value pair.
-        AddConstant(Smi::Handle(Smi::New(mat->FieldOffsetAt(i))),
+        AddConstant(Smi::ZoneHandle(Smi::New(mat->FieldOffsetAt(i))),
                     dest_index++);
         AddCopy(mat->InputAt(i), mat->LocationAt(i), dest_index++);
       }
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index a5cadf0..8c69bc7 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -5,6 +5,7 @@
 #include "vm/flow_graph.h"
 
 #include "vm/bit_vector.h"
+#include "vm/cha.h"
 #include "vm/flow_graph_builder.h"
 #include "vm/flow_graph_compiler.h"
 #include "vm/flow_graph_range_analysis.h"
@@ -371,6 +372,92 @@
   }
 }
 
+void FlowGraph::ComputeIsReceiverRecursive(
+    PhiInstr* phi, GrowableArray<PhiInstr*>* unmark) const {
+  if (phi->is_receiver() != PhiInstr::kUnknownReceiver) return;
+  phi->set_is_receiver(PhiInstr::kReceiver);
+  for (intptr_t i = 0; i < phi->InputCount(); ++i) {
+    Definition* def = phi->InputAt(i)->definition();
+    if (def->IsParameter() && (def->AsParameter()->index() == 0)) continue;
+    if (!def->IsPhi()) {
+      phi->set_is_receiver(PhiInstr::kNotReceiver);
+      break;
+    }
+    ComputeIsReceiverRecursive(def->AsPhi(), unmark);
+    if (def->AsPhi()->is_receiver() == PhiInstr::kNotReceiver) {
+      phi->set_is_receiver(PhiInstr::kNotReceiver);
+      break;
+    }
+  }
+
+  if (phi->is_receiver() == PhiInstr::kNotReceiver) {
+    unmark->Add(phi);
+  }
+}
+
+
+void FlowGraph::ComputeIsReceiver(PhiInstr* phi) const {
+  GrowableArray<PhiInstr*> unmark;
+  ComputeIsReceiverRecursive(phi, &unmark);
+
+  // Now drain unmark.
+  while (!unmark.is_empty()) {
+    PhiInstr* phi = unmark.RemoveLast();
+    for (Value::Iterator it(phi->input_use_list()); !it.Done(); it.Advance()) {
+      PhiInstr* use = it.Current()->instruction()->AsPhi();
+      if ((use != NULL) && (use->is_receiver() == PhiInstr::kReceiver)) {
+        use->set_is_receiver(PhiInstr::kNotReceiver);
+        unmark.Add(use);
+      }
+    }
+  }
+}
+
+
+bool FlowGraph::IsReceiver(Definition* def) const {
+  if (def->IsParameter()) return (def->AsParameter()->index() == 0);
+  if (!def->IsPhi() || graph_entry()->catch_entries().is_empty()) return false;
+  PhiInstr* phi = def->AsPhi();
+  if (phi->is_receiver() != PhiInstr::kUnknownReceiver) {
+    return (phi->is_receiver() == PhiInstr::kReceiver);
+  }
+  // Not known if this phi is the receiver yet. Compute it now.
+  ComputeIsReceiver(phi);
+  return (phi->is_receiver() == PhiInstr::kReceiver);
+}
+
+
+// Use CHA to determine if the call needs a class check: if the callee's
+// receiver is the same as the caller's receiver and there are no overriden
+// callee functions, then no class check is needed.
+bool FlowGraph::InstanceCallNeedsClassCheck(InstanceCallInstr* call,
+                                            RawFunction::Kind kind) const {
+  if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) {
+    // Even if class or function are private, lazy class finalization
+    // may later add overriding methods.
+    return true;
+  }
+  Definition* callee_receiver = call->ArgumentAt(0);
+  ASSERT(callee_receiver != NULL);
+  if (function().IsDynamicFunction() && IsReceiver(callee_receiver)) {
+    const String& name = (kind == RawFunction::kMethodExtractor)
+        ? String::Handle(zone(), Field::NameFromGetter(call->function_name()))
+        : call->function_name();
+    const Class& cls = Class::Handle(zone(), function().Owner());
+    if (!thread()->cha()->HasOverride(cls, name)) {
+      if (FLAG_trace_cha) {
+        THR_Print("  **(CHA) Instance call needs no check, "
+            "no overrides of '%s' '%s'\n",
+            name.ToCString(), cls.ToCString());
+      }
+      thread()->cha()->AddToLeafClasses(cls);
+      return false;
+    }
+  }
+  return true;
+}
+
+
 
 bool FlowGraph::VerifyUseLists() {
   // Verify the initial definitions.
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index d4d9d2f..c19dc0c 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -159,6 +159,9 @@
     return current_ssa_temp_index();
   }
 
+  bool InstanceCallNeedsClassCheck(InstanceCallInstr* call,
+                                   RawFunction::Kind kind) const;
+
   Thread* thread() const { return thread_; }
   Zone* zone() const { return thread()->zone(); }
   Isolate* isolate() const { return thread()->isolate(); }
@@ -352,6 +355,11 @@
                         Value* use,
                         bool is_environment_use);
 
+  bool IsReceiver(Definition* def) const;
+  void ComputeIsReceiver(PhiInstr* phi) const;
+  void ComputeIsReceiverRecursive(PhiInstr* phi,
+                                  GrowableArray<PhiInstr*>* unmark) const;
+
   Thread* thread_;
 
   // DiscoverBlocks computes parent_ and assigned_vars_ which are then used
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 6f7ff8d..c9e02e7 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -4336,6 +4336,7 @@
   CatchBlockEntryInstr* catch_entry =
       new(Z) CatchBlockEntryInstr(owner()->AllocateBlockId(),
                                   catch_handler_index,
+                                  owner()->graph_entry(),
                                   catch_block->handler_types(),
                                   try_handler_index,
                                   catch_block->exception_var(),
@@ -4381,6 +4382,7 @@
     CatchBlockEntryInstr* finally_entry =
         new(Z) CatchBlockEntryInstr(owner()->AllocateBlockId(),
                                     original_handler_index,
+                                    owner()->graph_entry(),
                                     types,
                                     catch_handler_index,
                                     catch_block->exception_var(),
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 474bc4f..977df17 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -140,6 +140,10 @@
 
   void AddCatchEntry(CatchBlockEntryInstr* entry);
 
+  GraphEntryInstr* graph_entry() const {
+    return graph_entry_;
+  }
+
   intptr_t num_copied_params() const {
     return num_copied_params_;
   }
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 9f0da1e..3d15b4e 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -121,7 +121,7 @@
   Zone* zone = compiler->zone();
 
   builder->AddPp(current->function(), slot_ix++);
-  builder->AddPcMarker(Function::Handle(zone), slot_ix++);
+  builder->AddPcMarker(Function::ZoneHandle(zone), slot_ix++);
   builder->AddCallerFp(slot_ix++);
   builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
 
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 6750d70..034eec6 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -118,7 +118,7 @@
   Zone* zone = compiler->zone();
 
   builder->AddPp(current->function(), slot_ix++);
-  builder->AddPcMarker(Function::Handle(zone), slot_ix++);
+  builder->AddPcMarker(Function::ZoneHandle(zone), slot_ix++);
   builder->AddCallerFp(slot_ix++);
   builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
 
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index fe9696f..576aef3 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -120,7 +120,7 @@
 
   Zone* zone = compiler->zone();
 
-  builder->AddPcMarker(Function::Handle(zone), slot_ix++);
+  builder->AddPcMarker(Function::ZoneHandle(zone), slot_ix++);
   builder->AddCallerFp(slot_ix++);
   builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index c02d511..ff0ec98 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -117,7 +117,7 @@
   Zone* zone = compiler->zone();
 
   builder->AddPp(current->function(), slot_ix++);
-  builder->AddPcMarker(Function::Handle(zone), slot_ix++);
+  builder->AddPcMarker(Function::ZoneHandle(zone), slot_ix++);
   builder->AddCallerFp(slot_ix++);
   builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
 
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 7c5d7de..d9a11c4 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -118,7 +118,7 @@
   Zone* zone = compiler->zone();
 
   builder->AddPp(current->function(), slot_ix++);
-  builder->AddPcMarker(Function::Handle(zone), slot_ix++);
+  builder->AddPcMarker(Function::ZoneHandle(zone), slot_ix++);
   builder->AddCallerFp(slot_ix++);
   builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
 
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index f3d3406..c8a5f28 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -609,7 +609,9 @@
     if (constant != NULL) {
       return new(Z) ConstantInstr(constant->value());
     } else {
-      return new(Z) ParameterInstr(i, graph->graph_entry());
+      ParameterInstr* param = new(Z) ParameterInstr(i, graph->graph_entry());
+      param->UpdateType(*argument->Type());
+      return param;
     }
   }
 
@@ -637,10 +639,9 @@
       return false;
     }
 
-    // Function has no type feedback. With precompilation we don't rely on
-    // type feedback.
-    if (!FLAG_precompiled_mode &&
-        function.ic_data_array() == Object::null()) {
+    // Do not rely on function type feedback or presence of code to determine
+    // if a function was compiled.
+    if (!FLAG_precompiled_mode && !function.was_compiled()) {
       TRACE_INLINING(THR_Print("     Bailout: not compiled yet\n"));
       PRINT_INLINING_TREE("Not compiled",
           &call_data->caller, &function, call_data->call);
@@ -832,6 +833,13 @@
             DEBUG_ASSERT(callee_graph->VerifyUseLists());
           } else {
             JitOptimizer optimizer(callee_graph);
+
+            optimizer.ApplyClassIds();
+            DEBUG_ASSERT(callee_graph->VerifyUseLists());
+
+            FlowGraphTypePropagator::Propagate(callee_graph);
+            DEBUG_ASSERT(callee_graph->VerifyUseLists());
+
             optimizer.ApplyICData();
             DEBUG_ASSERT(callee_graph->VerifyUseLists());
 
@@ -1115,27 +1123,12 @@
     return parsed_function;
   }
 
-  // Include special handling for List. factory: inlining it is not helpful
-  // if the incoming argument is a non-constant value.
-  // TODO(srdjan): Fix inlining of List. factory.
   void InlineStaticCalls() {
     const GrowableArray<CallSites::StaticCallInfo>& call_info =
         inlining_call_sites_->static_calls();
     TRACE_INLINING(THR_Print("  Static Calls (%" Pd ")\n", call_info.length()));
     for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) {
       StaticCallInstr* call = call_info[call_idx].call;
-      if (call->function().name() == Symbols::ListFactory().raw()) {
-        // Inline only if no arguments or a constant was passed.
-        ASSERT(call->function().NumImplicitParameters() == 1);
-        ASSERT(call->ArgumentCount() <= 2);
-        // Arg 0: Instantiator type arguments.
-        // Arg 1: Length (optional).
-        if ((call->ArgumentCount() == 2) &&
-            (!call->PushArgumentAt(1)->value()->BindsToConstant())) {
-          // Do not inline since a non-constant argument was passed.
-          continue;
-        }
-      }
       const Function& target = call->function();
       if (!inliner_->AlwaysInline(target) &&
           (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) {
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index bd860d9..20ccd3a 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -697,12 +697,15 @@
   // However there are parameters that are known to match their declared type:
   // for example receiver.
   GraphEntryInstr* graph_entry = block_->AsGraphEntry();
-  // Parameters at catch blocks and OSR entries have type dynamic.
+  if (graph_entry == NULL) {
+    graph_entry = block_->AsCatchBlockEntry()->graph_entry();
+  }
+  // Parameters at OSR entries have type dynamic.
   //
   // TODO(kmillikin): Use the actual type of the parameter at OSR entry.
   // The code below is not safe for OSR because it doesn't necessarily use
   // the correct scope.
-  if ((graph_entry == NULL) || graph_entry->IsCompiledForOsr()) {
+  if (graph_entry->IsCompiledForOsr()) {
     return CompileType::Dynamic();
   }
 
@@ -724,12 +727,11 @@
     return CompileType::Dynamic();
   }
 
-  LocalScope* scope = graph_entry->parsed_function().node_sequence()->scope();
-  const AbstractType& type = scope->VariableAt(index())->type();
-
   // Parameter is the receiver.
   if ((index() == 0) &&
       (function.IsDynamicFunction() || function.IsGenerativeConstructor())) {
+    LocalScope* scope = graph_entry->parsed_function().node_sequence()->scope();
+    const AbstractType& type = scope->VariableAt(index())->type();
     if (type.IsObjectType() || type.IsNullType()) {
       // Receiver can be null.
       return CompileType::FromAbstractType(type, CompileType::kNullable);
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 6732c1b..287cbdc 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -196,9 +196,11 @@
   // Associate an id with an object (used when serializing an object).
   // A non-existant id is equal to 0.
   void SetObjectId(RawObject* raw_obj, intptr_t object_id) {
+    ASSERT(Thread::Current()->IsMutatorThread());
     SetWeakEntry(raw_obj, kObjectIds, object_id);
   }
   intptr_t GetObjectId(RawObject* raw_obj) const {
+    ASSERT(Thread::Current()->IsMutatorThread());
     return GetWeakEntry(raw_obj, kObjectIds);
   }
   int64_t ObjectIdCount() const;
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 59cb8ab..5b5ac04 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -133,6 +133,7 @@
       unary_checks_(unary_checks),
       cids_(unary_checks.NumberOfChecks()),
       licm_hoisted_(false),
+      is_dense_switch_(IsDenseCidRange(unary_checks)),
       token_pos_(token_pos) {
   ASSERT(unary_checks.IsZoneHandle());
   // Expected useful check data.
@@ -231,14 +232,24 @@
 }
 
 
+bool CheckClassInstr::IsDenseCidRange(const ICData& unary_checks) {
+  ASSERT(unary_checks.NumArgsTested() == 1);
+  // TODO(fschneider): Support smis in dense cid checks.
+  if (unary_checks.GetReceiverClassIdAt(0) == kSmiCid) return false;
+  if (unary_checks.NumberOfChecks() <= 2) return false;
+  intptr_t max = 0;
+  intptr_t min = kIntptrMax;
+  for (intptr_t i = 0; i < unary_checks.NumberOfChecks(); ++i) {
+    intptr_t cid = unary_checks.GetCidAt(i);
+    if (cid < min) min = cid;
+    if (cid > max) max = cid;
+  }
+  return (max - min) < kBitsPerWord;
+}
+
 
 bool CheckClassInstr::IsDenseSwitch() const {
-  if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) return false;
-  if (cids_.length() > 2 &&
-      cids_[cids_.length() - 1] - cids_[0] < kBitsPerWord) {
-    return true;
-  }
-  return false;
+  return is_dense_switch_;
 }
 
 
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 731feca..0b64cbc 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -1558,12 +1558,14 @@
  public:
   CatchBlockEntryInstr(intptr_t block_id,
                        intptr_t try_index,
+                       GraphEntryInstr* graph_entry,
                        const Array& handler_types,
                        intptr_t catch_try_index,
                        const LocalVariable& exception_var,
                        const LocalVariable& stacktrace_var,
                        bool needs_stacktrace)
       : BlockEntryInstr(block_id, try_index),
+        graph_entry_(graph_entry),
         predecessor_(NULL),
         catch_handler_types_(Array::ZoneHandle(handler_types.raw())),
         catch_try_index_(catch_try_index),
@@ -1581,6 +1583,8 @@
     return predecessor_;
   }
 
+  GraphEntryInstr* graph_entry() const { return graph_entry_; }
+
   const LocalVariable& exception_var() const { return exception_var_; }
   const LocalVariable& stacktrace_var() const { return stacktrace_var_; }
 
@@ -1606,6 +1610,7 @@
     predecessor_ = predecessor;
   }
 
+  GraphEntryInstr* graph_entry_;
   BlockEntryInstr* predecessor_;
   const Array& catch_handler_types_;
   const intptr_t catch_try_index_;
@@ -1912,10 +1917,11 @@
   PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
     : block_(block),
       inputs_(num_inputs),
-      is_alive_(false),
       representation_(kTagged),
       reaching_defs_(NULL),
-      loop_variable_info_(NULL) {
+      loop_variable_info_(NULL),
+      is_alive_(false),
+      is_receiver_(kUnknownReceiver) {
     for (intptr_t i = 0; i < num_inputs; ++i) {
       inputs_.Add(NULL);
     }
@@ -1985,6 +1991,20 @@
 
   PRINT_TO_SUPPORT
 
+  enum ReceiverType {
+    kUnknownReceiver = -1,
+    kNotReceiver = 0,
+    kReceiver = 1
+  };
+
+  ReceiverType is_receiver() const {
+    return static_cast<ReceiverType>(is_receiver_);
+  }
+
+  void set_is_receiver(ReceiverType is_receiver) {
+    is_receiver_ = is_receiver;
+  }
+
  private:
   // Direct access to inputs_ in order to resize it due to unreachable
   // predecessors.
@@ -1994,11 +2014,11 @@
 
   JoinEntryInstr* block_;
   GrowableArray<Value*> inputs_;
-  bool is_alive_;
   Representation representation_;
-
   BitVector* reaching_defs_;
   InductionVariableInfo* loop_variable_info_;
+  bool is_alive_;
+  int8_t is_receiver_;
 
   DISALLOW_COPY_AND_ASSIGN(PhiInstr);
 };
@@ -7784,6 +7804,7 @@
   bool DeoptIfNotNull() const;
 
   bool IsDenseSwitch() const;
+  static bool IsDenseCidRange(const ICData& unary_checks);
   intptr_t ComputeCidMask() const;
   static bool IsDenseMask(intptr_t mask);
 
@@ -7802,6 +7823,7 @@
   const ICData& unary_checks_;
   GrowableArray<intptr_t> cids_;  // Sorted, lowest first.
   bool licm_hoisted_;
+  bool is_dense_switch_;
   const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(CheckClassInstr);
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index a7ebef5..03b275e 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -776,7 +776,6 @@
       gc_epilogue_callback_(NULL),
       defer_finalization_count_(0),
       deopt_context_(NULL),
-      compiler_stats_(NULL),
       is_service_isolate_(false),
       stacktrace_(NULL),
       stack_frame_index_(-1),
@@ -846,10 +845,6 @@
   boxed_field_list_mutex_ = NULL;
   ASSERT(spawn_count_ == 0);
   delete spawn_count_monitor_;
-  if (compiler_stats_ != NULL) {
-    delete compiler_stats_;
-    compiler_stats_ = NULL;
-  }
   delete safepoint_handler_;
   delete thread_registry_;
 }
@@ -923,13 +918,6 @@
     }
   }
 
-  if (FLAG_support_compiler_stats) {
-    result->compiler_stats_ = new CompilerStats(result);
-    if (FLAG_compiler_benchmark) {
-      result->compiler_stats_->EnableBenchmark();
-    }
-  }
-
   if (FLAG_support_service) {
     ObjectIdRing::Init(result);
   }
@@ -1536,12 +1524,17 @@
 }
 
 
-void Isolate::Shutdown() {
-  ASSERT(this == Isolate::Current());
+void Isolate::StopBackgroundCompiler() {
   // Wait until all background compilation has finished.
   if (background_compiler_ != NULL) {
     BackgroundCompiler::Stop(background_compiler_);
   }
+}
+
+
+void Isolate::Shutdown() {
+  ASSERT(this == Isolate::Current());
+  StopBackgroundCompiler();
 
 #if defined(DEBUG)
   if (heap_ != NULL) {
@@ -1571,7 +1564,7 @@
     if (FLAG_support_compiler_stats && FLAG_compiler_stats
         && !ServiceIsolate::IsServiceIsolateDescendant(this)
         && (this != Dart::vm_isolate())) {
-      OS::Print("%s", compiler_stats()->PrintToZone());
+      OS::Print("%s", aggregate_compiler_stats()->PrintToZone());
     }
   }
 
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 58ca52c..e1564da 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -418,8 +418,10 @@
 
   void PrintJSON(JSONStream* stream, bool ref = true);
 
-  CompilerStats* compiler_stats() {
-    return compiler_stats_;
+  // Mutator thread is used to aggregate compiler stats.
+  CompilerStats* aggregate_compiler_stats() {
+    ASSERT(HasMutatorThread());
+    return mutator_thread_->compiler_stats();
   }
 
   VMTagCounters* vm_tag_counters() {
@@ -573,6 +575,8 @@
   static void DisableIsolateCreation();
   static void EnableIsolateCreation();
 
+  void StopBackgroundCompiler();
+
  private:
   friend class Dart;  // Init, InitOnce, Shutdown.
   friend class IsolateKillerVisitor;  // Kill().
@@ -671,8 +675,6 @@
   intptr_t defer_finalization_count_;
   DeoptContext* deopt_context_;
 
-  CompilerStats* compiler_stats_;
-
   bool is_service_isolate_;
 
   // Isolate-specific flags.
diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc
index edb2524..8a632f1 100644
--- a/runtime/vm/jit_optimizer.cc
+++ b/runtime/vm/jit_optimizer.cc
@@ -1283,40 +1283,6 @@
 }
 
 
-// Use CHA to determine if the call needs a class check: if the callee's
-// receiver is the same as the caller's receiver and there are no overriden
-// callee functions, then no class check is needed.
-bool JitOptimizer::InstanceCallNeedsClassCheck(
-    InstanceCallInstr* call, RawFunction::Kind kind) const {
-  if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) {
-    // Even if class or function are private, lazy class finalization
-    // may later add overriding methods.
-    return true;
-  }
-  Definition* callee_receiver = call->ArgumentAt(0);
-  ASSERT(callee_receiver != NULL);
-  const Function& function = flow_graph_->function();
-  if (function.IsDynamicFunction() &&
-      callee_receiver->IsParameter() &&
-      (callee_receiver->AsParameter()->index() == 0)) {
-    const String& name = (kind == RawFunction::kMethodExtractor)
-        ? String::Handle(Z, Field::NameFromGetter(call->function_name()))
-        : call->function_name();
-    const Class& cls = Class::Handle(Z, function.Owner());
-    if (!thread()->cha()->HasOverride(cls, name)) {
-      if (FLAG_trace_cha) {
-        THR_Print("  **(CHA) Instance call needs no check, "
-            "no overrides of '%s' '%s'\n",
-            name.ToCString(), cls.ToCString());
-      }
-      thread()->cha()->AddToLeafClasses(cls);
-      return false;
-    }
-  }
-  return true;
-}
-
-
 bool JitOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
   ASSERT(call->HasICData());
   const ICData& ic_data = *call->ic_data();
@@ -1331,7 +1297,8 @@
       Field::ZoneHandle(Z, GetField(class_ids[0], field_name));
   ASSERT(!field.IsNull());
 
-  if (InstanceCallNeedsClassCheck(call, RawFunction::kImplicitGetter)) {
+  if (flow_graph()->InstanceCallNeedsClassCheck(
+          call, RawFunction::kImplicitGetter)) {
     AddReceiverCheck(call);
   }
   LoadFieldInstr* load = new(Z) LoadFieldInstr(
@@ -2723,11 +2690,14 @@
   const ICData& unary_checks =
       ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
 
+  const bool is_dense = CheckClassInstr::IsDenseCidRange(unary_checks);
   const intptr_t max_checks = (op_kind == Token::kEQ)
       ? FLAG_max_equality_polymorphic_checks
       : FLAG_max_polymorphic_checks;
   if ((unary_checks.NumberOfChecks() > max_checks) &&
-      InstanceCallNeedsClassCheck(instr, RawFunction::kRegularFunction)) {
+      !is_dense &&
+      flow_graph()->InstanceCallNeedsClassCheck(
+          instr, RawFunction::kRegularFunction)) {
     // Too many checks, it will be megamorphic which needs unary checks.
     instr->set_ic_data(&unary_checks);
     return;
@@ -2782,7 +2752,7 @@
   if (has_one_target) {
     RawFunction::Kind function_kind =
         Function::Handle(Z, unary_checks.GetTargetAt(0)).kind();
-    if (!InstanceCallNeedsClassCheck(instr, function_kind)) {
+    if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) {
       PolymorphicInstanceCallInstr* call =
           new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
                                               /* call_with_checks = */ false);
@@ -2791,7 +2761,8 @@
     }
   }
 
-  if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
+  if ((unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) ||
+      (has_one_target && is_dense)) {
     bool call_with_checks;
     if (has_one_target && FLAG_polymorphic_with_deopt) {
       // Type propagation has not run yet, we cannot eliminate the check.
@@ -3114,7 +3085,8 @@
       Field::ZoneHandle(Z, GetField(class_id, field_name));
   ASSERT(!field.IsNull());
 
-  if (InstanceCallNeedsClassCheck(instr, RawFunction::kImplicitSetter)) {
+  if (flow_graph()->InstanceCallNeedsClassCheck(
+          instr, RawFunction::kImplicitSetter)) {
     AddReceiverCheck(instr);
   }
   if (field.guarded_cid() != kDynamicCid) {
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index a6626d0..8784651 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -381,7 +381,7 @@
         }
       }
       if (FLAG_trace_isolates) {
-        if (status != kOK && isolate() != NULL) {
+        if (status != kOK && thread() != NULL) {
           const Error& error = Error::Handle(thread()->sticky_error());
           OS::Print("[-] Stopping message handler (%s):\n"
                     "\thandler:    %s\n"
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 894452d..4f9f8d0 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2779,6 +2779,81 @@
 }
 
 
+bool Class::ValidatePostFinalizePatch(const Class& orig_class,
+                                      Error* error) const {
+  ASSERT(error != NULL);
+  // Not allowed to add new fields in a post finalization patch.
+  if (fields() != Object::empty_array().raw()) {
+    *error = LanguageError::NewFormatted(
+        *error,  // No previous error.
+        Script::Handle(script()),
+        token_pos(),
+        Report::AtLocation,
+        Report::kError,
+        Heap::kNew,
+        "new fields are not allowed for this patch");
+    return false;
+  }
+  // There seem to be no functions, the patch is pointless.
+  if (functions() == Object::empty_array().raw()) {
+    *error = LanguageError::NewFormatted(
+        *error,  // No previous error.
+        Script::Handle(script()),
+        token_pos(),
+        Report::AtLocation,
+        Report::kError,
+        Heap::kNew,
+        "no functions to patch");
+    return false;
+  }
+  // Iterate over all functions that will be patched and make sure
+  // the original function was declared 'external' and has not executed
+  // so far i.e no code has been generated for it.
+  Thread* thread = Thread::Current();
+  ASSERT(thread->IsMutatorThread());
+  Zone* zone = thread->zone();
+  const Array& funcs = Array::Handle(zone, functions());
+  Function& func = Function::Handle(zone);
+  Function& orig_func = Function::Handle(zone);
+  String& name = String::Handle(zone);
+  for (intptr_t i = 0; i < funcs.Length(); i++) {
+    func ^= funcs.At(i);
+    name ^= func.name();
+    orig_func ^= orig_class.LookupFunctionAllowPrivate(name);
+    if (!orig_func.IsNull()) {
+      if (!orig_func.is_external() || orig_func.HasCode()) {
+        // We can only patch external functions in a post finalized class.
+        *error = LanguageError::NewFormatted(
+            *error,  // No previous error.
+            Script::Handle(script()),
+            token_pos(),
+            Report::AtLocation,
+            Report::kError,
+            Heap::kNew,
+            !orig_func.is_external() ?
+            "'%s' is not external and therefore cannot be patched" :
+            "'%s' has already executed and therefore cannot be patched",
+            name.ToCString());
+        return false;
+      }
+    } else if (!Library::IsPrivate(name)) {
+      // We can only have new private functions that are added.
+      *error = LanguageError::NewFormatted(
+          *error,  // No previous error.
+          Script::Handle(script()),
+          token_pos(),
+          Report::AtLocation,
+          Report::kError,
+          Heap::kNew,
+          "'%s' is not private and therefore cannot be patched",
+          name.ToCString());
+      return false;
+    }
+  }
+  return true;
+}
+
+
 void Class::set_cha_codes(const Array& cache) const {
   StorePointer(&raw_ptr()->cha_codes_, cache.raw());
 }
@@ -3422,6 +3497,14 @@
 }
 
 
+void Class::SetRefinalizeAfterPatch() const {
+  ASSERT(!IsTopLevel());
+  set_state_bits(ClassFinalizedBits::update(RawClass::kRefinalizeAfterPatch,
+                                            raw_ptr()->state_bits_));
+  set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_));
+}
+
+
 void Class::ResetFinalization() const {
   ASSERT(IsTopLevel());
   set_state_bits(ClassFinalizedBits::update(RawClass::kAllocated,
@@ -5757,7 +5840,7 @@
 }
 
 
-void Function::set_kind_tag(intptr_t value) const {
+void Function::set_kind_tag(uint32_t value) const {
   StoreNonPointer(&raw_ptr()->kind_tag_, static_cast<uint32_t>(value));
 }
 
@@ -5832,6 +5915,7 @@
 bool Function::CanBeInlined() const {
   Thread* thread = Thread::Current();
   return is_inlinable() &&
+         !is_external() &&
          !is_generated_body() &&
          (!FLAG_support_debugger ||
           !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()));
@@ -6408,6 +6492,7 @@
   result.set_is_generated_body(false);
   result.set_always_inline(false);
   result.set_is_polymorphic_target(false);
+  result.set_was_compiled(false);
   result.set_owner(owner);
   result.set_token_pos(token_pos);
   result.set_end_token_pos(token_pos);
@@ -9351,11 +9436,15 @@
     // are not cached. This reduces the size of the the cache.
     return obj.raw();
   }
-  String& accessor_name = String::Handle(Field::GetterName(name));
-  obj = LookupLocalObject(accessor_name);
-  if (obj.IsNull()) {
-    accessor_name = Field::SetterName(name);
+  String& accessor_name = String::Handle(Field::LookupGetterSymbol(name));
+  if (!accessor_name.IsNull()) {
     obj = LookupLocalObject(accessor_name);
+  }
+  if (obj.IsNull()) {
+    accessor_name = Field::LookupSetterSymbol(name);
+    if (!accessor_name.IsNull()) {
+      obj = LookupLocalObject(accessor_name);
+    }
     if (obj.IsNull() && !ShouldBePrivate(name)) {
       obj = LookupImportedObject(name);
     }
@@ -14471,12 +14560,12 @@
 }
 
 
-RawObject* Instance::Evaluate(const String& expr,
+RawObject* Instance::Evaluate(const Class& method_cls,
+                              const String& expr,
                               const Array& param_names,
                               const Array& param_values) const {
-  const Class& cls = Class::Handle(clazz());
   const Function& eval_func =
-      Function::Handle(EvaluateHelper(cls, expr, param_names, false));
+      Function::Handle(EvaluateHelper(method_cls, expr, param_names, false));
   const Array& args = Array::Handle(Array::New(1 + param_values.Length()));
   PassiveObject& param = PassiveObject::Handle();
   args.SetAt(0, *this);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 8a818f6..9a946b0 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1265,6 +1265,12 @@
 
   void set_is_prefinalized() const;
 
+  bool is_refinalize_after_patch() const {
+    return ClassFinalizedBits::decode(raw_ptr()->state_bits_)
+        == RawClass::kRefinalizeAfterPatch;
+  }
+
+  void SetRefinalizeAfterPatch() const;
   void ResetFinalization() const;
 
   bool is_marked_for_parsing() const {
@@ -1378,6 +1384,8 @@
   bool TraceAllocation(Isolate* isolate) const;
   void SetTraceAllocation(bool trace_allocation) const;
 
+  bool ValidatePostFinalizePatch(const Class& orig_class, Error* error) const;
+
  private:
   enum MemberKind {
     kAny = 0,
@@ -2425,10 +2433,11 @@
     StoreNonPointer(&raw_ptr()->usage_counter_, value);
   }
 
-  int16_t deoptimization_counter() const {
+  int8_t deoptimization_counter() const {
     return raw_ptr()->deoptimization_counter_;
   }
-  void set_deoptimization_counter(int16_t value) const {
+  void set_deoptimization_counter(int8_t value) const {
+    ASSERT(value >= 0);
     StoreNonPointer(&raw_ptr()->deoptimization_counter_, value);
   }
 
@@ -2710,6 +2719,15 @@
 
   void set_modifier(RawFunction::AsyncModifier value) const;
 
+  // 'was_compiled' is true if the function was compiled once in this
+  // VM instantiation. It independent from presence of type feedback
+  // (ic_data_array) and code, whihc may be loaded from a snapshot.
+  void set_was_compiled(bool value) const {
+    StoreNonPointer(&raw_ptr()->was_compiled_, value ? 1 : 0);
+  }
+  bool was_compiled() const { return raw_ptr()->was_compiled_ == 1; }
+
+
   // static: Considered during class-side or top-level resolution rather than
   //         instance-side resolution.
   // const: Valid target of a const constructor call.
@@ -2816,7 +2834,7 @@
   RawScript* eval_script() const;
   void set_eval_script(const Script& value) const;
   void set_num_optional_parameters(intptr_t value) const;  // Encoded value.
-  void set_kind_tag(intptr_t value) const;
+  void set_kind_tag(uint32_t value) const;
   void set_data(const Object& value) const;
 
   static RawFunction* New();
@@ -5182,7 +5200,8 @@
   // error object if evaluating the expression fails. The method has
   // the formal parameters given in param_names, and is invoked with
   // the argument values given in param_values.
-  RawObject* Evaluate(const String& expr,
+  RawObject* Evaluate(const Class& method_cls,
+                      const String& expr,
                       const Array& param_names,
                       const Array& param_values) const;
 
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index d93391f..90f9e1d 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -1542,6 +1542,12 @@
   jsobj.AddProperty("_externalOneByteFunction", func);
   func = function(kExternalTwoByteStringCid);
   jsobj.AddProperty("_externalTwoByteFunction", func);
+
+  TypedData& bc = TypedData::Handle();
+  bc = bytecode(true);
+  jsobj.AddProperty("_oneByteBytecode", bc);
+  bc = bytecode(false);
+  jsobj.AddProperty("_twoByteBytecode", bc);
 }
 
 
diff --git a/runtime/vm/os_thread.cc b/runtime/vm/os_thread.cc
index b381692..947b7f6 100644
--- a/runtime/vm/os_thread.cc
+++ b/runtime/vm/os_thread.cc
@@ -63,6 +63,18 @@
 }
 
 
+
+void OSThread::SetName(const char* name) {
+  MutexLocker ml(thread_list_lock_);
+  // Clear the old thread name.
+  if (name_ != NULL) {
+    free(name_);
+    name_ = NULL;
+  }
+  set_name(name);
+}
+
+
 void OSThread::DisableThreadInterrupts() {
   ASSERT(OSThread::Current() == this);
   AtomicOperations::FetchAndIncrement(&thread_interrupt_disabled_);
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index 976a137..e0b41ac 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -75,6 +75,8 @@
     return name_;
   }
 
+  void SetName(const char* name);
+
   void set_name(const char* name) {
     ASSERT(OSThread::Current() == this);
     ASSERT(name_ == NULL);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 3e89bad..5691522 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -4565,8 +4565,11 @@
     cls.set_is_patch();
     // Apply the changes to the patched class looked up above.
     ASSERT(obj.raw() == library_.LookupLocalObject(class_name));
-    // The patched class must not be finalized yet.
-    ASSERT(!Class::Cast(obj).is_finalized());
+    const Class& orig_class = Class::Cast(obj);
+    if (orig_class.is_finalized()) {
+      orig_class.SetRefinalizeAfterPatch();
+      pending_classes.Add(orig_class, Heap::kOld);
+    }
     library_.AddPatchClass(cls);
   }
   pending_classes.Add(cls, Heap::kOld);
@@ -4634,6 +4637,14 @@
     const Class& orig_class = Class::Cast(obj);
     ASSERT(!orig_class.is_finalized());
     Error& error = Error::Handle(Z);
+    // Check if this is a case of patching a class after it has already
+    // been finalized.
+    if (orig_class.is_refinalize_after_patch()) {
+      if (!cls.ValidatePostFinalizePatch(orig_class, &error)) {
+        Report::LongJumpF(error, script_, class_pos,
+                          "patch validation failed, not applying patch.\n");
+      }
+    }
     if (!orig_class.ApplyPatch(cls, &error)) {
       Report::LongJumpF(error, script_, class_pos, "applying patch failed");
     }
@@ -12019,7 +12030,7 @@
   ConstantsMap constants(isolate()->object_store()->compile_time_constants());
   constants.InsertNewOrGetValue(key, value);
   if (FLAG_compiler_stats) {
-    isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied();
+    thread_->compiler_stats()->num_cached_consts = constants.NumOccupied();
   }
   isolate()->object_store()->set_compile_time_constants(constants.Release());
 }
@@ -12038,7 +12049,7 @@
   // do not assert that 'compile_time_constants' has not changed.
   constants.Release();
   if (FLAG_compiler_stats && is_present) {
-    isolate_->compiler_stats()->num_const_cache_hits++;
+    thread_->compiler_stats()->num_const_cache_hits++;
   }
   return is_present;
 }
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index e1b28fe..6d63bc1 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -1109,6 +1109,7 @@
 
 TEST_CASE(Profiler_StringInterpolation) {
   DisableNativeProfileScope dnps;
+  DisableBackgroundCompilationScope dbcs;
   const char* kScript = "String foo(String a, String b) => '$a | $b';";
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 7c90991..323fed4 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -677,6 +677,7 @@
     kAllocated = 0,  // Initial state.
     kPreFinalized,  // VM classes: size precomputed, but no checks done.
     kFinalized,  // Class parsed, finalized and ready for use.
+    kRefinalizeAfterPatch,  // Class needs to be refinalized (patched).
   };
 
  private:
@@ -851,7 +852,8 @@
   int32_t usage_counter_;  // Incremented while function is running.
   int16_t num_fixed_parameters_;
   int16_t num_optional_parameters_;  // > 0: positional; < 0: named.
-  int16_t deoptimization_counter_;
+  int8_t deoptimization_counter_;
+  int8_t was_compiled_;
   uint32_t kind_tag_;  // See Function::KindTagBits.
   uint16_t optimized_instruction_count_;
   uint16_t optimized_call_site_count_;
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 7c861e2..e8fcf69 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -733,10 +733,11 @@
       func.set_optimized_call_site_count(0);
     } else {
       func.set_usage_counter(reader->Read<int32_t>());
-      func.set_deoptimization_counter(reader->Read<int16_t>());
+      func.set_deoptimization_counter(reader->Read<int8_t>());
       func.set_optimized_instruction_count(reader->Read<uint16_t>());
       func.set_optimized_call_site_count(reader->Read<uint16_t>());
     }
+    func.set_was_compiled(false);
 
     // Set all the object fields.
     READ_OBJECT_FIELDS(func,
@@ -814,7 +815,7 @@
       } else {
         writer->Write<int32_t>(0);
       }
-      writer->Write<int16_t>(ptr()->deoptimization_counter_);
+      writer->Write<int8_t>(ptr()->deoptimization_counter_);
       writer->Write<uint16_t>(ptr()->optimized_instruction_count_);
       writer->Write<uint16_t>(ptr()->optimized_call_site_count_);
     }
diff --git a/runtime/vm/report.cc b/runtime/vm/report.cc
index 21bbdc8..01b7a86 100644
--- a/runtime/vm/report.cc
+++ b/runtime/vm/report.cc
@@ -118,7 +118,7 @@
                        const char* format, va_list args) {
   const Error& error = Error::Handle(LanguageError::NewFormattedV(
       prev_error, script, token_pos, Report::AtLocation,
-      kError, Heap::kNew,
+      kError, Heap::kOld,
       format, args));
   LongJump(error);
   UNREACHABLE();
@@ -159,7 +159,7 @@
   const Error& error = Error::Handle(
       LanguageError::NewFormattedV(Error::Handle(),  // No previous error.
                                    script, token_pos, report_after_token,
-                                   kind, Heap::kNew,
+                                   kind, Heap::kOld,
                                    format, args));
   LongJump(error);
   UNREACHABLE();
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 0caeb9c..62048e0 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2150,8 +2150,10 @@
     // We don't use Instance::Cast here because it doesn't allow null.
     Instance& instance = Instance::Handle(zone);
     instance ^= obj.raw();
+    const Class& receiver_cls = Class::Handle(zone, instance.clazz());
     const Object& result =
-        Object::Handle(zone, instance.Evaluate(expr_str,
+        Object::Handle(zone, instance.Evaluate(receiver_cls,
+                                               expr_str,
                                                Array::empty_array(),
                                                Array::empty_array()));
     result.PrintJSON(js, true);
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index a75c2fd..cb14557 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -339,11 +339,17 @@
       return;
     }
 
+    bool got_unwind;
     {
       ASSERT(Isolate::Current() == NULL);
       StartIsolateScope start_scope(isolate);
       ServiceIsolate::ConstructExitMessageAndCache(isolate);
-      RunMain(isolate);
+      got_unwind = RunMain(isolate);
+    }
+
+    if (got_unwind) {
+      ShutdownIsolate(reinterpret_cast<uword>(isolate));
+      return;
     }
 
     ServiceIsolate::FinishedInitializing();
@@ -385,7 +391,7 @@
     ServiceIsolate::FinishedExiting();
   }
 
-  void RunMain(Isolate* I) {
+  bool RunMain(Isolate* I) {
     Thread* T = Thread::Current();
     ASSERT(I == T->isolate());
     StackZone zone(T);
@@ -398,7 +404,7 @@
         OS::Print("vm-service: Embedder did not install a script.");
       }
       // Service isolate is not supported by embedder.
-      return;
+      return false;
     }
     ASSERT(!root_library.IsNull());
     const String& entry_name = String::Handle(Z, String::New("main"));
@@ -410,7 +416,7 @@
       if (FLAG_trace_service) {
         OS::Print("vm-service: Embedder did not provide a main function.");
       }
-      return;
+      return false;
     }
     ASSERT(!entry.IsNull());
     const Object& result = Object::Handle(Z,
@@ -423,11 +429,15 @@
         OS::Print("vm-service: Calling main resulted in an error: %s",
                   error.ToErrorCString());
       }
-      return;
+      if (result.IsUnwindError()) {
+        return true;
+      }
+      return false;
     }
     ASSERT(result.IsReceivePort());
     const ReceivePort& rp = ReceivePort::Cast(result);
     ServiceIsolate::SetLoadPort(rp.Id());
+    return false;
   }
 };
 
@@ -462,7 +472,19 @@
 
 
 void ServiceIsolate::Shutdown() {
-  if (!IsRunning()) {
+  if (IsRunning()) {
+    {
+      MonitorLocker ml(monitor_);
+      shutting_down_ = true;
+    }
+    SendServiceExitMessage();
+    {
+      MonitorLocker ml(monitor_);
+      while (shutting_down_ && (port_ != ILLEGAL_PORT)) {
+        ml.Wait();
+      }
+    }
+  } else {
     if (isolate_ != NULL) {
       // TODO(johnmccutchan,turnidge) When it is possible to properly create
       // the VMService object and set up its shutdown handler in the service
@@ -470,18 +492,6 @@
       // can be removed.
       KillServiceIsolate();
     }
-    return;
-  }
-  {
-    MonitorLocker ml(monitor_);
-    shutting_down_ = true;
-  }
-  SendServiceExitMessage();
-  {
-    MonitorLocker ml(monitor_);
-    while (shutting_down_ && (port_ != ILLEGAL_PORT)) {
-      ml.Wait();
-    }
   }
   if (server_address_ != NULL) {
     free(server_address_);
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 8d1fdcf..f7a880d 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -1936,6 +1936,8 @@
 
 FullSnapshotWriter::~FullSnapshotWriter() {
   delete forward_list_;
+  // We may run Dart code afterwards, restore the symbol table.
+  isolate()->object_store()->set_symbol_table(symbol_table_);
   symbol_table_ = Array::null();
   scripts_ = Array::null();
 }
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 9b36cd4..5775145 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -4,6 +4,7 @@
 
 #include "vm/thread.h"
 
+#include "vm/compiler_stats.h"
 #include "vm/dart_api_state.h"
 #include "vm/growable_array.h"
 #include "vm/isolate.h"
@@ -30,6 +31,10 @@
 Thread::~Thread() {
   // We should cleanly exit any isolate before destruction.
   ASSERT(isolate_ == NULL);
+  if (compiler_stats_ != NULL) {
+    delete compiler_stats_;
+    compiler_stats_ = NULL;
+  }
   // There should be no top api scopes at this point.
   ASSERT(api_top_scope() == NULL);
   // Delete the resusable api scope if there is one.
@@ -85,6 +90,7 @@
       deopt_id_(0),
       pending_functions_(GrowableObjectArray::null()),
       sticky_error_(Error::null()),
+      compiler_stats_(NULL),
       REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
       REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
       safepoint_state_(0),
@@ -110,6 +116,13 @@
   if ((Dart::vm_isolate() != NULL) && (isolate != Dart::vm_isolate())) {
     InitVMConstants();
   }
+
+  if (FLAG_support_compiler_stats) {
+    compiler_stats_ = new CompilerStats(isolate);
+    if (FLAG_compiler_benchmark) {
+      compiler_stats_->EnableBenchmark();
+    }
+  }
 }
 
 
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 31313d6..8e126f5 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -23,6 +23,7 @@
 class CHA;
 class Class;
 class Code;
+class CompilerStats;
 class Error;
 class ExceptionHandlers;
 class Field;
@@ -443,6 +444,8 @@
   void set_sticky_error(const Error& value);
   void clear_sticky_error();
 
+  CompilerStats* compiler_stats() { return compiler_stats_; }
+
 #if defined(DEBUG)
 #define REUSABLE_HANDLE_SCOPE_ACCESSORS(object)                                \
   void set_reusable_##object##_handle_scope_active(bool value) {               \
@@ -651,6 +654,8 @@
 
   RawError* sticky_error_;
 
+  CompilerStats* compiler_stats_;
+
   // Reusable handles support.
 #define REUSABLE_HANDLE_FIELDS(object)                                         \
   object* object##_handle_;
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 959b9ad..68e0784 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -379,6 +379,18 @@
 }
 
 
+void TimelineEvent::Counter(const char* label, int64_t micros) {
+  Init(kCounter, label);
+  set_timestamp0(micros);
+}
+
+
+void TimelineEvent::Metadata(const char* label, int64_t micros) {
+  Init(kMetadata, label);
+  set_timestamp0(micros);
+}
+
+
 void TimelineEvent::CompleteWithPreSerializedJSON(const char* json) {
   set_pre_serialized_json(true);
   SetNumArguments(1);
@@ -577,6 +589,14 @@
       obj.AddPropertyF("id", "%" Px64 "", AsyncId());
     }
     break;
+    case kMetadata: {
+      obj.AddProperty("ph", "M");
+    }
+    break;
+    case kCounter: {
+      obj.AddProperty("ph", "C");
+    }
+    break;
     default:
       UNIMPLEMENTED();
   }
@@ -1156,6 +1176,7 @@
     return;
   }
   JSONArray events(js);
+  PrintJSONMeta(&events);
   PrintJSONEvents(&events, filter);
 }
 
@@ -1301,6 +1322,7 @@
     return;
   }
   JSONArray events(js);
+  PrintJSONMeta(&events);
   PrintJSONEvents(&events, filter);
 }
 
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 0e0cf73..9196ee0 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -128,6 +128,8 @@
     kAsyncBegin,
     kAsyncInstant,
     kAsyncEnd,
+    kCounter,
+    kMetadata,
     kNumEventTypes,
   };
 
@@ -169,6 +171,12 @@
   void End(const char* label,
            int64_t micros = OS::GetCurrentMonotonicMicros());
 
+  void Counter(const char* label,
+               int64_t micros = OS::GetCurrentMonotonicMicros());
+
+  void Metadata(const char* label,
+                int64_t micros = OS::GetCurrentMonotonicMicros());
+
   // Completes this event with pre-serialized JSON. Copies |json|.
   void CompleteWithPreSerializedJSON(const char* json);
 
diff --git a/runtime/vm/timer.h b/runtime/vm/timer.h
index f3b15fa..01a6b6f 100644
--- a/runtime/vm/timer.h
+++ b/runtime/vm/timer.h
@@ -7,6 +7,7 @@
 
 #include "platform/utils.h"
 #include "vm/allocation.h"
+#include "vm/atomic.h"
 #include "vm/flags.h"
 #include "vm/os.h"
 
@@ -34,7 +35,8 @@
     stop_ = OS::GetCurrentTimeMicros();
     int64_t elapsed = ElapsedMicros();
     max_contiguous_ = Utils::Maximum(max_contiguous_, elapsed);
-    total_ += elapsed;
+    // Make increment atomic in case it occurs in parallel with aggregation.
+    AtomicOperations::IncrementInt64By(&total_, elapsed);
     running_ = false;
   }
 
@@ -65,6 +67,15 @@
     running_ = false;
   }
 
+  bool IsReset() const {
+    return (start_ == 0) && (stop_ == 0) && (total_ == 0) &&
+        (max_contiguous_ == 0) && !running_;
+  }
+
+  void AddTotal(const Timer& other) {
+    AtomicOperations::IncrementInt64By(&total_, other.total_);
+  }
+
   // Accessors.
   bool report() const { return report_; }
   bool running() const { return running_; }
diff --git a/sdk/lib/_blink/dartium/_blink_dartium.dart b/sdk/lib/_blink/dartium/_blink_dartium.dart
index 4e302c9..609fd88 100644
--- a/sdk/lib/_blink/dartium/_blink_dartium.dart
+++ b/sdk/lib/_blink/dartium/_blink_dartium.dart
@@ -10143,9 +10143,9 @@
 
   ancestorOrigins_Getter_(mthis) => Blink_JsNative_DomException.getProperty(mthis /* Location */, "ancestorOrigins");
 
-  hash_Getter_(mthis) => Blink_JsNative_DomException.getProperty(mthis /* Location */, "hash");
+  hash_Getter_(mthis) native "Blink_Getter_Location_hash";
 
-  hash_Setter_(mthis, __arg_0) => Blink_JsNative_DomException.setProperty(mthis /* Location */, "hash", __arg_0);
+  hash_Setter_(mthis, __arg_0) native "Blink_Setter_Location_hash";
 
   host_Getter_(mthis) => Blink_JsNative_DomException.getProperty(mthis /* Location */, "host");
 
@@ -23301,6 +23301,7 @@
   // In any case, returns a typed JS wrapper compatibile with dart:html and the new
   // typed JS Interop.
   static defineInterceptorCustomElement(jsObject, Type type) native "Utils_defineInterceptorCustomElement";
+  static defineInterceptor(jsObject, Type type) native "Utils_defineInterceptor";
   static setInstanceInterceptor(o, Type type, {bool customElement: false}) native "Utils_setInstanceInterceptor";
 
   // This method will throw if the element isn't actually a real Element.
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 89565e1..87fc341 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -259,13 +259,13 @@
    *         _outputSink.add(data);
    *       }
    *
-   *       void addError(e, [st]) => _outputSink(e, st);
+   *       void addError(e, [st]) => _outputSink.addError(e, st);
    *       void close() => _outputSink.close();
    *     }
    *
    *     class DuplicationTransformer implements StreamTransformer<String, String> {
    *       // Some generic types ommitted for brevety.
-   *       Stream bind(Stream stream) => new Stream<String>.eventTransform(
+   *       Stream bind(Stream stream) => new Stream<String>.eventTransformed(
    *           stream,
    *           (EventSink sink) => new DuplicationSink(sink));
    *     }
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index b54fc76..b9db444 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -20088,6 +20088,10 @@
    */
   void registerElement(String tag, Type customElementClass,
       {String extendsTag}) {
+    // Hack to setup an interceptor for HTMLElement so it isn't changed when a custom element is created.
+    var jsHTMLElementPrototype = js.JsNative.getProperty(js.JsNative.getProperty(js.context, 'HTMLElement'),'prototype');
+    _blink.Blink_Utils.defineInterceptor(jsHTMLElementPrototype, HtmlElement.instanceRuntimeType);
+
     // Figure out which DOM class is being extended from the user's Dart class.
     var classMirror = reflectClass(customElementClass);
 
diff --git a/sdk/lib/io/security_context.dart b/sdk/lib/io/security_context.dart
index 1e169af..1909571 100644
--- a/sdk/lib/io/security_context.dart
+++ b/sdk/lib/io/security_context.dart
@@ -14,6 +14,10 @@
  *
  * Certificates and keys can be added to a SecurityContext from either PEM
  * or PKCS12 containers.
+ *
+ * iOS note: Some methods to add, remove, and inspect certificates are not yet
+ * implemented. However, the platform's built-in trusted certificates can
+ * be used, by way of [SecurityContext.defaultContext].
  */
 abstract class SecurityContext {
   external factory SecurityContext();
@@ -24,8 +28,10 @@
    * This object can also be accessed, and modified, directly.
    * Each isolate has a different [defaultContext] object.
    * The [defaultContext] object uses a list of well-known trusted
-   * certificate authorities as its trusted roots.  This list is
-   * taken from Mozilla, who maintains it as part of Firefox.
+   * certificate authorities as its trusted roots. On Linux and Windows, this
+   * list is taken from Mozilla, who maintains it as part of Firefox. On,
+   * MacOS, iOS, and Android, this list comes from the trusted certificates
+   * stores built in to the platforms.
    */
   external static SecurityContext get defaultContext;
 
@@ -41,6 +47,8 @@
    *
    * NB: This function calls [ReadFileAsBytesSync], and will block on file IO.
    * Prefer using [usePrivateKeyBytes].
+   *
+   * iOS note: Not yet implemented.
    */
   void usePrivateKey(String file, {String password});
 
@@ -49,6 +57,8 @@
    *
    * Like [usePrivateKey], but takes the contents of the file as a list
    * of bytes.
+   *
+   * iOS note: Not yet implemented.
    */
   void usePrivateKeyBytes(List<int> keyBytes, {String password});
 
@@ -72,6 +82,13 @@
    * client connections, when connecting to a secure server.
    *
    * Like [setTrustedCertificates] but takes the contents of the file.
+   *
+   * iOS note: On iOS, this call takes only the bytes for a single DER
+   * encoded X509 certificate. It may be called multiple times to add
+   * multiple trusted certificates to the context. A DER encoded certificate
+   * can be obtained from a PEM encoded certificate by using the openssl tool:
+   *
+   *   $ openssl x509 -outform der -in cert.pem -out cert.der
    */
   void setTrustedCertificatesBytes(List<int> certBytes, {String password});
 
@@ -89,6 +106,8 @@
    *
    * NB: This function calls [ReadFileAsBytesSync], and will block on file IO.
    * Prefer using [useCertificateChainBytes].
+   *
+   * iOS note: Not yet implemented.
    */
   void useCertificateChain(String file, {String password});
 
@@ -97,6 +116,8 @@
    * when making secure connections, including the server certificate.
    *
    * Like [useCertificateChain] but takes the contents of the file.
+   *
+   * iOS note: Not yet implemented.
    */
   void useCertificateChainBytes(List<int> chainBytes, {String password});
 
@@ -113,6 +134,8 @@
    *
    * NB: This function calls [ReadFileAsBytesSync], and will block on file IO.
    * Prefer using [setClientAuthoritiesBytes].
+   *
+   * iOS note: Not yet implemented.
    */
   void setClientAuthorities(String file, {String password});
 
@@ -122,6 +145,8 @@
    * client.
    *
    * Like [setClientAuthority] but takes the contents of the file.
+   *
+   * iOS note: Not yet implemented.
    */
   void setClientAuthoritiesBytes(List<int> authCertBytes, {String password});
 
diff --git a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
index 71f2dbb..4a83a42 100644
--- a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
+++ b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
@@ -3006,7 +3006,7 @@
   @Deprecated("Use texImage2D")
   void texImage2DUntyped(int targetTexture, int levelOfDetail,
       int internalFormat, int format, int type, data) {
-    texImage2D(targetText, levelOfDetail, internalFormat, format, type, data);
+    texImage2D(targetTexture, levelOfDetail, internalFormat, format, type, data);
   }
 
   /**
@@ -3051,17 +3051,15 @@
    */
   @Deprecated("Use bufferData")
   void bufferDataTyped(int target, TypedData data, int usage) {
-    bufferData2D(targetTexture, levelOfDetail, xOffset, yOffset,
-        format, type, data);
+    bufferData(target, data, usage);
   }
 
   /**
    * Set the bufferSubData to [data].
    */
   @Deprecated("Use bufferSubData")
-  void bufferSubDataTyped(int target, TypedData data, int usage) {
-    bufferSubData2D(targetTexture, levelOfDetail, xOffset, yOffset,
-        format, type, data);
+  void bufferSubDataTyped(int target, int offset, TypedData data) {
+    bufferSubData(target, offset, data);
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
diff --git a/sdk/lib/web_gl/dartium/web_gl_dartium.dart b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
index 31ad9e4..a82b5f6 100644
--- a/sdk/lib/web_gl/dartium/web_gl_dartium.dart
+++ b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
@@ -3379,7 +3379,7 @@
   @Deprecated("Use texImage2D")
   void texImage2DUntyped(int targetTexture, int levelOfDetail,
       int internalFormat, int format, int type, data) {
-    texImage2D(targetText, levelOfDetail, internalFormat, format, type, data);
+    texImage2D(targetTexture, levelOfDetail, internalFormat, format, type, data);
   }
 
   /**
@@ -3424,17 +3424,15 @@
    */
   @Deprecated("Use bufferData")
   void bufferDataTyped(int target, TypedData data, int usage) {
-    bufferData2D(targetTexture, levelOfDetail, xOffset, yOffset,
-        format, type, data);
+    bufferData(target, data, usage);
   }
 
   /**
    * Set the bufferSubData to [data].
    */
   @Deprecated("Use bufferSubData")
-  void bufferSubDataTyped(int target, TypedData data, int usage) {
-    bufferSubData2D(targetTexture, levelOfDetail, xOffset, yOffset,
-        format, type, data);
+  void bufferSubDataTyped(int target, int offset, TypedData data) {
+    bufferSubData(target, offset, data);
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index c550a6f..3fe27f7 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -203,6 +203,7 @@
 Language/Libraries_and_Scripts/URIs/syntax_t10: RuntimeError # Please triage this failure.
 Language/Libraries_and_Scripts/URIs/syntax_t14: RuntimeError # Please triage this failure.
 Language/Libraries_and_Scripts/URIs/syntax_t15: RuntimeError # Please triage this failure.
+Language/Metadata/before_param_t09: RuntimeError # Issue 26187
 Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure.
 Language/Mixins/Mixin_Application/error_t01: Fail # co19 issue 43
 Language/Mixins/Mixin_Application/error_t02: Fail # co19 issue 43
@@ -1353,14 +1354,6 @@
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-event-interface/event-path-001_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/32
 WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-002_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/33
 # Must fix failures below after JsInterop checkin.
-WebPlatformTest/custom-elements/instantiating/createElement_A02_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t02: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/createElementNS_A04_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/createElementNS_A03_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/createElement_A03_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: RuntimeError # Issue 26134
 WebPlatformTest/dom/nodes/Node-appendChild_t01: RuntimeError # Issue 26134
 WebPlatformTest/dom/nodes/attributes/setAttribute_A01_t01: RuntimeError # Issue 26134
 LayoutTests/fast/dom/Document/createElement-invalid-names_t01: RuntimeError # Issue 26134
@@ -1370,7 +1363,6 @@
 LayoutTests/fast/dom/HTMLTemplateElement/cycles_t01: RuntimeError # Issue 26134
 LayoutTests/fast/dom/computed-style-set-property_t01: RuntimeError # Issue 26134
 LayoutTests/fast/dom/custom/element-type_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/custom/type-extensions_t01: RuntimeError # Issue 26134
 LayoutTests/fast/dom/custom/element-upgrade_t01: RuntimeError # Issue 26134
 LayoutTests/fast/dom/custom/document-register-type-extensions_t01: RuntimeError # Issue 26134
 LayoutTests/fast/dom/custom/document-register-namespace_t01: RuntimeError # Issue 26134
diff --git a/tests/compiler/dart2js/analyze_api_test.dart b/tests/compiler/dart2js/analyze_api_test.dart
index e121190..908ae11 100644
--- a/tests/compiler/dart2js/analyze_api_test.dart
+++ b/tests/compiler/dart2js/analyze_api_test.dart
@@ -19,9 +19,6 @@
  */
 // TODO(johnniwinther): Support canonical URIs as keys.
 const Map<String, List<String>> WHITE_LIST = const {
-  'sdk/lib/web_gl/dart2js/web_gl_dart2js.dart': const [
-    "is not defined for the class 'RenderingContext'", // Issue 26111
-  ],
 };
 
 void main() {
diff --git a/tests/compiler/dart2js/analyze_helper.dart b/tests/compiler/dart2js/analyze_helper.dart
index 70a1f22..61b52be 100644
--- a/tests/compiler/dart2js/analyze_helper.dart
+++ b/tests/compiler/dart2js/analyze_helper.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -7,13 +7,14 @@
 import 'dart:async';
 import 'dart:io';
 import 'package:compiler/compiler.dart' as api;
-import 'package:compiler/compiler_new.dart' as new_api;
 import 'package:compiler/src/apiimpl.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/diagnostics/messages.dart' show
     Message,
     MessageKind;
 import 'package:compiler/src/filenames.dart';
+import 'package:compiler/src/options.dart' show
+    CompilerOptions;
 import 'package:compiler/src/source_file_provider.dart';
 import 'package:compiler/src/util/uri_extras.dart';
 
@@ -226,7 +227,7 @@
       provider,
       null,
       handler,
-      new new_api.CompilerOptions.parse(
+      new CompilerOptions.parse(
           libraryRoot: libraryRoot,
           packageRoot: packageRoot,
           options: options,
diff --git a/tests/compiler/dart2js/backend_dart/dart_printer_test.dart b/tests/compiler/dart2js/backend_dart/dart_printer_test.dart
index 88eabca..e3c52bc 100644
--- a/tests/compiler/dart2js/backend_dart/dart_printer_test.dart
+++ b/tests/compiler/dart2js/backend_dart/dart_printer_test.dart
@@ -22,6 +22,7 @@
 import 'package:compiler/src/string_validator.dart';
 import 'package:compiler/src/tree/tree.dart' show DartString;
 import 'package:compiler/src/tree/tree.dart' as tree;
+import '../options_helper.dart';
 
 /// For debugging the [AstBuilder] stack. Prints information about [x].
 void show(x) {
@@ -673,7 +674,7 @@
   Scanner scan = new Scanner(file);
   Token tok = scan.tokenize();
   AstBuilder builder = new AstBuilder();
-  Parser parser = new Parser(builder);
+  Parser parser = new Parser(builder, new MockParserOptions());
   tok = parser.parseExpression(tok);
   if (builder.stack.length != 1 || tok.kind != EOF_TOKEN) {
     throw "Parse error in $code";
@@ -685,7 +686,7 @@
   Scanner scan = new Scanner(file);
   Token tok = scan.tokenize();
   AstBuilder builder = new AstBuilder();
-  Parser parser = new Parser(builder);
+  Parser parser = new Parser(builder, new MockParserOptions());
   tok = parser.parseStatement(tok);
   if (builder.stack.length != 1 || tok.kind != EOF_TOKEN) {
     throw "Parse error in $code";
diff --git a/tests/compiler/dart2js/bad_loop_test.dart b/tests/compiler/dart2js/bad_loop_test.dart
index 525aa8c..bc6d43d 100644
--- a/tests/compiler/dart2js/bad_loop_test.dart
+++ b/tests/compiler/dart2js/bad_loop_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -8,7 +8,7 @@
 
 import 'package:compiler/compiler.dart'
        show Diagnostic;
-import 'package:compiler/compiler_new.dart' show CompilerOptions;
+import 'package:compiler/src/options.dart' show CompilerOptions;
 import 'package:compiler/src/old_to_new_api.dart';
 
 main() {
diff --git a/tests/compiler/dart2js/codegen_helper.dart b/tests/compiler/dart2js/codegen_helper.dart
index 1e1dec8..cd45136 100644
--- a/tests/compiler/dart2js/codegen_helper.dart
+++ b/tests/compiler/dart2js/codegen_helper.dart
@@ -1,10 +1,10 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
 import 'package:expect/expect.dart';
-import 'package:compiler/compiler_new.dart' show CompilerOptions;
+import 'package:compiler/src/options.dart' show CompilerOptions;
 import 'package:compiler/src/null_compiler_output.dart';
 import 'memory_source_file_helper.dart';
 
diff --git a/tests/compiler/dart2js/diagnostic_reporter_helper.dart b/tests/compiler/dart2js/diagnostic_reporter_helper.dart
index 0bff795..afc199d 100644
--- a/tests/compiler/dart2js/diagnostic_reporter_helper.dart
+++ b/tests/compiler/dart2js/diagnostic_reporter_helper.dart
@@ -9,6 +9,7 @@
 import 'package:compiler/src/diagnostics/spannable.dart';
 import 'package:compiler/src/diagnostics/source_span.dart';
 import 'package:compiler/src/elements/elements.dart';
+import 'options_helper.dart';
 
 abstract class DiagnosticReporterWrapper extends DiagnosticReporter {
   DiagnosticReporter get reporter;
diff --git a/tests/compiler/dart2js/exit_code_test.dart b/tests/compiler/dart2js/exit_code_test.dart
index 11a04b1..2bbde2b 100644
--- a/tests/compiler/dart2js/exit_code_test.dart
+++ b/tests/compiler/dart2js/exit_code_test.dart
@@ -27,6 +27,7 @@
 import 'package:compiler/src/library_loader.dart';
 import 'package:compiler/src/null_compiler_output.dart';
 import 'package:compiler/src/old_to_new_api.dart';
+import 'package:compiler/src/options.dart' show CompilerOptions;
 import 'package:compiler/src/resolution/resolution.dart';
 import 'package:compiler/src/scanner/scanner_task.dart';
 import 'package:compiler/src/universe/world_impact.dart';
@@ -51,7 +52,7 @@
                String this.testType,
                Function this.onTest)
       : super(inputProvider, outputProvider, handler,
-            new api.CompilerOptions.parse(
+            new CompilerOptions.parse(
                 libraryRoot: libraryRoot,
                 packageRoot: packageRoot,
                 options: options,
diff --git a/tests/compiler/dart2js/library_env_test.dart b/tests/compiler/dart2js/library_env_test.dart
index 7f377cf..d162b72 100644
--- a/tests/compiler/dart2js/library_env_test.dart
+++ b/tests/compiler/dart2js/library_env_test.dart
@@ -1,14 +1,10 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 /// Check that 'dart:' libraries have their corresponding dart.library.X
 /// environment variable set.
 
-import "dart:io";
-
-import "dart:async";
-
 import "memory_source_file_helper.dart";
 
 import "package:async_helper/async_helper.dart";
@@ -16,19 +12,15 @@
 import 'package:expect/expect.dart' show
     Expect;
 
-import 'package:compiler/src/elements/elements.dart' show
-    LibraryElement;
-
 import 'package:compiler/src/null_compiler_output.dart' show
     NullCompilerOutput;
 
-import 'package:compiler/compiler_new.dart' show
-    CompilerInput,
-    CompilerDiagnostics,
+import 'package:compiler/src/options.dart' show
     CompilerOptions;
 
-import 'package:sdk_library_metadata/libraries.dart' show
-    LibraryInfo;
+import 'package:compiler/compiler_new.dart' show
+    CompilerInput,
+    CompilerDiagnostics;
 
 const clientPlatform = r'''
 [dart-spec]
diff --git a/tests/compiler/dart2js/library_resolution_test.dart b/tests/compiler/dart2js/library_resolution_test.dart
index 23e4a0a..c5a5fa7 100644
--- a/tests/compiler/dart2js/library_resolution_test.dart
+++ b/tests/compiler/dart2js/library_resolution_test.dart
@@ -25,7 +25,7 @@
 
 import 'package:compiler/src/old_to_new_api.dart'
     show LegacyCompilerDiagnostics, LegacyCompilerInput;
-import 'package:compiler/compiler_new.dart' show CompilerOptions;
+import 'package:compiler/src/options.dart' show CompilerOptions;
 
 Uri sdkRoot = Uri.base.resolve("sdk/");
 Uri mock1LibraryUri = sdkRoot.resolve("lib/mock1.dart");
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index df9807e..7c88613 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -11,7 +11,6 @@
 import 'package:compiler/compiler_new.dart' show
     CompilationResult,
     CompilerDiagnostics,
-    CompilerOptions,
     CompilerOutput,
     Diagnostic,
     PackagesDiscoveryProvider;
@@ -23,6 +22,8 @@
     NullCompilerOutput;
 import 'package:compiler/src/library_loader.dart' show
     LoadedLibraries;
+import 'package:compiler/src/options.dart' show
+    CompilerOptions;
 
 import 'memory_source_file_helper.dart';
 
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index c08dbde..e2628b8 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -1,15 +1,13 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 library mock_compiler;
 
-import "package:expect/expect.dart";
 import 'dart:async';
 import 'dart:collection';
 
 import 'package:compiler/compiler.dart' as api;
-import 'package:compiler/compiler_new.dart' as new_api;
 import 'package:compiler/src/common/names.dart' show
     Uris;
 import 'package:compiler/src/constants/expressions.dart';
@@ -17,11 +15,14 @@
 import 'package:compiler/src/diagnostics/source_span.dart';
 import 'package:compiler/src/diagnostics/spannable.dart';
 import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/js_backend/backend_helpers.dart'
-    show BackendHelpers;
-import 'package:compiler/src/js_backend/lookup_map_analysis.dart'
-    show LookupMapAnalysis;
+import 'package:compiler/src/elements/visitor.dart';
+import 'package:compiler/src/js_backend/backend_helpers.dart' show
+    BackendHelpers;
+import 'package:compiler/src/js_backend/lookup_map_analysis.dart' show
+    LookupMapAnalysis;
 import 'package:compiler/src/io/source_file.dart';
+import 'package:compiler/src/options.dart' show
+    CompilerOptions;
 import 'package:compiler/src/resolution/members.dart';
 import 'package:compiler/src/resolution/registry.dart';
 import 'package:compiler/src/resolution/scope.dart';
@@ -31,17 +32,17 @@
 import 'package:compiler/src/old_to_new_api.dart';
 import 'parser_helper.dart';
 
-import 'package:compiler/src/elements/modelx.dart'
-    show ElementX,
-         LibraryElementX,
-         ErroneousElementX,
-         FunctionElementX;
+import 'package:compiler/src/elements/modelx.dart' show
+    ElementX,
+    LibraryElementX,
+    ErroneousElementX,
+    FunctionElementX;
 
 import 'package:compiler/src/compiler.dart';
 
-import 'package:compiler/src/deferred_load.dart'
-    show DeferredLoadTask,
-         OutputUnit;
+import 'package:compiler/src/deferred_load.dart' show
+    DeferredLoadTask,
+    OutputUnit;
 
 import 'mock_libraries.dart';
 import 'diagnostic_helper.dart';
@@ -88,7 +89,7 @@
        LibrarySourceProvider this.librariesOverride})
       : sourceFiles = new Map<String, SourceFile>(),
         testedPatchVersion = patchVersion,
-        super(options: new new_api.CompilerOptions(
+        super(options: new CompilerOptions(
               entryPoint: new Uri(scheme: 'mock'),
               libraryRoot: Uri.parse('placeholder_library_root_for_mock/'),
               enableTypeAssertions: enableTypeAssertions,
@@ -103,8 +104,7 @@
               preserveComments: preserveComments,
               trustTypeAnnotations: trustTypeAnnotations,
               trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations,
-              diagnosticOptions:
-                  new DiagnosticOptions(shownPackageWarnings: const [])),
+              shownPackageWarnings: const []),
               outputProvider: new LegacyCompilerOutput(outputProvider)) {
 
     deferredLoadTask = new MockDeferredLoadTask(this);
@@ -347,6 +347,10 @@
   parseNode(_) => null;
 
   bool get hasNode => false;
+
+  accept(ElementVisitor visitor, arg) {
+    return visitor.visitMethodElement(this, arg);
+  }
 }
 
 // TODO(herhut): Disallow warnings and errors during compilation by default.
diff --git a/tests/compiler/dart2js/options_helper.dart b/tests/compiler/dart2js/options_helper.dart
new file mode 100644
index 0000000..b071832
--- /dev/null
+++ b/tests/compiler/dart2js/options_helper.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library options_helper;
+
+import 'package:compiler/src/options.dart';
+export 'package:compiler/src/options.dart';
+
+class MockDiagnosticOptions implements DiagnosticOptions {
+  const MockDiagnosticOptions();
+
+  bool get fatalWarnings => false;
+  bool get terseDiagnostics => false;
+  bool get suppressWarnings => false;
+  bool get suppressHints => false;
+  bool get showAllPackageWarnings => false;
+  bool get hidePackageWarnings => true;
+  bool showPackageWarningsFor(Uri uri) => false;
+}
+
+class MockParserOptions implements ParserOptions {
+  bool get enableConditionalDirectives => true;
+}
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index 202e6f2..d6e1953 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -22,12 +22,15 @@
     show CompilationUnitElementX, ElementX, LibraryElementX;
 
 import "package:compiler/src/compiler.dart";
+import 'package:compiler/src/options.dart';
 import "package:compiler/src/diagnostics/source_span.dart";
 import "package:compiler/src/diagnostics/spannable.dart";
 import "package:compiler/src/diagnostics/diagnostic_listener.dart";
 import "package:compiler/src/diagnostics/messages.dart";
 import "package:compiler/src/script.dart";
 
+import "options_helper.dart";
+
 export "package:compiler/src/diagnostics/diagnostic_listener.dart";
 export 'package:compiler/src/parser/listener.dart';
 export 'package:compiler/src/parser/node_listener.dart';
@@ -38,6 +41,8 @@
 export "package:compiler/src/tokens/token_constants.dart";
 
 class LoggerCanceler extends DiagnosticReporter {
+  DiagnosticOptions get options => const MockDiagnosticOptions();
+
   void log(message) {
     print(message);
   }
@@ -102,7 +107,7 @@
   NodeListener listener = new NodeListener(
       new ScannerOptions(canUseNative: true),
       reporter, library.entryCompilationUnit);
-  Parser parser = new Parser(listener, enableConditionalDirectives: true);
+  Parser parser = new Parser(listener, new MockParserOptions());
   Token endToken = parseMethod(parser, tokens);
   assert(endToken.kind == EOF_TOKEN);
   Node node = listener.popNode();
@@ -150,7 +155,7 @@
   ElementListener listener = new ElementListener(
       compiler.parsing.getScannerOptionsFor(library),
       reporter, unit, () => id++);
-  PartialParser parser = new PartialParser(listener);
+  PartialParser parser = new PartialParser(listener, new MockParserOptions());
   reporter.withCurrentElement(unit, () => parser.parseUnit(tokens));
   return unit.localMembers;
 }
diff --git a/tests/compiler/dart2js/partial_parser_test.dart b/tests/compiler/dart2js/partial_parser_test.dart
index e0099f1..b1c4d3b 100644
--- a/tests/compiler/dart2js/partial_parser_test.dart
+++ b/tests/compiler/dart2js/partial_parser_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import 'options_helper.dart';
 import 'parser_helper.dart';
 
 void main() {
@@ -10,7 +11,8 @@
 }
 
 void testSkipExpression() {
-  PartialParser parser = new PartialParser(new Listener());
+  PartialParser parser =
+      new PartialParser(new Listener(), new MockParserOptions());
   Token token = scan('a < b;');
   token = parser.skipExpression(token);
   Expect.equals(';', token.value);
diff --git a/tests/compiler/dart2js/semantic_visitor_test.dart b/tests/compiler/dart2js/semantic_visitor_test.dart
index 5a0e9dd..f8eca14 100644
--- a/tests/compiler/dart2js/semantic_visitor_test.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test.dart
@@ -674,6 +674,12 @@
   VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,
   VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,
 
+  VISIT_INDEX_SET_IF_NULL,
+  VISIT_SUPER_INDEX_SET_IF_NULL,
+  VISIT_UNRESOLVED_SUPER_INDEX_SET_IF_NULL,
+  VISIT_UNRESOLVED_SUPER_GETTER_INDEX_SET_IF_NULL,
+  VISIT_UNRESOLVED_SUPER_SETTER_INDEX_SET_IF_NULL,
+
   VISIT_LOGICAL_AND,
   VISIT_LOGICAL_OR,
   VISIT_IS,
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
index 51eae03..b72e479 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
@@ -2142,6 +2142,66 @@
                     error: MessageKind.NO_SUPER_IN_STATIC,
                     index: '42',
                     operator: '--')),
+    const Test(
+        '''
+        m() => [][42] ??= 0;
+        ''',
+        const Visit(VisitKind.VISIT_INDEX_SET_IF_NULL,
+                    receiver: '[] ',
+                    index: '42',
+                    rhs: '0')),
+    const Test.clazz(
+        '''
+        class B {
+          operator [](_) => null;
+          operator []=(a, b) {}
+        }
+        class C extends B {
+          m() => super[42] ??= 0;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_INDEX_SET_IF_NULL,
+                    getter: 'function(B#[])',
+                    setter: 'function(B#[]=)',
+                    index: '42',
+                    rhs: '0')),
+    const Test.clazz(
+        '''
+        class B {
+          operator []=(a, b) {}
+        }
+        class C extends B {
+          m() => super[42] ??= 0;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_SET_IF_NULL,
+                    setter: 'function(B#[]=)',
+                    index: '42',
+                    rhs: '0')),
+    const Test.clazz(
+        '''
+        class B {
+          operator [](_) => null;
+        }
+        class C extends B {
+          m() => super[42] ??= 0;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_SET_IF_NULL,
+                    getter: 'function(B#[])',
+                    index: '42',
+                    rhs: '0')),
+    const Test.clazz(
+        '''
+        class B {
+        }
+        class C extends B {
+          m() => super[42] ??= 0;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_SET_IF_NULL,
+                    index: '42',
+                    rhs: '0')),
   ],
   'Equals': const [
     // Equals
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart b/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
index cdbbe41..2187ba8 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
@@ -3551,4 +3551,87 @@
     super.visitUnresolvedTopLevelSetterSetIfNull(
         node, getter, element, rhs, arg);
   }
+
+  @override
+  visitIndexSetIfNull(
+      SendSet node,
+      Node receiver,
+      Node index,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_INDEX_SET_IF_NULL,
+        receiver: receiver, index: index, rhs: rhs));
+    super.visitIndexSetIfNull(node, receiver, index, rhs, arg);
+  }
+
+  @override
+  visitSuperIndexSetIfNull(
+      SendSet node,
+      MethodElement getter,
+      MethodElement setter,
+      Node index,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_SUPER_INDEX_SET_IF_NULL,
+        getter: getter, setter: setter, index: index, rhs: rhs));
+    super.visitSuperIndexSetIfNull(node, getter, setter, index, rhs, arg);
+  }
+
+  @override
+  visitUnresolvedSuperGetterIndexSetIfNull(
+      Send node,
+      Element element,
+      MethodElement setter,
+      Node index,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_SET_IF_NULL,
+        setter: setter, index: index, rhs: rhs));
+    super.visitUnresolvedSuperGetterIndexSetIfNull(
+        node, element, setter, index, rhs, arg);
+  }
+
+  @override
+  visitUnresolvedSuperSetterIndexSetIfNull(
+      Send node,
+      MethodElement getter,
+      Element element,
+      Node index,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_SET_IF_NULL,
+        getter: getter, index: index, rhs: rhs));
+    super.visitUnresolvedSuperSetterIndexSetIfNull(
+        node, getter, element, index, rhs, arg);
+  }
+
+  @override
+  visitUnresolvedSuperIndexSetIfNull(
+      Send node,
+      Element element,
+      Node index,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_SET_IF_NULL,
+        index: index, rhs: rhs));
+    super.visitUnresolvedSuperIndexSetIfNull(node, element, index, rhs, arg);
+  }
+
+  @override
+  errorInvalidIndexSetIfNull(
+      SendSet node,
+      ErroneousElement error,
+      Node index,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.ERROR_INVALID_SET_IF_NULL,
+        index: index, rhs: rhs));
+    super.visitUnresolvedSuperIndexSetIfNull(node, error, index, rhs, arg);
+  }
 }
diff --git a/tests/compiler/dart2js/serialization_analysis_test.dart b/tests/compiler/dart2js/serialization_analysis_test.dart
index 19aedf7..373fb89 100644
--- a/tests/compiler/dart2js/serialization_analysis_test.dart
+++ b/tests/compiler/dart2js/serialization_analysis_test.dart
@@ -8,21 +8,19 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common/backend_api.dart';
 import 'package:compiler/src/common/names.dart';
-import 'package:compiler/src/common/resolution.dart';
 import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/filenames.dart';
-import 'package:compiler/src/serialization/element_serialization.dart';
-import 'package:compiler/src/serialization/impact_serialization.dart';
-import 'package:compiler/src/serialization/json_serializer.dart';
-import 'package:compiler/src/serialization/serialization.dart';
-import 'package:compiler/src/serialization/task.dart';
-import 'package:compiler/src/universe/world_impact.dart';
 import 'memory_compiler.dart';
+import 'serialization_helper.dart';
 
 const List<Test> TESTS = const <Test>[
   const Test(const {
+    'main.dart': 'main() {}'
+  }),
+
+  const Test(const {
     'main.dart': 'main() => print("Hello World");'
   }),
 
@@ -241,13 +239,7 @@
       options: [Flags.analyzeOnly],
       diagnosticHandler: diagnosticCollector,
       beforeRun: (Compiler compiler) {
-        Deserializer deserializer = new Deserializer.fromText(
-            new DeserializationContext(),
-            serializedData,
-            const JsonSerializationDecoder());
-        deserializer.plugins.add(compiler.backend.serialization.deserializer);
-        compiler.serialization.deserializer =
-            new _DeserializerSystem(deserializer);
+        deserialize(compiler, serializedData);
       });
   if (test != null) {
     Expect.equals(test.expectedErrorCount, diagnosticCollector.errors.length,
@@ -263,84 +255,3 @@
   }
 }
 
-Future<String> serializeDartCore() async {
-  Compiler compiler = compilerFor(
-      options: [Flags.analyzeAll]);
-  compiler.serialization.supportSerialization = true;
-  await compiler.run(Uris.dart_core);
-  return serialize(compiler);
-}
-
-String serialize(Compiler compiler) {
-  Serializer serializer = new Serializer();
-  serializer.plugins.add(compiler.backend.serialization.serializer);
-  serializer.plugins.add(new WorldImpactSerializer(compiler.resolution));
-
-  for (LibraryElement library in compiler.libraryLoader.libraries) {
-    serializer.serialize(library);
-  }
-  return serializer.toText(const JsonSerializationEncoder());
-}
-
-const String WORLD_IMPACT_TAG = 'worldImpact';
-
-class WorldImpactSerializer extends SerializerPlugin {
-  final Resolution resolution;
-
-  WorldImpactSerializer(this.resolution);
-
-  @override
-  void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
-    if (resolution.hasBeenResolved(element)) {
-      WorldImpact impact = resolution.getWorldImpact(element);
-      ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG);
-      impact.apply(new ImpactSerializer(encoder));
-    }
-  }
-}
-
-class WorldImpactDeserializer extends DeserializerPlugin {
-  Map<Element, WorldImpact> impactMap = <Element, WorldImpact>{};
-
-  @override
-  void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
-    ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG);
-    if (decoder != null) {
-      impactMap[element] = ImpactDeserializer.deserializeImpact(decoder);
-    }
-  }
-}
-
-class _DeserializerSystem extends DeserializerSystem {
-  final Deserializer _deserializer;
-  final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
-  final WorldImpactDeserializer _worldImpactDeserializer =
-      new WorldImpactDeserializer();
-
-  _DeserializerSystem(this._deserializer) {
-    _deserializer.plugins.add(_worldImpactDeserializer);
-  }
-
-  LibraryElement readLibrary(Uri resolvedUri) {
-    LibraryElement library = _deserializer.lookupLibrary(resolvedUri);
-    if (library != null) {
-      deserializedLibraries.add(library);
-    }
-    return library;
-  }
-
-  @override
-  WorldImpact computeWorldImpact(Element element) {
-    WorldImpact impact = _worldImpactDeserializer.impactMap[element];
-    if (impact == null) {
-      print('No impact found for $element (${element.library})');
-      impact = const WorldImpact();
-    }
-    return impact;
-  }
-
-  @override
-  bool isDeserialized(Element element) {
-    return deserializedLibraries.contains(element.library);
-  }
-}
diff --git a/tests/compiler/dart2js/serialization_helper.dart b/tests/compiler/dart2js/serialization_helper.dart
new file mode 100644
index 0000000..a8f95a6
--- /dev/null
+++ b/tests/compiler/dart2js/serialization_helper.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization_helper;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common/backend_api.dart';
+import 'package:compiler/src/common/names.dart';
+import 'package:compiler/src/common/resolution.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/filenames.dart';
+import 'package:compiler/src/serialization/element_serialization.dart';
+import 'package:compiler/src/serialization/impact_serialization.dart';
+import 'package:compiler/src/serialization/json_serializer.dart';
+import 'package:compiler/src/serialization/serialization.dart';
+import 'package:compiler/src/serialization/task.dart';
+import 'package:compiler/src/universe/world_impact.dart';
+import 'memory_compiler.dart';
+
+
+Future<String> serializeDartCore() async {
+  Compiler compiler = compilerFor(
+      options: [Flags.analyzeAll]);
+  compiler.serialization.supportSerialization = true;
+  await compiler.run(Uris.dart_core);
+  return serialize(compiler, compiler.libraryLoader.libraries)
+      .toText(const JsonSerializationEncoder());
+}
+
+Serializer serialize(Compiler compiler, Iterable<LibraryElement> libraries) {
+  assert(compiler.serialization.supportSerialization);
+
+  Serializer serializer = new Serializer();
+  serializer.plugins.add(compiler.backend.serialization.serializer);
+  serializer.plugins.add(new ResolutionImpactSerializer(compiler.resolution));
+
+  for (LibraryElement library in libraries) {
+    serializer.serialize(library);
+  }
+  return serializer;
+}
+
+void deserialize(Compiler compiler, String serializedData) {
+  Deserializer deserializer = new Deserializer.fromText(
+      new DeserializationContext(),
+      serializedData,
+      const JsonSerializationDecoder());
+  deserializer.plugins.add(compiler.backend.serialization.deserializer);
+  compiler.serialization.deserializer =
+      new _DeserializerSystem(
+          deserializer,
+          compiler.backend.impactTransformer);
+}
+
+
+const String WORLD_IMPACT_TAG = 'worldImpact';
+
+class ResolutionImpactSerializer extends SerializerPlugin {
+  final Resolution resolution;
+
+  ResolutionImpactSerializer(this.resolution);
+
+  @override
+  void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
+    if (resolution.hasBeenResolved(element)) {
+      ResolutionImpact impact = resolution.getResolutionImpact(element);
+      ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG);
+      new ImpactSerializer(encoder).serialize(impact);
+    }
+  }
+}
+
+class ResolutionImpactDeserializer extends DeserializerPlugin {
+  Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{};
+
+  @override
+  void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
+    ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG);
+    if (decoder != null) {
+      impactMap[element] = ImpactDeserializer.deserializeImpact(decoder);
+    }
+  }
+}
+
+class _DeserializerSystem extends DeserializerSystem {
+  final Deserializer _deserializer;
+  final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
+  final ResolutionImpactDeserializer _resolutionImpactDeserializer =
+      new ResolutionImpactDeserializer();
+  final ImpactTransformer _impactTransformer;
+
+  _DeserializerSystem(this._deserializer, this._impactTransformer) {
+    _deserializer.plugins.add(_resolutionImpactDeserializer);
+  }
+
+  LibraryElement readLibrary(Uri resolvedUri) {
+    LibraryElement library = _deserializer.lookupLibrary(resolvedUri);
+    if (library != null) {
+      deserializedLibraries.add(library);
+    }
+    return library;
+  }
+
+  ResolutionImpact getResolutionImpact(Element element) {
+    return _resolutionImpactDeserializer.impactMap[element];
+  }
+
+  @override
+  WorldImpact computeWorldImpact(Element element) {
+    ResolutionImpact resolutionImpact = getResolutionImpact(element);
+    if (resolutionImpact == null) {
+      print('No impact found for $element (${element.library})');
+      return const WorldImpact();
+    } else {
+      return _impactTransformer.transformResolutionImpact(resolutionImpact);
+    }
+  }
+
+  @override
+  bool isDeserialized(Element element) {
+    return deserializedLibraries.contains(element.library);
+  }
+}
diff --git a/tests/compiler/dart2js/serialization_impact_test.dart b/tests/compiler/dart2js/serialization_impact_test.dart
new file mode 100644
index 0000000..2fbd212
--- /dev/null
+++ b/tests/compiler/dart2js/serialization_impact_test.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization_impact_test;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common/resolution.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/filenames.dart';
+import 'package:compiler/src/serialization/equivalence.dart';
+import 'memory_compiler.dart';
+import 'serialization_helper.dart';
+import 'serialization_test.dart';
+
+main(List<String> arguments) {
+  asyncTest(() async {
+    String serializedData = await serializeDartCore();
+    if (arguments.isNotEmpty) {
+      Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.last));
+      await check(serializedData, entryPoint);
+    } else {
+      Uri entryPoint = Uri.parse('memory:main.dart');
+      await check(serializedData, entryPoint, {'main.dart': 'main() {}'});
+    }
+  });
+}
+
+Future check(
+  String serializedData,
+  Uri entryPoint,
+  [Map<String, String> sourceFiles = const <String, String>{}]) async {
+
+  Compiler compilerNormal = compilerFor(
+      memorySourceFiles: sourceFiles,
+      options: [Flags.analyzeOnly]);
+  compilerNormal.resolution.retainCachesForTesting = true;
+  await compilerNormal.run(entryPoint);
+
+  Compiler compilerDeserialized = compilerFor(
+      memorySourceFiles: sourceFiles,
+      options: [Flags.analyzeOnly]);
+  compilerDeserialized.resolution.retainCachesForTesting = true;
+  deserialize(compilerDeserialized, serializedData);
+  await compilerDeserialized.run(entryPoint);
+
+  checkResolutionImpacts(compilerNormal, compilerDeserialized, verbose: true);
+}
+
+/// Check equivalence of [impact1] and [impact2].
+void checkImpacts(Element element1, Element element2,
+                  ResolutionImpact impact1, ResolutionImpact impact2,
+                  {bool verbose: false}) {
+  if (impact1 == null || impact2 == null) return;
+
+  if (verbose) {
+    print('Checking impacts for $element1 vs $element2');
+  }
+
+  testResolutionImpactEquivalence(impact1, impact2, const CheckStrategy());
+}
+
+
+/// Check equivalence between all resolution impacts common to [compiler1] and
+/// [compiler2].
+void checkResolutionImpacts(
+    Compiler compiler1,
+    Compiler compiler2,
+    {bool verbose: false}) {
+
+  void checkMembers(Element member1, Element member2) {
+    if (member1.isClass && member2.isClass) {
+      ClassElement class1 = member1;
+      ClassElement class2 = member2;
+      class1.forEachLocalMember((m1) {
+        checkMembers(m1, class2.lookupLocalMember(m1.name));
+      });
+      return;
+    }
+
+    if (!compiler1.resolution.hasResolutionImpact(member1)) {
+      return;
+    }
+
+    if (member2 == null) {
+      return;
+    }
+
+    if (areElementsEquivalent(member1, member2)) {
+      checkImpacts(
+          member1, member2,
+          compiler1.resolution.getResolutionImpact(member1),
+          compiler2.serialization.deserializer.getResolutionImpact(member2),
+          verbose: verbose);
+    }
+  }
+
+  for (LibraryElement library1 in compiler1.libraryLoader.libraries) {
+    LibraryElement library2 =
+        compiler2.libraryLoader.lookupLibrary(library1.canonicalUri);
+    if (library2 != null) {
+      library1.forEachLocalMember((Element member1) {
+        checkMembers(member1, library2.localLookup(member1.name));
+      });
+
+    }
+  }
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/serialization_model_test.dart b/tests/compiler/dart2js/serialization_model_test.dart
new file mode 100644
index 0000000..b8cef25
--- /dev/null
+++ b/tests/compiler/dart2js/serialization_model_test.dart
@@ -0,0 +1,224 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization_model_test;
+
+import 'dart:async';
+import 'dart:io';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common/backend_api.dart';
+import 'package:compiler/src/common/names.dart';
+import 'package:compiler/src/common/resolution.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/dart_types.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/filenames.dart';
+import 'package:compiler/src/serialization/element_serialization.dart';
+import 'package:compiler/src/serialization/impact_serialization.dart';
+import 'package:compiler/src/serialization/json_serializer.dart';
+import 'package:compiler/src/serialization/serialization.dart';
+import 'package:compiler/src/serialization/equivalence.dart';
+import 'package:compiler/src/serialization/task.dart';
+import 'package:compiler/src/universe/world_impact.dart';
+import 'package:compiler/src/universe/class_set.dart';
+import 'package:compiler/src/universe/use.dart';
+import 'memory_compiler.dart';
+import 'serialization_helper.dart';
+import 'serialization_analysis_test.dart';
+import 'serialization_impact_test.dart';
+import 'serialization_test.dart';
+
+main(List<String> arguments) {
+  String filename;
+  for (String arg in arguments) {
+    if (!arg.startsWith('-')) {
+      filename = arg;
+    }
+  }
+  bool verbose = arguments.contains('-v');
+
+  asyncTest(() async {
+    print('------------------------------------------------------------------');
+    print('serialize dart:core');
+    print('------------------------------------------------------------------');
+    String serializedData;
+    File file = new File('out.data');
+    if (arguments.contains('-l')) {
+      if (file.existsSync()) {
+        print('Loading data from $file');
+        serializedData = file.readAsStringSync();
+      }
+    }
+    if (serializedData == null) {
+      serializedData = await serializeDartCore();
+      if (arguments.contains('-s')) {
+        print('Saving data to $file');
+        file.writeAsStringSync(serializedData);
+      }
+    }
+    if (filename != null) {
+      Uri entryPoint = Uri.base.resolve(nativeToUriPath(filename));
+      await check(serializedData, entryPoint);
+    } else {
+      Uri entryPoint = Uri.parse('memory:main.dart');
+      for (Test test in TESTS) {
+        if (test.sourceFiles['main.dart']
+                .contains('main(List<String> arguments)')) {
+          // TODO(johnniwinther): Check this test.
+          continue;
+        }
+        print('==============================================================');
+        print(test.sourceFiles);
+        await check(
+          serializedData,
+          entryPoint,
+          sourceFiles: test.sourceFiles,
+          verbose: verbose);
+      }
+    }
+  });
+}
+
+Future check(
+  String serializedData,
+  Uri entryPoint,
+  {Map<String, String> sourceFiles: const <String, String>{},
+   bool verbose: false}) async {
+
+  print('------------------------------------------------------------------');
+  print('compile normal');
+  print('------------------------------------------------------------------');
+  Compiler compilerNormal = compilerFor(
+      memorySourceFiles: sourceFiles,
+      options: [Flags.analyzeOnly]);
+  compilerNormal.resolution.retainCachesForTesting = true;
+  await compilerNormal.run(entryPoint);
+  compilerNormal.world.populate();
+
+  print('------------------------------------------------------------------');
+  print('compile deserialized');
+  print('------------------------------------------------------------------');
+  Compiler compilerDeserialized = compilerFor(
+      memorySourceFiles: sourceFiles,
+      options: [Flags.analyzeOnly]);
+  compilerDeserialized.resolution.retainCachesForTesting = true;
+  deserialize(compilerDeserialized, serializedData);
+  await compilerDeserialized.run(entryPoint);
+  compilerDeserialized.world.populate();
+
+  checkResolutionImpacts(
+      compilerNormal, compilerDeserialized,
+      verbose: verbose);
+
+  checkSets(
+      compilerNormal.resolverWorld.directlyInstantiatedClasses,
+      compilerDeserialized.resolverWorld.directlyInstantiatedClasses,
+      "Directly instantiated classes mismatch",
+      areElementsEquivalent,
+      verbose: verbose);
+
+  checkSets(
+      compilerNormal.resolverWorld.instantiatedTypes,
+      compilerDeserialized.resolverWorld.instantiatedTypes,
+      "Instantiated types mismatch",
+      areTypesEquivalent,
+      // TODO(johnniwinther): Ensure that all instantiated types are tracked.
+      failOnUnfound: false,
+      verbose: verbose);
+
+  checkSets(
+      compilerNormal.resolverWorld.isChecks,
+      compilerDeserialized.resolverWorld.isChecks,
+      "Is-check mismatch",
+      areTypesEquivalent,
+      verbose: verbose);
+
+  checkSets(
+      compilerNormal.enqueuer.resolution.processedElements,
+      compilerDeserialized.enqueuer.resolution.processedElements,
+      "Processed element mismatch",
+      areElementsEquivalent,
+      verbose: verbose);
+
+  checkClassHierarchyNodes(
+    compilerNormal.world.getClassHierarchyNode(
+        compilerNormal.coreClasses.objectClass),
+    compilerDeserialized.world.getClassHierarchyNode(
+        compilerDeserialized.coreClasses.objectClass),
+    verbose: verbose);
+}
+
+void checkClassHierarchyNodes(
+    ClassHierarchyNode a, ClassHierarchyNode b,
+    {bool verbose: false}) {
+  if (verbose) {
+    print('Checking $a vs $b');
+  }
+  Expect.isTrue(
+      areElementsEquivalent(a.cls, b.cls),
+      "Element identity mismatch for ${a.cls} vs ${b.cls}.");
+  Expect.equals(
+      a.isDirectlyInstantiated,
+      b.isDirectlyInstantiated,
+      "Value mismatch for 'isDirectlyInstantiated' for ${a.cls} vs ${b.cls}.");
+  Expect.equals(
+      a.isIndirectlyInstantiated,
+      b.isIndirectlyInstantiated,
+      "Value mismatch for 'isIndirectlyInstantiated' "
+      "for ${a.cls} vs ${b.cls}.");
+  // TODO(johnniwinther): Enforce a canonical and stable order on direct
+  // subclasses.
+  for (ClassHierarchyNode child in a.directSubclasses) {
+    bool found = false;
+    for (ClassHierarchyNode other in b.directSubclasses) {
+      if (areElementsEquivalent(child.cls, other.cls)) {
+        checkClassHierarchyNodes(child, other,
+            verbose: verbose);
+        found = true;
+        break;
+      }
+    }
+    if (!found) {
+      Expect.isFalse(
+          child.isInstantiated, 'Missing subclass ${child.cls} of ${a.cls}');
+    }
+  }
+}
+
+void checkSets(
+    Iterable set1,
+    Iterable set2,
+    String messagePrefix,
+    bool areEquivalent(a, b),
+    {bool failOnUnfound: true,
+     bool verbose: false}) {
+  List common = [];
+  List unfound = [];
+  Set remaining = computeSetDifference(
+      set1, set2, common, unfound, areEquivalent);
+  StringBuffer sb = new StringBuffer();
+  sb.write("$messagePrefix:");
+  if (verbose) {
+    sb.write("\n Common:\n  ${common.join('\n  ')}");
+  }
+  if (unfound.isNotEmpty || verbose) {
+    sb.write("\n Unfound:\n  ${unfound.join('\n  ')}");
+  }
+  if (remaining.isNotEmpty || verbose) {
+    sb.write("\n Extra: \n  ${remaining.join('\n  ')}");
+  }
+  String message = sb.toString();
+  if (unfound.isNotEmpty || remaining.isNotEmpty) {
+
+    if (failOnUnfound || remaining.isNotEmpty) {
+      Expect.fail(message);
+    } else {
+      print(message);
+    }
+  } else if (verbose) {
+    print(message);
+  }
+}
diff --git a/tests/compiler/dart2js/serialization_test.dart b/tests/compiler/dart2js/serialization_test.dart
index 0f965a3..c19fb61 100644
--- a/tests/compiler/dart2js/serialization_test.dart
+++ b/tests/compiler/dart2js/serialization_test.dart
@@ -17,6 +17,7 @@
 import 'package:compiler/src/elements/visitor.dart';
 import 'package:compiler/src/ordered_typeset.dart';
 import 'package:compiler/src/serialization/element_serialization.dart';
+import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:compiler/src/serialization/json_serializer.dart';
 import 'package:compiler/src/serialization/serialization.dart';
 
@@ -144,7 +145,7 @@
 /// [checkEquivalence] to check the pair-wise equivalence.
 ///
 /// Uses [object1], [object2] and [property] to provide context for failures.
-void checkListEquivalence(
+bool checkListEquivalence(
     Object object1, Object object2, String property,
     Iterable list1, Iterable list2,
     void checkEquivalence(o1, o2, property, a, b)) {
@@ -167,30 +168,96 @@
         '`${property}` on $object1:\n ${list1.join('\n ')}\n'
         '`${property}` on $object2:\n ${list2.join('\n ')}';
   }
+  return true;
+}
+
+/// Computes the set difference between [set1] and [set2] using
+/// [elementEquivalence] to determine element equivalence.
+///
+/// Elements both in [set1] and [set2] are added to [common], elements in [set1]
+/// but not in [set2] are added to [unfound], and the set of elements in [set2]
+/// but not in [set1] are returned.
+Set computeSetDifference(
+    Iterable set1,
+    Iterable set2,
+    List common,
+    List unfound,
+    [bool sameElement(a, b) = equality]) {
+  // TODO(johnniwinther): Avoid the quadratic cost here. Some ideas:
+  // - convert each set to a list and sort it first, then compare by walking
+  // both lists in parallel
+  // - map each element to a canonical object, create a map containing those
+  // mappings, use the mapped sets to compare (then operations like
+  // set.difference would work)
+  Set remaining = set2.toSet();
+  for (var element1 in set1) {
+    bool found = false;
+    for (var element2 in remaining) {
+      if (sameElement(element1, element2)) {
+        found = true;
+        remaining.remove(element2);
+        break;
+      }
+    }
+    if (found) {
+      common.add(element1);
+    } else {
+      unfound.add(element1);
+    }
+  }
+  return remaining;
+}
+
+/// Check equivalence of the two iterables, [set1] and [set1], as sets using
+/// [elementEquivalence] to compute the pair-wise equivalence.
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkSetEquivalence(
+    var object1,
+    var object2,
+    String property,
+    Iterable set1,
+    Iterable set2,
+    bool sameElement(a, b)) {
+  List common = [];
+  List unfound = [];
+  Set remaining =
+      computeSetDifference(set1, set2, common, unfound, sameElement);
+  if (unfound.isNotEmpty || remaining.isNotEmpty) {
+    String message =
+        "Set mismatch for `$property` on $object1 vs $object2: \n"
+        "Common:\n ${common.join('\n ')}\n"
+        "Unfound:\n ${unfound.join('\n ')}\n"
+        "Extra: \n ${remaining.join('\n ')}";
+    throw message;
+  }
+  return true;
 }
 
 /// Checks the equivalence of the identity (but not properties) of [element1]
 /// and [element2].
 ///
 /// Uses [object1], [object2] and [property] to provide context for failures.
-void checkElementIdentities(
+bool checkElementIdentities(
     Object object1, Object object2, String property,
     Element element1, Element element2) {
-  if (identical(element1, element2)) return;
+  if (identical(element1, element2)) return true;
   if (element1 == null || element2 == null) {
-    check(object1, object2, property, element1, element2);
+    return check(object1, object2, property, element1, element2);
+  } else {
+    return const ElementIdentityEquivalence(const CheckStrategy())
+        .visit(element1, element2);
   }
-  const ElementIdentityEquivalence().visit(element1, element2);
 }
 
 /// Checks the pair-wise equivalence of the identity (but not properties) of the
 /// elements in [list] and [list2].
 ///
 /// Uses [object1], [object2] and [property] to provide context for failures.
-void checkElementListIdentities(
+bool checkElementListIdentities(
     Object object1, Object object2, String property,
     Iterable<Element> list1, Iterable<Element> list2) {
-  checkListEquivalence(
+  return checkListEquivalence(
       object1, object2, property,
       list1, list2, checkElementIdentities);
 }
@@ -198,50 +265,129 @@
 /// Checks the equivalence of [type1] and [type2].
 ///
 /// Uses [object1], [object2] and [property] to provide context for failures.
-void checkTypes(
+bool checkTypes(
     Object object1, Object object2, String property,
     DartType type1, DartType type2) {
-  if (identical(type1, type2)) return;
+  if (identical(type1, type2)) return true;
   if (type1 == null || type2 == null) {
-    check(object1, object2, property, type1, type2);
+    return check(object1, object2, property, type1, type2);
+  } else {
+    return const TypeEquivalence(const CheckStrategy()).visit(type1, type2);
   }
-  const TypeEquivalence().visit(type1, type2);
 }
 
 /// Checks the pair-wise equivalence of the types in [list1] and [list2].
 ///
 /// Uses [object1], [object2] and [property] to provide context for failures.
-void checkTypeLists(
+bool checkTypeLists(
     Object object1, Object object2, String property,
     List<DartType> list1, List<DartType> list2) {
-  checkListEquivalence(object1, object2, property, list1, list2, checkTypes);
+  return checkListEquivalence(
+      object1, object2, property, list1, list2, checkTypes);
 }
 
 /// Checks the equivalence of [exp1] and [exp2].
 ///
 /// Uses [object1], [object2] and [property] to provide context for failures.
-void checkConstants(
+bool checkConstants(
     Object object1, Object object2, String property,
     ConstantExpression exp1, ConstantExpression exp2) {
-  if (identical(exp1, exp2)) return;
+  if (identical(exp1, exp2)) return true;
   if (exp1 == null || exp2 == null) {
-    check(object1, object2, property, exp1, exp2);
+    return check(object1, object2, property, exp1, exp2);
+  } else {
+    return const ConstantEquivalence(const CheckStrategy()).visit(exp1, exp2);
   }
-  const ConstantEquivalence().visit(exp1, exp2);
 }
 
 /// Checks the pair-wise equivalence of the contants in [list1] and [list2].
 ///
 /// Uses [object1], [object2] and [property] to provide context for failures.
-void checkConstantLists(
+bool checkConstantLists(
     Object object1, Object object2, String property,
     List<ConstantExpression> list1,
     List<ConstantExpression> list2) {
-  checkListEquivalence(
+  return checkListEquivalence(
       object1, object2, property,
       list1, list2, checkConstants);
 }
 
+
+/// Strategy for checking equivalence.
+///
+/// Use this strategy to fail early with contextual information in the event of
+/// inequivalence.
+class CheckStrategy implements TestStrategy {
+  const CheckStrategy();
+
+  @override
+  bool test(var object1, var object2, String property, var value1, var value2) {
+    return check(object1, object2, property, value1, value2);
+  }
+
+  @override
+  bool testLists(
+      Object object1, Object object2, String property,
+      List list1, List list2,
+      [bool elementEquivalence(a, b) = equality]) {
+    return checkListEquivalence(
+        object1, object2, property, list1, list2,
+        (o1, o2, p, v1, v2) {
+          if (!elementEquivalence(v1, v2)) {
+            throw "$o1.$p = '${v1}' <> "
+                  "$o2.$p = '${v2}'";
+          }
+          return true;
+        });
+  }
+
+  @override
+  bool testSets(
+      var object1, var object2, String property,
+      Iterable set1, Iterable set2,
+      [bool elementEquivalence(a, b) = equality]) {
+    return checkSetEquivalence(
+        object1, object2,property, set1, set2, elementEquivalence);
+  }
+
+  @override
+  bool testElements(
+      Object object1, Object object2, String property,
+      Element element1, Element element2) {
+    return checkElementIdentities(
+        object1, object2, property, element1, element2);
+  }
+
+  @override
+  bool testTypes(
+      Object object1, Object object2, String property,
+      DartType type1, DartType type2) {
+    return checkTypes(object1, object2, property, type1, type2);
+  }
+
+  @override
+  bool testConstants(
+      Object object1, Object object2, String property,
+      ConstantExpression exp1, ConstantExpression exp2) {
+    return checkConstants(object1, object2, property, exp1, exp2);
+  }
+
+  @override
+  bool testTypeLists(
+      Object object1, Object object2, String property,
+      List<DartType> list1, List<DartType> list2) {
+    return checkTypeLists(object1, object2, property, list1, list2);
+  }
+
+  @override
+  bool testConstantLists(
+      Object object1, Object object2, String property,
+      List<ConstantExpression> list1,
+      List<ConstantExpression> list2) {
+    return checkConstantLists(object1, object2, property, list1, list2);
+  }
+}
+
 /// Checks the equivalence of [constructor1] and [constructor2].
 void constantConstructorEquivalence(ConstantConstructor constructor1,
                                     ConstantConstructor constructor2) {
@@ -333,127 +479,12 @@
 
 /// Check that the values [property] of [object1] and [object2], [value1] and
 /// [value2] respectively, are equal and throw otherwise.
-void check(var object1, var object2, String property, var value1, value2) {
+bool check(var object1, var object2, String property, var value1, value2) {
   if (value1 != value2) {
     throw "$object1.$property = '${value1}' <> "
           "$object2.$property = '${value2}'";
   }
-}
-
-/// Visitor that checks for equivalence of [Element] identities.
-class ElementIdentityEquivalence extends BaseElementVisitor<dynamic, Element> {
-  const ElementIdentityEquivalence();
-
-  void visit(Element element1, Element element2) {
-    if (element1 == null && element2 == null) return;
-    element1 = element1.declaration;
-    element2 = element2.declaration;
-    if (element1 == element2) return;
-    check(element1, element2, 'kind', element1.kind, element2.kind);
-    element1.accept(this, element2);
-  }
-
-  @override
-  void visitElement(Element e, Element arg) {
-    throw new UnsupportedError("Unsupported element $e");
-  }
-
-  @override
-  void visitLibraryElement(LibraryElement element1, LibraryElement element2) {
-    check(element1, element2,
-          'canonicalUri',
-          element1.canonicalUri, element2.canonicalUri);
-  }
-
-  @override
-  void visitCompilationUnitElement(CompilationUnitElement element1,
-                                   CompilationUnitElement element2) {
-    check(element1, element2,
-          'name',
-          element1.name, element2.name);
-    visit(element1.library, element2.library);
-  }
-
-  @override
-  void visitClassElement(ClassElement element1, ClassElement element2) {
-    check(element1, element2,
-          'name',
-          element1.name, element2.name);
-    visit(element1.library, element2.library);
-  }
-
-  void checkMembers(Element element1, Element element2) {
-    check(element1, element2,
-          'name',
-          element1.name, element2.name);
-    if (element1.enclosingClass != null || element2.enclosingClass != null) {
-      visit(element1.enclosingClass, element2.enclosingClass);
-    } else {
-      visit(element1.library, element2.library);
-    }
-  }
-
-  @override
-  void visitFieldElement(FieldElement element1, FieldElement element2) {
-    checkMembers(element1, element2);
-  }
-
-  @override
-  void visitFunctionElement(FunctionElement element1,
-                            FunctionElement element2) {
-    checkMembers(element1, element2);
-  }
-
-  void visitAbstractFieldElement(AbstractFieldElement element1,
-                                 AbstractFieldElement element2) {
-    checkMembers(element1, element2);
-  }
-
-  @override
-  void visitTypeVariableElement(TypeVariableElement element1,
-                                TypeVariableElement element2) {
-    check(element1, element2,
-          'name',
-          element1.name, element2.name);
-    visit(element1.typeDeclaration, element2.typeDeclaration);
-  }
-
-  @override
-  void visitTypedefElement(TypedefElement element1, TypedefElement element2) {
-    check(element1, element2,
-          'name',
-          element1.name, element2.name);
-    visit(element1.library, element2.library);
-  }
-
-  @override
-  void visitParameterElement(ParameterElement element1,
-                             ParameterElement element2) {
-    check(element1, element2,
-          'name',
-          element1.name, element2.name);
-    visit(element1.functionDeclaration, element2.functionDeclaration);
-  }
-
-  @override
-  void visitImportElement(ImportElement element1, ImportElement element2) {
-    visit(element1.importedLibrary, element2.importedLibrary);
-    visit(element1.library, element2.library);
-  }
-
-  @override
-  void visitExportElement(ExportElement element1, ExportElement element2) {
-    visit(element1.exportedLibrary, element2.exportedLibrary);
-    visit(element1.library, element2.library);
-  }
-
-  @override
-  void visitPrefixElement(PrefixElement element1, PrefixElement element2) {
-    check(element1, element2,
-          'name',
-          element1.name, element2.name);
-    visit(element1.library, element2.library);
-  }
+  return true;
 }
 
 /// Visitor that checks for equivalence of [Element] properties.
@@ -555,7 +586,7 @@
             'Missing member for $member2 in\n ${members1.join('\n ')}';
         if (member2.isAbstractField) {
           // TODO(johnniwinther): Ensure abstract fields are handled correctly.
-          print(message);
+          //print(message);
           continue;
         } else {
           throw message;
@@ -566,7 +597,7 @@
             'Missing member for $member1 in\n ${members2.join('\n ')}';
         if (member1.isAbstractField) {
           // TODO(johnniwinther): Ensure abstract fields are handled correctly.
-          print(message);
+          //print(message);
           continue;
         } else {
           throw message;
@@ -864,273 +895,3 @@
     // TODO(johnniwinther): Check members.
   }
 }
-
-/// Visitor that checks for equivalence of [DartType]s.
-class TypeEquivalence implements DartTypeVisitor<dynamic, DartType> {
-  const TypeEquivalence();
-
-  void visit(DartType type1, DartType type2) {
-    check(type1, type2, 'kind', type1.kind, type2.kind);
-    type1.accept(this, type2);
-  }
-
-  @override
-  void visitDynamicType(DynamicType type, DynamicType other) {
-  }
-
-  @override
-  void visitFunctionType(FunctionType type, FunctionType other) {
-    checkTypeLists(
-        type, other, 'parameterTypes',
-        type.parameterTypes, other.parameterTypes);
-    checkTypeLists(
-        type, other, 'optionalParameterTypes',
-        type.optionalParameterTypes, other.optionalParameterTypes);
-    checkTypeLists(
-        type, other, 'namedParameterTypes',
-        type.namedParameterTypes, other.namedParameterTypes);
-    for (int i = 0; i < type.namedParameters.length; i++) {
-      if (type.namedParameters[i] != other.namedParameters[i]) {
-        throw "Named parameter '$type.namedParameters[i]' <> "
-              "'${other.namedParameters[i]}'";
-      }
-    }
-  }
-
-  void visitGenericType(GenericType type, GenericType other) {
-    checkElementIdentities(
-        type, other, 'element',
-        type.element, other.element);
-    checkTypeLists(
-        type, other, 'typeArguments',
-        type.typeArguments, other.typeArguments);
-  }
-
-  @override
-  void visitMalformedType(MalformedType type, MalformedType other) {
-  }
-
-  @override
-  void  visitStatementType(StatementType type, StatementType other) {
-    throw new UnsupportedError("Unsupported type: $type");
-  }
-
-  @override
-  void visitTypeVariableType(TypeVariableType type, TypeVariableType other) {
-    checkElementIdentities(
-        type, other, 'element',
-        type.element, other.element);
-  }
-
-  @override
-  void visitVoidType(VoidType type, VoidType argument) {
-  }
-
-  @override
-  void visitInterfaceType(InterfaceType type, InterfaceType other) {
-    visitGenericType(type, other);
-  }
-
-  @override
-  void visitTypedefType(TypedefType type, TypedefType other) {
-    visitGenericType(type, other);
-  }
-}
-
-/// Visitor that checks for structural equivalence of [ConstantExpression]s.
-class ConstantEquivalence
-    implements ConstantExpressionVisitor<dynamic, ConstantExpression> {
-  const ConstantEquivalence();
-
-  @override
-  visit(ConstantExpression exp1, ConstantExpression exp2) {
-    if (identical(exp1, exp2)) return;
-    check(exp1, exp2, 'kind', exp1.kind, exp2.kind);
-    exp1.accept(this, exp2);
-  }
-
-  @override
-  visitBinary(BinaryConstantExpression exp1, BinaryConstantExpression exp2) {
-    check(exp1, exp2, 'operator', exp1.operator, exp2.operator);
-    checkConstants(exp1, exp2, 'left', exp1.left, exp2.left);
-    checkConstants(exp1, exp2, 'right', exp1.right, exp2.right);
-  }
-
-  @override
-  visitConcatenate(ConcatenateConstantExpression exp1,
-                   ConcatenateConstantExpression exp2) {
-    checkConstantLists(
-        exp1, exp2, 'expressions',
-        exp1.expressions, exp2.expressions);
-  }
-
-  @override
-  visitConditional(ConditionalConstantExpression exp1,
-                   ConditionalConstantExpression exp2) {
-    checkConstants(
-        exp1, exp2, 'condition', exp1.condition, exp2.condition);
-    checkConstants(exp1, exp2, 'trueExp', exp1.trueExp, exp2.trueExp);
-    checkConstants(exp1, exp2, 'falseExp', exp1.falseExp, exp2.falseExp);
-  }
-
-  @override
-  visitConstructed(ConstructedConstantExpression exp1,
-                   ConstructedConstantExpression exp2) {
-    checkTypes(
-        exp1, exp2, 'type',
-        exp1.type, exp2.type);
-    checkElementIdentities(
-        exp1, exp2, 'target',
-        exp1.target, exp2.target);
-    checkConstantLists(
-        exp1, exp2, 'arguments',
-        exp1.arguments, exp2.arguments);
-    check(exp1, exp2, 'callStructure', exp1.callStructure, exp2.callStructure);
-  }
-
-  @override
-  visitFunction(FunctionConstantExpression exp1,
-                FunctionConstantExpression exp2) {
-    checkElementIdentities(
-        exp1, exp2, 'element',
-        exp1.element, exp2.element);
-  }
-
-  @override
-  visitIdentical(IdenticalConstantExpression exp1,
-                 IdenticalConstantExpression exp2) {
-    checkConstants(exp1, exp2, 'left', exp1.left, exp2.left);
-    checkConstants(exp1, exp2, 'right', exp1.right, exp2.right);
-  }
-
-  @override
-  visitList(ListConstantExpression exp1, ListConstantExpression exp2) {
-    checkTypes(
-        exp1, exp2, 'type',
-        exp1.type, exp2.type);
-    checkConstantLists(
-        exp1, exp2, 'values',
-        exp1.values, exp2.values);
-  }
-
-  @override
-  visitMap(MapConstantExpression exp1, MapConstantExpression exp2) {
-    checkTypes(
-        exp1, exp2, 'type',
-        exp1.type, exp2.type);
-    checkConstantLists(
-        exp1, exp2, 'keys',
-        exp1.keys, exp2.keys);
-    checkConstantLists(
-        exp1, exp2, 'values',
-        exp1.values, exp2.values);
-  }
-
-  @override
-  visitNamed(NamedArgumentReference exp1, NamedArgumentReference exp2) {
-    check(exp1, exp2, 'name', exp1.name, exp2.name);
-  }
-
-  @override
-  visitPositional(PositionalArgumentReference exp1,
-                  PositionalArgumentReference exp2) {
-    check(exp1, exp2, 'index', exp1.index, exp2.index);
-  }
-
-  @override
-  visitSymbol(SymbolConstantExpression exp1, SymbolConstantExpression exp2) {
-    // TODO: implement visitSymbol
-  }
-
-  @override
-  visitType(TypeConstantExpression exp1, TypeConstantExpression exp2) {
-    checkTypes(
-        exp1, exp2, 'type',
-        exp1.type, exp2.type);
-  }
-
-  @override
-  visitUnary(UnaryConstantExpression exp1, UnaryConstantExpression exp2) {
-    check(exp1, exp2, 'operator', exp1.operator, exp2.operator);
-    checkConstants(
-        exp1, exp2, 'expression', exp1.expression, exp2.expression);
-  }
-
-  @override
-  visitVariable(VariableConstantExpression exp1,
-                VariableConstantExpression exp2) {
-    checkElementIdentities(
-        exp1, exp2, 'element',
-        exp1.element, exp2.element);
-  }
-
-  @override
-  visitBool(BoolConstantExpression exp1, BoolConstantExpression exp2) {
-    check(exp1, exp2, 'primitiveValue',
-          exp1.primitiveValue, exp2.primitiveValue);
-  }
-
-  @override
-  visitDouble(DoubleConstantExpression exp1, DoubleConstantExpression exp2) {
-    check(exp1, exp2, 'primitiveValue',
-          exp1.primitiveValue, exp2.primitiveValue);
-  }
-
-  @override
-  visitInt(IntConstantExpression exp1, IntConstantExpression exp2) {
-    check(exp1, exp2, 'primitiveValue',
-          exp1.primitiveValue, exp2.primitiveValue);
-  }
-
-  @override
-  visitNull(NullConstantExpression exp1, NullConstantExpression exp2) {
-    // Do nothing.
-  }
-
-  @override
-  visitString(StringConstantExpression exp1, StringConstantExpression exp2) {
-    check(exp1, exp2, 'primitiveValue',
-          exp1.primitiveValue, exp2.primitiveValue);
-  }
-
-  @override
-  visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp1,
-                           BoolFromEnvironmentConstantExpression exp2) {
-    checkConstants(exp1, exp2, 'name', exp1.name, exp2.name);
-    checkConstants(
-        exp1, exp2, 'defaultValue',
-        exp1.defaultValue, exp2.defaultValue);
-  }
-
-  @override
-  visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp1,
-                          IntFromEnvironmentConstantExpression exp2) {
-    checkConstants(exp1, exp2, 'name', exp1.name, exp2.name);
-    checkConstants(
-        exp1, exp2, 'defaultValue',
-        exp1.defaultValue, exp2.defaultValue);
-  }
-
-  @override
-  visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp1,
-                             StringFromEnvironmentConstantExpression exp2) {
-    checkConstants(exp1, exp2, 'name', exp1.name, exp2.name);
-    checkConstants(
-        exp1, exp2, 'defaultValue',
-        exp1.defaultValue, exp2.defaultValue);
-  }
-
-  @override
-  visitStringLength(StringLengthConstantExpression exp1,
-                    StringLengthConstantExpression exp2) {
-    checkConstants(
-        exp1, exp2, 'expression',
-        exp1.expression, exp2.expression);
-  }
-
-  @override
-  visitDeferred(DeferredConstantExpression exp1,
-                DeferredConstantExpression exp2) {
-    // TODO: implement visitDeferred
-  }
-}
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 1d3e26d..446062f 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -26,6 +26,7 @@
 import 'package:compiler/src/util/util.dart';
 
 import 'mock_compiler.dart';
+import 'options_helper.dart';
 import 'parser_helper.dart';
 
 final MessageKind NOT_ASSIGNABLE = MessageKind.NOT_ASSIGNABLE;
@@ -2555,7 +2556,7 @@
   Token tokens = scan(text);
   NodeListener listener = new NodeListener(
       const ScannerOptions(), compiler.reporter, null);
-  Parser parser = new Parser(listener);
+  Parser parser = new Parser(listener, new MockParserOptions());
   parser.parseStatement(tokens);
   Node node = listener.popNode();
   Element compilationUnit =
@@ -2601,7 +2602,7 @@
   Token tokens = scan(text);
   NodeListener listener = new NodeListener(
       const ScannerOptions(), compiler.reporter, null);
-  Parser parser = new Parser(listener,
+  Parser parser = new Parser(listener, new MockParserOptions(),
       asyncAwaitKeywordsEnabled: element.asyncMarker != AsyncMarker.SYNC);
   parser.parseStatement(tokens);
   Node node = listener.popNode();
diff --git a/tests/compiler/dart2js/unparser2_test.dart b/tests/compiler/dart2js/unparser2_test.dart
index 8ede8c9..7053e6a 100644
--- a/tests/compiler/dart2js/unparser2_test.dart
+++ b/tests/compiler/dart2js/unparser2_test.dart
@@ -19,6 +19,8 @@
          LibraryElementX;
 import "package:compiler/src/script.dart";
 
+import "options_helper.dart";
+
 main() {
   testClassDef();
   testClass1Field();
@@ -84,7 +86,6 @@
   Expect.equals(expectedResult, doUnparse(code));
 }
 
-
 String doUnparse(String source) {
   MessageCollector diagnosticListener = new MessageCollector();
   Script script = new Script(null, null, null);
@@ -94,7 +95,7 @@
   Token beginToken = scanner.tokenize();
   NodeListener listener = new NodeListener(
       const ScannerOptions(), diagnosticListener, element);
-  Parser parser = new Parser(listener);
+  Parser parser = new Parser(listener, new MockParserOptions());
   parser.parseUnit(beginToken);
   Node node = listener.popNode();
   Expect.isTrue(listener.nodes.isEmpty);
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 4552337..fe92613 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -159,7 +159,7 @@
 [ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 regexp/global_test: Skip # Timeout. Issue 21709 and 21708
 
-[ $runtime != vm && $runtime != dart_precompiled && $compiler != dart2analyzer]
+[ $runtime != vm && $runtime != dart_precompiled && $runtime != dart_product && $compiler != dart2analyzer]
 data_resource_test: RuntimeError # Issue 23825 (not implemented yet).
 file_resource_test: Skip, OK # VM specific test, uses dart:io.
 http_resource_test: Skip, OK # VM specific test, uses dart:io.
@@ -203,6 +203,8 @@
 big_integer_parsed_mul_div_vm_test: Pass, Timeout # --no_intrinsify
 int_parse_radix_test: Pass, Timeout # --no_intrinsify
 
-[ $runtime == dart_product ]
+[ $compiler == precompiler || $runtime == dart_product ]
 data_resource_test: Skip # Resolve URI not supported yet in product mode.
 package_resource_test: Skip # Resolve URI not supported yet in product mode.
+file_resource_test: Skip # Resolve URI not supported yet in product mode.
+http_resource_test: Skip # Resolve URI not supported yet in product mode.
\ No newline at end of file
diff --git a/tests/html/html.status b/tests/html/html.status
index 742f19d..6862539 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -39,6 +39,7 @@
 [ $compiler == dart2js && $browser ]
 custom/created_callback_test: Fail # Support for created constructor. Issue 14835
 fontface_loaded_test: Fail # Support for promises.
+js_test/JsArray: RuntimeError # Issue 26197
 
 [ $compiler == dart2js && ($runtime == safari || $runtime == safarimobilesim || $runtime == ff  || $ie) ]
 custom/entered_left_view_test/viewless_document: Fail # Polyfill does not handle this
diff --git a/tests/language/vm/optimized_try_catch_cha_test.dart b/tests/language/vm/optimized_try_catch_cha_test.dart
new file mode 100644
index 0000000..a75b0d2
--- /dev/null
+++ b/tests/language/vm/optimized_try_catch_cha_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization_counter_threshold=100 --no-use-osr --no-background_compilation
+
+// Test CHA-based optimizations in presence of try-catch.
+
+import "package:expect/expect.dart";
+
+bar(i) {
+  if (i == 11) throw 123;
+}
+
+class A {
+  var f = 42;
+  
+  foo(i) {
+    do {
+      try {
+        bar(i);
+      } catch (e, s) {
+        Expect.equals(123, e);
+      }
+    } while (i < 0);
+    return f;
+  }
+}
+
+class B extends A {
+
+}
+
+main() {
+  var result;
+  for (var i = 0; i < 200; i++) {
+    try {
+      result = new B().foo(i);
+    } catch (e) { }
+  }
+  Expect.equals(42, result);
+}
diff --git a/tests/standalone/precompilation_dart2js_test.dart b/tests/standalone/precompilation_dart2js_test.dart
deleted file mode 100644
index b964726..0000000
--- a/tests/standalone/precompilation_dart2js_test.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test generating and running a simple precompiled snapshot of this script.
-
-import 'dart:io';
-
-main(List args) {
-  if (args.length > 0 && args[0] == "--hello") {
-    print("Hello");
-    return;
-  }
-
-  var cc, cc_flags, shared, libname;
-  if (Platform.isLinux) {
-    cc = 'gcc';
-    shared = '-shared';
-    libname = 'libprecompiled.so';
-  } else if (Platform.isMacOS) {
-    cc = 'clang';
-    shared = '-dynamiclib';
-    libname = 'libprecompiled.dylib';
-  } else {
-    print("Test only supports Linux and Mac");
-    return;
-  }
-
-  if (Platform.version.contains("x64")) {
-    cc_flags = "-m64";
-  } else if (Platform.version.contains("simarm64")) {
-    cc_flags = "-m64";
-  } else if (Platform.version.contains("simarm")) {
-    cc_flags = "-m32";
-  } else if (Platform.version.contains("simmips")) {
-    cc_flags = "-m32";
-  } else if (Platform.version.contains("arm")) {
-    cc_flags = "";
-  } else if (Platform.version.contains("mips")) {
-    cc_flags = "-EL";
-  } else {
-    print("Architecture not supported: ${Platform.version}");
-    return;
-  }
-
-  var abs_package_root = Uri.parse(Platform.packageRoot).toFilePath();
-  var dart_executable =
-      Directory.current.path + Platform.pathSeparator + Platform.executable;
-  Directory tmp;
-  try {
-    tmp = Directory.current.createTempSync("temp_precompilation_test");
-    var exec = "${dart_executable}_bootstrap";
-    var args = ["--package-root=$abs_package_root",
-                "--gen-precompiled-snapshot",
-                "${abs_package_root}compiler/src/dart2js.dart"];
-    print("$exec ${args.join(' ')}");
-    var result = Process.runSync(exec, args, workingDirectory: tmp.path);
-    if (result.exitCode != 0) {
-      print(result.stdout);
-      print(result.stderr);
-      throw "Snapshot generation failed.";
-    }
-
-    // Check if gcc is present, and skip test if it is not.
-    try {
-      result = Process.runSync(
-          cc,
-          ["--version"],
-          workingDirectory: tmp.path);
-      if (result.exitCode != 0) {
-        throw "$cc --version failed.";
-      }
-    } catch(e) {
-      print("Skipping test because $cc is not present: $e");
-      return;
-    }
-
-    result = Process.runSync(
-        cc,
-        [shared, cc_flags, "-nostartfiles", "-o", libname, "precompiled.S"],
-        workingDirectory: tmp.path);
-    if (result.exitCode != 0) {
-      print(result.stdout);
-      print(result.stderr);
-      throw "Shared library creation failed!";
-    }
-
-    var ld_library_path = new String.fromEnvironment("LD_LIBRARY_PATH");
-    ld_library_path = "${ld_library_path}:${tmp.path}";
-    exec = "${dart_executable}_precompiled_runtime";
-    args = ["--run-precompiled-snapshot", "ignored_script", "--version"];
-    print("LD_LIBRARY_PATH=$ld_library_path $exec ${args.join(' ')}");
-    result = Process.runSync(exec, args,
-       workingDirectory: tmp.path,
-       environment: {"LD_LIBRARY_PATH": ld_library_path});
-    if (result.exitCode != 0) {
-      print(result.stdout);
-      print(result.stderr);
-      throw "Precompiled binary failed.";
-    }
-    print(result.stdout);
-    if (!result.stdout.contains("Dart-to-JavaScript compiler")) {
-      throw "Precompiled binary output mismatch.";
-    }
-  } finally {
-    tmp?.deleteSync(recursive: true);
-  }
-}
diff --git a/tests/standalone/precompilation_test.dart b/tests/standalone/precompilation_test.dart
deleted file mode 100644
index ad493c9..0000000
--- a/tests/standalone/precompilation_test.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test generating and running a simple precompiled snapshot of this script.
-
-import 'dart:io';
-
-main(List args) {
-  if (args.length > 0 && args[0] == "--hello") {
-    print("Hello");
-    return;
-  }
-
-  var cc, cc_flags, shared, libname;
-  if (Platform.isLinux) {
-    cc = 'gcc';
-    shared = '-shared';
-    libname = 'libprecompiled.so';
-  } else if (Platform.isMacOS) {
-    cc = 'clang';
-    shared = '-dynamiclib';
-    libname = 'libprecompiled.dylib';
-  } else {
-    print("Test only supports Linux and Mac");
-    return;
-  }
-
-  if (Platform.version.contains("x64")) {
-    cc_flags = "-m64";
-  } else if (Platform.version.contains("simarm64")) {
-    cc_flags = "-m64";
-  } else if (Platform.version.contains("simarm")) {
-    cc_flags = "-m32";
-  } else if (Platform.version.contains("simmips")) {
-    cc_flags = "-m32";
-  } else if (Platform.version.contains("arm")) {
-    cc_flags = "";
-  } else if (Platform.version.contains("mips")) {
-    cc_flags = "-EL";
-  } else {
-    print("Architecture not supported: ${Platform.version}");
-    return;
-  }
-
-  var dart_executable =
-      Directory.current.path + Platform.pathSeparator + Platform.executable;
-  Directory tmp;
-  try {
-    tmp = Directory.current.createTempSync("temp_precompilation_test");
-    var result = Process.runSync(
-       "${dart_executable}_bootstrap",
-       ["--gen-precompiled-snapshot", Platform.script.path],
-       workingDirectory: tmp.path);
-    if (result.exitCode != 0) {
-      print(result.stdout);
-      print(result.stderr);
-      throw "Snapshot generation failed.";
-    }
-
-    // Check if gcc is present, and skip test if it is not.
-    try {
-      result = Process.runSync(
-          cc,
-          ["--version"],
-          workingDirectory: tmp.path);
-      if (result.exitCode != 0) {
-        throw "$cc --version failed.";
-      }
-    } catch(e) {
-      print("Skipping test because $cc is not present: $e");
-      return;
-    }
-
-    result = Process.runSync(
-        cc,
-        [shared, cc_flags, "-nostartfiles", "-o", libname, "precompiled.S"],
-        workingDirectory: tmp.path);
-    if (result.exitCode != 0) {
-      print(result.stdout);
-      print(result.stderr);
-      throw "Shared library creation failed!";
-    }
-
-    var ld_library_path = new String.fromEnvironment("LD_LIBRARY_PATH");
-    ld_library_path = "${ld_library_path}:${tmp.path}";
-
-    result = Process.runSync(
-       "${dart_executable}_precompiled_runtime",
-       ["--run-precompiled-snapshot", "ignored_script", "--hello"],
-       workingDirectory: tmp.path,
-       environment: {"LD_LIBRARY_PATH": ld_library_path});
-    if (result.exitCode != 0) {
-      print(result.stdout);
-      print(result.stderr);
-      throw "Precompiled binary failed.";
-    }
-    print(result.stdout);
-    if (result.stdout != "Hello\n") {
-      throw "Precompiled binary output mismatch.";
-    }
-  } finally {
-    tmp?.deleteSync(recursive: true);
-  }
-}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 730d959..4103c33 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -69,8 +69,6 @@
 out_of_memory_test: Skip
 map_insert_remove_oom_test: Skip  # Issue 24571
 verbose_gc_to_bmu_test: Skip
-precompilation_test: Skip # Standalone only test.
-precompilation_dart2js_test: Skip # Standalone only test.
 regress_26031_test: SkipByDesign # Standalone only test
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
@@ -109,24 +107,11 @@
 issue14236_test: Skip # dart2js does not deal with Script snapshots.
 unboxed_int_converter_test: Skip
 pair_location_remapping_test: Skip
-precompilation_test: Skip # Standalone only test.
-precompilation_dart2js_test: Skip # Standalone only test.
 regress_25335_test: Skip # Int64List not supported.
 
 [ $compiler == dart2js && $cps_ir && $checked ]
 *: Skip # `assert` not implemented
 
-[ ($runtime == vm || $runtime == dart_product) ]
-precompilation_dart2js_test: Pass, Slow
-
-[ ($runtime == vm || $runtime == dart_product) && $arch == ia32 ]
-precompilation_test: SkipByDesign # Not expected to pass on ia32.
-precompilation_dart2js_test: SkipByDesign # Not expected to pass on ia32.
-
-[ ($runtime == vm || $runtime == dart_product) && ($arch == mips || $arch == arm || $arch == arm64) ]
-precompilation_test: SkipSlow
-precompilation_dart2js_test: SkipSlow
-
 [ ($runtime == vm || $runtime == dart_product) && ($arch == arm || $arch == arm64) ]
 io/file_stream_test: Skip # Issue 26109
 
@@ -223,13 +208,12 @@
 [ $noopt || $compiler == precompiler ]
 map_insert_remove_oom_test: Skip # Heap limit too low. Increasing iteration count to make a higher limit a meaningful test makes it too slow for simarm[64] bots.
 io/web_socket_test: Pass, RuntimeError # Issue 24674
-precompilation_test: Skip # Platform.executable
-precompilation_dart2js_test: Skip  # Platform.executable
 io/test_extension_test: Skip # Platform.executable
 io/test_extension_fail_test: Skip # Platform.executable
 io/platform_test: Skip # Platform.executable
 io/code_collection_test: Skip # Platform.executable
 full_coverage_test: Skip # Platform.executable
+regress_26031_test: Skip # Platform.resolvedExecutable
 
 [ $runtime == dart_precompiled ]
 io/compile_all_test: Crash # Incompatible flag --compile_all
@@ -239,8 +223,6 @@
 
 [ $runtime == dart_precompiled || $runtime == dart_product ]
 debugger/*: Skip
-precompilation_test: Skip # Platform.executable
-precompilation_dart2js_test: Skip # Platform.executable
 full_coverage_test: Skip # Platform.executable
 http_launch_test: Skip # Platform.executable
 io/addlatexhash_test: Skip # Platform.executable
@@ -254,7 +236,6 @@
 io/snapshot_fail_test: Skip # Platform.executable
 io/stdin_sync_test: Skip # Platform.executable
 io/test_extension_fail_test: Skip # Platform.executable
-precompilation_test: Skip # Platform.executable
 io/file_read_special_device_test: Skip # Platform.executable
 verbose_gc_to_bmu_test: Skip # Platform.executable
 io/http_server_close_response_after_error_test: Skip # Platform.executable
@@ -294,7 +275,7 @@
 no_support_timeline_test: SkipByDesign
 
 # Following tests are skipped on dart_product as package mapping is not supported.
-[ $runtime == dart_product ]
+[ $runtime == dart_precompiled || $runtime == dart_product ]
 package/scenarios/packages_file_strange_formatting/mixed_line_ends_test: Skip
 package/scenarios/packages_file_strange_formatting/empty_lines_test: Skip
 package/scenarios/invalid/invalid_utf8_test: Skip
diff --git a/tools/VERSION b/tools/VERSION
index a42c595..2ca4386 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 16
 PATCH 0
-PRERELEASE 3
+PRERELEASE 4
 PRERELEASE_PATCH 0
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index eea84da..ee710f8 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -8,8 +8,8 @@
 # Now we need to override some settings and add some new ones.
 
 vars.update({
-  "dartium_chromium_commit": "b16942297fc65fd478c6f46afd1c3aaecde77009",
-  "dartium_webkit_commit": "2223637e68ed9a95ee9bf07c2e597262e75f4b0c",
+  "dartium_chromium_commit": "f41b46133f75612579588ba14265a7e241406b0e",
+  "dartium_webkit_commit": "d4cfc86d765d59fd7048c7272b924a1a9e9ce5fe",
   "chromium_base_revision": "338390",
 
   # We use mirrors of all github repos to guarantee reproducibility and
diff --git a/tools/dom/scripts/generate_blink_file.py b/tools/dom/scripts/generate_blink_file.py
index 4beb0a5..cdac697 100644
--- a/tools/dom/scripts/generate_blink_file.py
+++ b/tools/dom/scripts/generate_blink_file.py
@@ -40,6 +40,7 @@
     'Document.createTextNode',
     'Window.location',
     'Location.href',
+    'Location.hash',
     'Node.querySelector',
 
     'HTMLElement.hidden',
@@ -130,6 +131,7 @@
   // In any case, returns a typed JS wrapper compatibile with dart:html and the new
   // typed JS Interop.
   static defineInterceptorCustomElement(jsObject, Type type) native "Utils_defineInterceptorCustomElement";
+  static defineInterceptor(jsObject, Type type) native "Utils_defineInterceptor";
   static setInstanceInterceptor(o, Type type, {bool customElement: false}) native "Utils_setInstanceInterceptor";
 
   // This method will throw if the element isn't actually a real Element.
diff --git a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
index 7768aad..a52e369 100644
--- a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
@@ -362,6 +362,10 @@
     _registerCustomElement(JS('', 'window'), this, tag, customElementClass,
         extendsTag);
 $else
+    // Hack to setup an interceptor for HTMLElement so it isn't changed when a custom element is created.
+    var jsHTMLElementPrototype = js.JsNative.getProperty(js.JsNative.getProperty(js.context, 'HTMLElement'),'prototype');
+    _blink.Blink_Utils.defineInterceptor(jsHTMLElementPrototype, HtmlElement.instanceRuntimeType);
+
     // Figure out which DOM class is being extended from the user's Dart class.
     var classMirror = reflectClass(customElementClass);
 
diff --git a/tools/dom/templates/html/impl/impl_WebGLRenderingContext.darttemplate b/tools/dom/templates/html/impl/impl_WebGLRenderingContext.darttemplate
index 029a38b..cb6f865 100644
--- a/tools/dom/templates/html/impl/impl_WebGLRenderingContext.darttemplate
+++ b/tools/dom/templates/html/impl/impl_WebGLRenderingContext.darttemplate
@@ -18,7 +18,7 @@
   @Deprecated("Use texImage2D")
   void texImage2DUntyped(int targetTexture, int levelOfDetail,
       int internalFormat, int format, int type, data) {
-    texImage2D(targetText, levelOfDetail, internalFormat, format, type, data);
+    texImage2D(targetTexture, levelOfDetail, internalFormat, format, type, data);
   }
 
   /**
@@ -63,16 +63,14 @@
    */
   @Deprecated("Use bufferData")
   void bufferDataTyped(int target, TypedData data, int usage) {
-    bufferData2D(targetTexture, levelOfDetail, xOffset, yOffset,
-        format, type, data);
+    bufferData(target, data, usage);
   }
 
   /**
    * Set the bufferSubData to [data].
    */
   @Deprecated("Use bufferSubData")
-  void bufferSubDataTyped(int target, TypedData data, int usage) {
-    bufferSubData2D(targetTexture, levelOfDetail, xOffset, yOffset,
-        format, type, data);
+  void bufferSubDataTyped(int target, int offset, TypedData data) {
+    bufferSubData(target, offset, data);
   }
 }
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart
index d514bd6..1d39071 100644
--- a/tools/testing/dart/android.dart
+++ b/tools/testing/dart/android.dart
@@ -12,17 +12,14 @@
 import "path.dart";
 import "utils.dart";
 
-Future _executeCommand(String executable,
-                       List<String> args,
-                       [String stdin = ""]) {
+Future _executeCommand(String executable, List<String> args,
+    [String stdin = ""]) {
   return _executeCommandRaw(executable, args, stdin).then((results) => null);
 }
 
-Future _executeCommandGetOutput(String executable,
-                                List<String> args,
-                                [String stdin = ""]) {
-  return _executeCommandRaw(executable, args, stdin)
-      .then((output) => output);
+Future _executeCommandGetOutput(String executable, List<String> args,
+    [String stdin = ""]) {
+  return _executeCommandRaw(executable, args, stdin).then((output) => output);
 }
 
 /**
@@ -32,11 +29,12 @@
  * If the exit code of the process was nonzero it will complete with an error.
  * If starting the process failed, it will complete with an error as well.
  */
-Future _executeCommandRaw(String executable,
-                          List<String> args,
-                          [String stdin = ""]) {
+Future _executeCommandRaw(String executable, List<String> args,
+    [String stdin = ""]) {
   Future<String> getOutput(Stream<List<int>> stream) {
-    return stream.transform(UTF8.decoder).toList()
+    return stream
+        .transform(UTF8.decoder)
+        .toList()
         .then((data) => data.join(""));
   }
 
@@ -47,16 +45,18 @@
     }
     process.stdin.close();
 
-    var futures = [getOutput(process.stdout),
-                   getOutput(process.stderr),
-                   process.exitCode];
+    var futures = [
+      getOutput(process.stdout),
+      getOutput(process.stderr),
+      process.exitCode
+    ];
     return Future.wait(futures).then((results) {
       bool success = results[2] == 0;
       if (!success) {
         var error = "Running: '\$ $executable ${args.join(' ')}' failed:"
-                    "stdout: \n ${results[0]}"
-                    "stderr: \n ${results[1]}"
-                    "exitCode: \n ${results[2]}";
+            "stdout: \n ${results[0]}"
+            "stderr: \n ${results[1]}"
+            "exitCode: \n ${results[2]}";
         throw new Exception(error);
       } else {
         DebugLogger.info("Success: $executable finished");
@@ -153,8 +153,18 @@
  */
 class AndroidHelper {
   static Future createAvd(String name, String target) {
-    var args = ['--silent', 'create', 'avd', '--name', '$name',
-                '--target', '$target', '--force', '--abi', 'armeabi-v7a'];
+    var args = [
+      '--silent',
+      'create',
+      'avd',
+      '--name',
+      '$name',
+      '--target',
+      '$target',
+      '--force',
+      '--abi',
+      'armeabi-v7a'
+    ];
     // We're adding newlines to stdin to simulate <enter>.
     return _executeCommand("android", args, "\n\n\n\n");
   }
@@ -189,15 +199,15 @@
     checkUntilBooted() {
       _adbCommandGetOutput(['shell', 'getprop', 'sys.boot_completed'])
           .then((String stdout) {
-            stdout = stdout.trim();
-            if (stdout == '1') {
-              completer.complete();
-            } else {
-              new Timer(timeout, checkUntilBooted);
-            }
-          }).catchError((error) {
-            new Timer(timeout, checkUntilBooted);
-          });
+        stdout = stdout.trim();
+        if (stdout == '1') {
+          completer.complete();
+        } else {
+          new Timer(timeout, checkUntilBooted);
+        }
+      }).catchError((error) {
+        new Timer(timeout, checkUntilBooted);
+      });
     }
     checkUntilBooted();
     return completer.future;
@@ -250,9 +260,16 @@
    * Start the given intent on the device.
    */
   Future startActivity(Intent intent) {
-    var arguments = ['shell', 'am', 'start', '-W',
-                     '-a', intent.action,
-                     '-n', "${intent.package}/${intent.activity}"];
+    var arguments = [
+      'shell',
+      'am',
+      'start',
+      '-W',
+      '-a',
+      intent.action,
+      '-n',
+      "${intent.package}/${intent.activity}"
+    ];
     if (intent.dataUri != null) {
       arguments.addAll(['-d', intent.dataUri]);
     }
@@ -312,10 +329,12 @@
     return Process.run('adb', ['devices']).then((ProcessResult result) {
       if (result.exitCode != 0) {
         throw new Exception("Could not list devices [stdout: ${result.stdout},"
-                            "stderr: ${result.stderr}]");
+            "stderr: ${result.stderr}]");
       }
-      return _deviceLineRegexp.allMatches(result.stdout)
-          .map((Match m) => m.group(1)).toList();
+      return _deviceLineRegexp
+          .allMatches(result.stdout)
+          .map((Match m) => m.group(1))
+          .toList();
     });
   }
 }
@@ -331,4 +350,3 @@
 
   Intent(this.action, this.package, this.activity, [this.dataUri]);
 }
-
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index a6d061c..6e37549 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -7,6 +7,7 @@
 import "dart:convert" show LineSplitter, UTF8, JSON;
 import "dart:core";
 import "dart:io";
+import "dart:math" show max, min;
 
 import 'android.dart';
 import 'http_server.dart';
@@ -66,9 +67,8 @@
 
   Browser();
 
-  factory Browser.byName(String name,
-                         String executablePath,
-                         [bool checkedMode = false]) {
+  factory Browser.byName(String name, String executablePath,
+      [bool checkedMode = false]) {
     var browser;
     if (name == 'firefox') {
       browser = new Firefox();
@@ -89,12 +89,21 @@
     return browser;
   }
 
-  static const List<String> SUPPORTED_BROWSERS =
-    const ['safari', 'ff', 'firefox', 'chrome', 'ie9', 'ie10',
-           'ie11', 'dartium'];
+  static const List<String> SUPPORTED_BROWSERS = const [
+    'safari',
+    'ff',
+    'firefox',
+    'chrome',
+    'ie9',
+    'ie10',
+    'ie11',
+    'dartium'
+  ];
 
-  static const List<String> BROWSERS_WITH_WINDOW_SUPPORT =
-      const ['ie11', 'ie10'];
+  static const List<String> BROWSERS_WITH_WINDOW_SUPPORT = const [
+    'ie11',
+    'ie10'
+  ];
 
   // TODO(kustermann): add standard support for chrome on android
   static bool supportedBrowser(String name) {
@@ -143,10 +152,10 @@
    * Start the browser using the supplied argument.
    * This sets up the error handling and usage logging.
    */
-  Future<bool> startBrowser(String command,
-                            List<String> arguments,
-                            {Map<String,String> environment}) {
-    return Process.start(command, arguments, environment: environment)
+  Future<bool> startBrowserProcess(String command, List<String> arguments,
+      {Map<String, String> environment}) {
+    return Process
+        .start(command, arguments, environment: environment)
         .then((startedProcess) {
       _logEvent("Started browser using $command ${arguments.join(' ')}");
       process = startedProcess;
@@ -168,7 +177,7 @@
       // handles alive even though the direct subprocess is dead.
       Timer watchdogTimer;
 
-      void closeStdout([_]){
+      void closeStdout([_]) {
         if (!stdoutIsDone) {
           stdoutDone.complete();
           stdoutIsDone = true;
@@ -191,7 +200,7 @@
       }
 
       stdoutSubscription =
-        process.stdout.transform(UTF8.decoder).listen((data) {
+          process.stdout.transform(UTF8.decoder).listen((data) {
         _addStdout(data);
       }, onError: (error) {
         // This should _never_ happen, but we really want this in the log
@@ -200,21 +209,21 @@
       }, onDone: closeStdout);
 
       stderrSubscription =
-        process.stderr.transform(UTF8.decoder).listen((data) {
+          process.stderr.transform(UTF8.decoder).listen((data) {
         _addStderr(data);
       }, onError: (error) {
         // This should _never_ happen, but we really want this in the log
         // if it actually does due to dart:io or vm bug.
         _logEvent("An error occured in the process stderr handling: $error");
-      },  onDone: closeStderr);
+      }, onDone: closeStderr);
 
       process.exitCode.then((exitCode) {
         _logEvent("Browser closed with exitcode $exitCode");
 
         if (!stdoutIsDone || !stderrIsDone) {
           watchdogTimer = new Timer(MAX_STDIO_DELAY, () {
-            DebugLogger.warning(
-                "$MAX_STDIO_DELAY_PASSED_MESSAGE (browser: $this)");
+            DebugLogger
+                .warning("$MAX_STDIO_DELAY_PASSED_MESSAGE (browser: $this)");
             watchdogTimer = null;
             stdoutSubscription.cancel();
             stderrSubscription.cancel();
@@ -254,7 +263,7 @@
    * where it will be reported for failing tests.  Used to report which
    * android device a failing test is running on.
    */
-  void logBrowserInfoToTestBrowserOutput() { }
+  void logBrowserInfoToTestBrowserOutput() {}
 
   String toString();
 
@@ -273,19 +282,22 @@
    * Directories where safari stores state. We delete these if the deleteCache
    * is set
    */
-  static const List<String> CACHE_DIRECTORIES =
-      const ["Library/Caches/com.apple.Safari",
-             "Library/Safari",
-             "Library/Saved Application State/com.apple.Safari.savedState",
-             "Library/Caches/Metadata/Safari"];
-
+  static const List<String> CACHE_DIRECTORIES = const [
+    "Library/Caches/com.apple.Safari",
+    "Library/Safari",
+    "Library/Saved Application State/com.apple.Safari.savedState",
+    "Library/Caches/Metadata/Safari"
+  ];
 
   Future<bool> allowPopUps() {
     var command = "defaults";
-    var args = ["write", "com.apple.safari",
-                "com.apple.Safari.ContentPageGroupIdentifier."
-                "WebKit2JavaScriptCanOpenWindowsAutomatically",
-                "1"];
+    var args = [
+      "write",
+      "com.apple.safari",
+      "com.apple.Safari.ContentPageGroupIdentifier."
+          "WebKit2JavaScriptCanOpenWindowsAutomatically",
+      "1"
+    ];
     return Process.run(command, args).then((result) {
       if (result.exitCode != 0) {
         _logEvent("Could not disable pop-up blocking for safari");
@@ -301,12 +313,13 @@
     return directory.exists().then((exists) {
       if (exists) {
         _logEvent("Deleting ${paths.current}");
-        return directory.delete(recursive: true)
-	    .then((_) => deleteIfExists(paths))
-	    .catchError((error) {
-	      _logEvent("Failure trying to delete ${paths.current}: $error");
-	      return false;
-	    });
+        return directory
+            .delete(recursive: true)
+            .then((_) => deleteIfExists(paths))
+            .catchError((error) {
+          _logEvent("Failure trying to delete ${paths.current}: $error");
+          return false;
+        });
       } else {
         _logEvent("${paths.current} is not present");
         return deleteIfExists(paths);
@@ -379,10 +392,12 @@
         return getVersion().then((version) {
           _logEvent("Got version: $version");
           return Directory.systemTemp.createTemp().then((userDir) {
-            _cleanup = () { userDir.deleteSync(recursive: true); };
+            _cleanup = () {
+              userDir.deleteSync(recursive: true);
+            };
             _createLaunchHTML(userDir.path, url);
             var args = ["${userDir.path}/launch.html"];
-            return startBrowser(_binary, args);
+            return startBrowserProcess(_binary, args);
           });
         }).catchError((error) {
           _logEvent("Running $_binary --version failed with $error");
@@ -395,7 +410,6 @@
   String toString() => "Safari";
 }
 
-
 class Chrome extends Browser {
   String _version = "Version not found yet";
 
@@ -429,7 +443,6 @@
     });
   }
 
-
   Future<bool> start(String url) {
     _logEvent("Starting chrome browser on: $url");
     // Get the version and log that.
@@ -438,11 +451,19 @@
       _logEvent("Got version: $_version");
 
       return Directory.systemTemp.createTemp().then((userDir) {
-        _cleanup = () { userDir.deleteSync(recursive: true); };
-        var args = ["--user-data-dir=${userDir.path}", url,
-                    "--disable-extensions", "--disable-popup-blocking",
-                    "--bwsi", "--no-first-run"];
-        return startBrowser(_binary, args, environment: _getEnvironment());
+        _cleanup = () {
+          userDir.deleteSync(recursive: true);
+        };
+        var args = [
+          "--user-data-dir=${userDir.path}",
+          url,
+          "--disable-extensions",
+          "--disable-popup-blocking",
+          "--bwsi",
+          "--no-first-run"
+        ];
+        return startBrowserProcess(_binary, args,
+            environment: _getEnvironment());
       });
     }).catchError((e) {
       _logEvent("Running $_binary --version failed with $e");
@@ -453,14 +474,14 @@
   String toString() => "Chrome";
 }
 
-
 class SafariMobileSimulator extends Safari {
   /**
    * Directories where safari simulator stores state. We delete these if the
    * deleteCache is set
    */
-  static const List<String> CACHE_DIRECTORIES =
-      const ["Library/Application Support/iPhone Simulator/7.1/Applications"];
+  static const List<String> CACHE_DIRECTORIES = const [
+    "Library/Application Support/iPhone Simulator/7.1/Applications"
+  ];
 
   // Clears the cache if the static deleteCache flag is set.
   // Returns false if the command to actually clear the cache did not complete.
@@ -476,33 +497,34 @@
     return clearCache().then((success) {
       if (!success) {
         _logEvent("Could not clear cache, exiting");
-	return false;
+        return false;
       }
-      var args = ["-SimulateApplication",
-                  "/Applications/Xcode.app/Contents/Developer/Platforms/"
-                  "iPhoneSimulator.platform/Developer/SDKs/"
-                  "iPhoneSimulator7.1.sdk/Applications/MobileSafari.app/"
-                  "MobileSafari",
-                  "-u", url];
-      return startBrowser(_binary, args)
-        .catchError((e) {
-          _logEvent("Running $_binary --version failed with $e");
-          return false;
-        });
+      var args = [
+        "-SimulateApplication",
+        "/Applications/Xcode.app/Contents/Developer/Platforms/"
+            "iPhoneSimulator.platform/Developer/SDKs/"
+            "iPhoneSimulator7.1.sdk/Applications/MobileSafari.app/"
+            "MobileSafari",
+        "-u",
+        url
+      ];
+      return startBrowserProcess(_binary, args).catchError((e) {
+        _logEvent("Running $_binary --version failed with $e");
+        return false;
+      });
     });
   }
 
   String toString() => "SafariMobileSimulator";
 }
 
-
 class Dartium extends Chrome {
   final bool checkedMode;
 
   Dartium(this.checkedMode);
 
   Map<String, String> _getEnvironment() {
-    var environment = new Map<String,String>.from(Platform.environment);
+    var environment = new Map<String, String>.from(Platform.environment);
     // By setting this environment variable, dartium will forward "print()"
     // calls in dart to the top-level javascript function "dartPrint()" if
     // available.
@@ -518,10 +540,12 @@
 
 class IE extends Browser {
   Future<String> getVersion() {
-    var args = ["query",
-                "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Internet Explorer",
-                "/v",
-                "svcVersion"];
+    var args = [
+      "query",
+      "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Internet Explorer",
+      "/v",
+      "svcVersion"
+    ];
     return Process.run("reg", args).then((result) {
       if (result.exitCode == 0) {
         // The string we get back looks like this:
@@ -543,27 +567,26 @@
     var localAppData = Platform.environment['LOCALAPPDATA'];
 
     Directory dir = new Directory("$localAppData\\Microsoft\\"
-                                  "Internet Explorer\\Recovery");
-    return dir.delete(recursive: true)
-      .then((_) { return true; })
-      .catchError((error) {
-        _logEvent("Deleting recovery dir failed with $error");
-        return false;
-      });
+        "Internet Explorer\\Recovery");
+    return dir.delete(recursive: true).then((_) {
+      return true;
+    }).catchError((error) {
+      _logEvent("Deleting recovery dir failed with $error");
+      return false;
+    });
   }
 
   Future<bool> start(String url) {
     _logEvent("Starting ie browser on: $url");
     return clearCache().then((_) => getVersion()).then((version) {
       _logEvent("Got version: $version");
-      return startBrowser(_binary, [url]);
+      return startBrowserProcess(_binary, [url]);
     });
   }
+
   String toString() => "IE";
-
 }
 
-
 class AndroidBrowserConfig {
   final String name;
   final String package;
@@ -572,20 +595,14 @@
   AndroidBrowserConfig(this.name, this.package, this.activity, this.action);
 }
 
-
 final contentShellOnAndroidConfig = new AndroidBrowserConfig(
     'ContentShellOnAndroid',
     'org.chromium.content_shell_apk',
     '.ContentShellActivity',
     'android.intent.action.VIEW');
 
-
-final dartiumOnAndroidConfig = new AndroidBrowserConfig(
-    'DartiumOnAndroid',
-    'com.google.android.apps.chrome',
-    '.Main',
-    'android.intent.action.VIEW');
-
+final dartiumOnAndroidConfig = new AndroidBrowserConfig('DartiumOnAndroid',
+    'com.google.android.apps.chrome', '.Main', 'android.intent.action.VIEW');
 
 class AndroidBrowser extends Browser {
   final bool checkedMode;
@@ -597,8 +614,8 @@
   }
 
   Future<bool> start(String url) {
-    var intent = new Intent(
-        _config.action, _config.package, _config.activity, url);
+    var intent =
+        new Intent(_config.action, _config.package, _config.activity, url);
     return _adbDevice.waitForBootCompleted().then((_) {
       return _adbDevice.forceStop(_config.package);
     }).then((_) {
@@ -630,14 +647,13 @@
   }
 
   void logBrowserInfoToTestBrowserOutput() {
-    _testBrowserOutput.stdout.write(
-        'Android device id: ${_adbDevice.deviceId}\n');
+    _testBrowserOutput.stdout
+        .write('Android device id: ${_adbDevice.deviceId}\n');
   }
 
   String toString() => _config.name;
 }
 
-
 class AndroidChrome extends Browser {
   static const String viewAction = 'android.intent.action.VIEW';
   static const String mainAction = 'android.intent.action.MAIN';
@@ -646,14 +662,13 @@
   static const String firefoxPackage = 'org.mozilla.firefox';
   static const String turnScreenOnPackage = 'com.google.dart.turnscreenon';
 
-  AndroidEmulator _emulator;
   AdbDevice _adbDevice;
 
   AndroidChrome(this._adbDevice);
 
   Future<bool> start(String url) {
-    var browserIntent = new Intent(
-        viewAction, browserPackage, '.BrowserActivity', url);
+    var browserIntent =
+        new Intent(viewAction, browserPackage, '.BrowserActivity', url);
     var chromeIntent = new Intent(viewAction, chromePackage, '.Main', url);
     var firefoxIntent = new Intent(viewAction, firefoxPackage, '.App', url);
     var turnScreenOnIntent =
@@ -702,14 +717,13 @@
   }
 
   void logBrowserInfoToTestBrowserOutput() {
-    _testBrowserOutput.stdout.write(
-        'Android device id: ${_adbDevice.deviceId}\n');
+    _testBrowserOutput.stdout
+        .write('Android device id: ${_adbDevice.deviceId}\n');
   }
 
   String toString() => "chromeOnAndroid";
 }
 
-
 class Firefox extends Browser {
   static const String enablePopUp =
       'user_pref("dom.disable_open_during_load", false);';
@@ -741,13 +755,19 @@
 
       return Directory.systemTemp.createTemp().then((userDir) {
         _createPreferenceFile(userDir.path);
-        _cleanup = () { userDir.deleteSync(recursive: true); };
-        var args = ["-profile", "${userDir.path}",
-                    "-no-remote", "-new-instance", url];
-        var environment = new Map<String,String>.from(Platform.environment);
+        _cleanup = () {
+          userDir.deleteSync(recursive: true);
+        };
+        var args = [
+          "-profile",
+          "${userDir.path}",
+          "-no-remote",
+          "-new-instance",
+          url
+        ];
+        var environment = new Map<String, String>.from(Platform.environment);
         environment["MOZ_CRASHREPORTER_DISABLE"] = "1";
-        return startBrowser(_binary, args, environment: environment);
-
+        return startBrowserProcess(_binary, args, environment: environment);
       });
     }).catchError((e) {
       _logEvent("Running $_binary --version failed with $e");
@@ -758,11 +778,10 @@
   String toString() => "Firefox";
 }
 
-
 /**
  * Describes the current state of a browser used for testing.
  */
-class BrowserTestingStatus {
+class BrowserStatus {
   Browser browser;
   BrowserTest currentTest;
 
@@ -772,12 +791,11 @@
   BrowserTest lastTest;
   bool timeout = false;
   Timer nextTestTimeout;
-  Stopwatch timeSinceRestart = new Stopwatch();
+  Stopwatch timeSinceRestart = new Stopwatch()..start();
 
-  BrowserTestingStatus(Browser this.browser);
+  BrowserStatus(Browser this.browser);
 }
 
-
 /**
  * Describes a single test to be run in the browser.
  */
@@ -805,12 +823,9 @@
     id = _idCounter++;
   }
 
-  String toJSON() => JSON.encode({'url': url,
-                                  'id': id,
-                                  'isHtmlTest': false});
+  String toJSON() => JSON.encode({'url': url, 'id': id, 'isHtmlTest': false});
 }
 
-
 /**
  * Describes a test with a custom HTML page to be run in the browser.
  */
@@ -818,15 +833,16 @@
   List<String> expectedMessages;
 
   HtmlTest(url, doneCallback, timeout, this.expectedMessages)
-      : super(url, doneCallback, timeout) { }
+      : super(url, doneCallback, timeout) {}
 
-  String toJSON() => JSON.encode({'url': url,
-                                  'id': id,
-                                  'isHtmlTest': true,
-                                  'expectedMessages': expectedMessages});
+  String toJSON() => JSON.encode({
+        'url': url,
+        'id': id,
+        'isHtmlTest': true,
+        'expectedMessages': expectedMessages
+      });
 }
 
-
 /* Describes the output of running the test in a browser */
 class BrowserTestOutput {
   final Duration delayUntilTestStarted;
@@ -837,149 +853,157 @@
   final BrowserOutput browserOutput;
   final bool didTimeout;
 
-  BrowserTestOutput(
-      this.delayUntilTestStarted, this.duration, this.lastKnownMessage,
-      this.browserOutput, {this.didTimeout: false});
+  BrowserTestOutput(this.delayUntilTestStarted, this.duration,
+      this.lastKnownMessage, this.browserOutput,
+      {this.didTimeout: false});
 }
 
-/**
- * Encapsulates all the functionality for running tests in browsers.
- * The interface is rather simple. After starting, the runner tests
- * are simply added to the queue and a the supplied callbacks are called
- * whenever a test completes.
- */
+/// Encapsulates all the functionality for running tests in browsers.
+/// Tests are added to the queue and the supplied callbacks are called
+/// when a test completes.
+/// BrowserTestRunner starts up to maxNumBrowser instances of the browser,
+/// to run the tests, starting them sequentially, as needed, so only
+/// one is starting up at a time.
+/// BrowserTestRunner starts a BrowserTestingServer, which serves a
+/// driver page to the browsers, serves tests, and receives results and
+/// requests back from the browsers.
 class BrowserTestRunner {
   static const int MAX_NEXT_TEST_TIMEOUTS = 10;
   static const Duration NEXT_TEST_TIMEOUT = const Duration(seconds: 60);
   static const Duration RESTART_BROWSER_INTERVAL = const Duration(seconds: 60);
 
+  /// If the queue was recently empty, don't start another browser.
+  static const Duration MIN_NONEMPTY_QUEUE_TIME = const Duration(seconds: 1);
+
   final Map configuration;
+  BrowserTestingServer testingServer;
 
   final String localIp;
   String browserName;
-  final int maxNumBrowsers;
+  int maxNumBrowsers;
   bool checkedMode;
+  int numBrowsers = 0;
   // Used to send back logs from the browser (start, stop etc)
   Function logger;
-  int browserIdCount = 0;
 
+  int browserIdCounter = 1;
+
+  bool testingServerStarted = false;
   bool underTermination = false;
   int numBrowserGetTestTimeouts = 0;
-
+  DateTime lastEmptyTestQueueTime = new DateTime.now();
+  String _currentStartingBrowserId;
   List<BrowserTest> testQueue = new List<BrowserTest>();
-  Map<String, BrowserTestingStatus> browserStatus =
-      new Map<String, BrowserTestingStatus>();
+  Map<String, BrowserStatus> browserStatus = new Map<String, BrowserStatus>();
 
   var adbDeviceMapping = new Map<String, AdbDevice>();
+  List<AdbDevice> idleAdbDevices;
+
   // This cache is used to guarantee that we never see double reporting.
   // If we do we need to provide developers with this information.
   // We don't add urls to the cache until we have run it.
   Map<int, String> testCache = new Map<int, String>();
+
   Map<int, String> doubleReportingOutputs = new Map<int, String>();
+  List<String> timedOut = [];
 
-  BrowserTestingServer testingServer;
+  // We will start a new browser when the test queue hasn't been empty
+  // recently, we have fewer than maxNumBrowsers browsers, and there is
+  // no other browser instance currently starting up.
+  bool get queueWasEmptyRecently {
+    return testQueue.isEmpty ||
+        new DateTime.now().difference(lastEmptyTestQueueTime) <
+            MIN_NONEMPTY_QUEUE_TIME;
+  }
 
-  /**
-   * The TestRunner takes the testingServer in as a constructor parameter in
-   * case we wish to have a testing server with different behavior (such as the
-   * case for performance testing.
-   */
-  BrowserTestRunner(this.configuration,
-                    this.localIp,
-                    this.browserName,
-                    this.maxNumBrowsers,
-                    {BrowserTestingServer this.testingServer}) {
+  // While a browser is starting, but has not requested its first test, its
+  // browserId is stored in _currentStartingBrowserId.
+  // When no browser is currently starting, _currentStartingBrowserId is null.
+  bool get aBrowserIsCurrentlyStarting => _currentStartingBrowserId != null;
+  void markCurrentlyStarting(String id) {
+    _currentStartingBrowserId = id;
+  }
+
+  void markNotCurrentlyStarting(String id) {
+    if (_currentStartingBrowserId == id) _currentStartingBrowserId = null;
+  }
+
+  // If [browserName] doesn't support opening new windows, we use new iframes
+  // instead.
+  bool get useIframe =>
+      !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName);
+
+  /// The optional testingServer parameter allows callers to pass in
+  /// a testing server with different behavior than the  default
+  /// BrowserTestServer. The url handlers of the testingServer are
+  /// overwritten, so an existing handler can't be shared between instances.
+  BrowserTestRunner(
+      this.configuration, this.localIp, this.browserName, this.maxNumBrowsers,
+      {BrowserTestingServer this.testingServer}) {
     checkedMode = configuration['checked'];
+    if (browserName == 'ff') browserName = 'firefox';
   }
 
-  Future<bool> start() {
-    // If [browserName] doesn't support opening new windows, we use new iframes
-    // instead.
-    bool useIframe =
-        !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName);
+  Future start() async {
     if (testingServer == null) {
-      testingServer = new BrowserTestingServer(
-          configuration, localIp, useIframe);
+      testingServer =
+          new BrowserTestingServer(configuration, localIp, useIframe);
     }
-    return testingServer.start().then((_) {
-      testingServer.testDoneCallBack = handleResults;
-      testingServer.testStatusUpdateCallBack = handleStatusUpdate;
-      testingServer.testStartedCallBack = handleStarted;
-      testingServer.nextTestCallBack = getNextTest;
-      return getBrowsers().then((browsers) {
-        var futures = [];
-        for (var browser in browsers) {
-          var url = testingServer.getDriverUrl(browser.id);
-          var future = browser.start(url).then((success) {
-            if (success) {
-              var status = new BrowserTestingStatus(browser);
-              browserStatus[browser.id] = status;
-              status.nextTestTimeout = createNextTestTimer(status);
-              status.timeSinceRestart.start();
-            }
-            return success;
-          });
-          futures.add(future);
-        }
-        return Future.wait(futures).then((values) {
-          return !values.contains(false);
-        });
-      });
-    });
+    await testingServer.start();
+    testingServer
+      ..testDoneCallBack = handleResults
+      ..testStatusUpdateCallBack = handleStatusUpdate
+      ..testStartedCallBack = handleStarted
+      ..nextTestCallBack = getNextTest;
+    if (browserName == 'chromeOnAndroid') {
+      var idbNames = await AdbHelper.listDevices();
+      idleAdbDevices = new List.from(idbNames.map((id) => new AdbDevice(id)));
+      maxNumBrowsers = min(maxNumBrowsers, idleAdbDevices.length);
+    }
+    testingServerStarted = true;
+    requestBrowser();
   }
 
-  Future<List<Browser>> getBrowsers() {
-    // TODO(kustermann): This is a hackisch way to accomplish it and should
-    // be encapsulated
-    var browsersCompleter = new Completer();
-    var androidBrowserCreationMapping = {
-      'chromeOnAndroid' : (AdbDevice device) => new AndroidChrome(device),
-      'ContentShellOnAndroid' : (AdbDevice device) => new AndroidBrowser(
-          device,
-          contentShellOnAndroidConfig,
-          checkedMode,
-          configuration['drt']),
-      'DartiumOnAndroid' : (AdbDevice device) => new AndroidBrowser(
-          device,
-          dartiumOnAndroidConfig,
-          checkedMode,
-          configuration['dartium']),
-    };
-    if (androidBrowserCreationMapping.containsKey(browserName)) {
-      AdbHelper.listDevices().then((deviceIds) {
-        if (deviceIds.length > 0) {
-          var browsers = [];
-          for (int i = 0; i < deviceIds.length; i++) {
-            var id = "BROWSER$i";
-            var device = new AdbDevice(deviceIds[i]);
-            adbDeviceMapping[id] = device;
-            var browser = androidBrowserCreationMapping[browserName](device);
-            browsers.add(browser);
-            // We store this in case we need to kill the browser.
-            browser.id = id;
-          }
-          browsersCompleter.complete(browsers);
-        } else {
-          throw new StateError("No android devices found.");
-        }
-      });
+  /// requestBrowser() is called whenever we might want to start an additional
+  /// browser instance.
+  /// It is called when starting the BrowserTestRunner, and whenever a browser
+  /// is killed, whenever a new test is enqueued, or whenever a browser
+  /// finishes a test.
+  /// So we are guaranteed that this will always eventually be called, as long
+  /// as the test queue isn't empty.
+  void requestBrowser() {
+    if (!testingServerStarted) return;
+    if (underTermination) return;
+    if (numBrowsers == maxNumBrowsers) return;
+    if (aBrowserIsCurrentlyStarting) return;
+    if (numBrowsers > 0 && queueWasEmptyRecently) return;
+    createBrowser();
+  }
+
+  String getNextBrowserId() => "BROWSER${browserIdCounter++}";
+
+  void createBrowser() {
+    final String id = getNextBrowserId();
+    final String url = testingServer.getDriverUrl(id);
+    Browser browser;
+    if (browserName == 'chromeOnAndroid') {
+      AdbDevice device = idleAdbDevices.removeLast();
+      adbDeviceMapping[id] = device;
+      browser = new AndroidChrome(device);
     } else {
-      var browsers = [];
-      for (int i = 0; i < maxNumBrowsers; i++) {
-        var id = "BROWSER$browserIdCount";
-        browserIdCount++;
-        var browser = getInstance();
-        browsers.add(browser);
-        // We store this in case we need to kill the browser.
-        browser.id = id;
-      }
-      browsersCompleter.complete(browsers);
+      String path = Locations.getBrowserLocation(browserName, configuration);
+      browser = new Browser.byName(browserName, path, checkedMode);
+      browser.logger = logger;
     }
-    return browsersCompleter.future;
+    browser.id = id;
+    markCurrentlyStarting(id);
+    final status = new BrowserStatus(browser);
+    browserStatus[id] = status;
+    numBrowsers++;
+    status.nextTestTimeout = createNextTestTimer(status);
+    browser.start(url);
   }
 
-  var timedOut = [];
-
   void handleResults(String browserId, String output, int testId) {
     var status = browserStatus[browserId];
     if (testCache.containsKey(testId)) {
@@ -997,11 +1021,11 @@
 
       if (status.currentTest.id != testId) {
         print("Expected test id ${status.currentTest.id} for"
-              "${status.currentTest.url}");
+            "${status.currentTest.url}");
         print("Got test id ${testId}");
         print("Last test id was ${status.lastTest.id} for "
-              "${status.currentTest.url}");
-        throw("This should never happen, wrong test id");
+            "${status.currentTest.url}");
+        throw ("This should never happen, wrong test id");
       }
       testCache[testId] = status.currentTest.url;
 
@@ -1050,12 +1074,11 @@
     }
   }
 
-  void handleTimeout(BrowserTestingStatus status) {
+  void handleTimeout(BrowserStatus status) {
     // We simply kill the browser and starts up a new one!
     // We could be smarter here, but it does not seems like it is worth it.
     if (status.timeout) {
-      DebugLogger.error(
-          "Got test timeout for an already restarting browser");
+      DebugLogger.error("Got test timeout for an already restarting browser");
       return;
     }
     status.timeout = true;
@@ -1084,63 +1107,24 @@
 
       // We don't want to start a new browser if we are terminating.
       if (underTermination) return;
-      restartBrowser(id);
+      removeBrowser(id);
+      requestBrowser();
     });
   }
 
-  void restartBrowser(String id) {
-    if (browserName.contains('OnAndroid')) {
-      DebugLogger.info("Restarting browser $id");
-    }
-    var browser;
-    var new_id = id;
+  /// Remove a browser that has closed from our data structures that track
+  /// open browsers. Check if we want to replace it with a new browser.
+  void removeBrowser(String id) {
     if (browserName == 'chromeOnAndroid') {
-      browser = new AndroidChrome(adbDeviceMapping[id]);
-    } else if (browserName == 'ContentShellOnAndroid') {
-      browser = new AndroidBrowser(adbDeviceMapping[id],
-                                   contentShellOnAndroidConfig,
-                                   checkedMode,
-                                   configuration['drt']);
-    } else if (browserName == 'DartiumOnAndroid') {
-      browser = new AndroidBrowser(adbDeviceMapping[id],
-                                   dartiumOnAndroidConfig,
-                                   checkedMode,
-                                   configuration['dartium']);
-    } else {
-      browserStatus.remove(id);
-      browser = getInstance();
-      new_id = "BROWSER$browserIdCount";
-      browserIdCount++;
+      idleAdbDevices.add(adbDeviceMapping.remove(id));
     }
-    browser.id = new_id;
-    var status = new BrowserTestingStatus(browser);
-    browserStatus[new_id] = status;
-    status.nextTestTimeout = createNextTestTimer(status);
-    status.timeSinceRestart.start();
-    browser.start(testingServer.getDriverUrl(new_id)).then((success) {
-      // We may have started terminating in the mean time.
-      if (underTermination) {
-        if (status.nextTestTimeout != null) {
-          status.nextTestTimeout.cancel();
-          status.nextTestTimeout = null;
-        }
-        browser.close().then((success) {
-         // We should never hit this, print it out.
-          if (!success) {
-            print("Could not kill browser ($id) started due to timeout");
-          }
-        });
-        return;
-      }
-      if (!success) {
-        // TODO(ricow): Handle this better.
-        print("This is bad, should never happen, could not start browser");
-        exit(1);
-      }
-    });
+    markNotCurrentlyStarting(id);
+    browserStatus.remove(id);
+    --numBrowsers;
   }
 
   BrowserTest getNextTest(String browserId) {
+    markNotCurrentlyStarting(browserId);
     var status = browserStatus[browserId];
     if (status == null) return null;
     if (status.nextTestTimeout != null) {
@@ -1152,13 +1136,10 @@
     // We are currently terminating this browser, don't start a new test.
     if (status.timeout) return null;
 
-    // Restart content_shell and dartium on Android if they have been
+    // Restart Internet Explorer if it has been
     // running for longer than RESTART_BROWSER_INTERVAL. The tests have
     // had flaky timeouts, and this may help.
-    if ((browserName == 'ContentShellOnAndroid' ||
-         browserName == 'DartiumOnAndroid' ||
-         browserName == 'ie10' ||
-         browserName == 'ie11') &&
+    if ((browserName == 'ie10' || browserName == 'ie11') &&
         status.timeSinceRestart.elapsed > RESTART_BROWSER_INTERVAL) {
       var id = status.browser.id;
       // Reset stopwatch so we don't trigger again before restarting.
@@ -1166,13 +1147,20 @@
       status.browser.close().then((_) {
         // We don't want to start a new browser if we are terminating.
         if (underTermination) return;
-        restartBrowser(id);
+        removeBrowser(id);
+        requestBrowser();
       });
       // Don't send a test to the browser we are restarting.
       return null;
     }
 
     BrowserTest test = testQueue.removeLast();
+    // If our queue isn't empty, try starting more browsers
+    if (testQueue.isEmpty) {
+      lastEmptyTestQueueTime = new DateTime.now();
+    } else {
+      requestBrowser();
+    }
     if (status.currentTest == null) {
       status.currentTest = test;
       status.currentTest.lastKnownMessage = '';
@@ -1196,26 +1184,27 @@
     // browser, since a new test is being started.
     status.browser.resetTestBrowserOutput();
     status.browser.logBrowserInfoToTestBrowserOutput();
-    if (browserName.contains('OnAndroid')) {
-      DebugLogger.info("Browser $browserId getting test ${test.url}");
-    }
-
     return test;
   }
 
-  Timer createTimeoutTimer(BrowserTest test, BrowserTestingStatus status) {
-    return new Timer(new Duration(seconds: test.timeout),
-                     () { handleTimeout(status); });
+  /// Creates a timer that is active while a test is running on a browser.
+  Timer createTimeoutTimer(BrowserTest test, BrowserStatus status) {
+    return new Timer(new Duration(seconds: test.timeout), () {
+      handleTimeout(status);
+    });
   }
 
-  Timer createNextTestTimer(BrowserTestingStatus status) {
-    return new Timer(BrowserTestRunner.NEXT_TEST_TIMEOUT,
-                     () { handleNextTestTimeout(status); });
+  /// Creates a timer that is active while no test is running on the
+  /// browser. It has finished one test, and it has not requested a new test.
+  Timer createNextTestTimer(BrowserStatus status) {
+    return new Timer(BrowserTestRunner.NEXT_TEST_TIMEOUT, () {
+      handleNextTestTimeout(status);
+    });
   }
 
   void handleNextTestTimeout(status) {
-    DebugLogger.warning(
-        "Browser timed out before getting next test. Restarting");
+    DebugLogger
+        .warning("Browser timed out before getting next test. Restarting");
     if (status.timeout) return;
     numBrowserGetTestTimeouts++;
     if (numBrowserGetTestTimeouts >= MAX_NEXT_TEST_TIMEOUTS) {
@@ -1224,12 +1213,16 @@
       terminate().then((_) => exit(1));
     } else {
       status.timeout = true;
-      status.browser.close().then((_) => restartBrowser(status.browser.id));
+      status.browser.close().then((_) {
+        removeBrowser(status.browser.id);
+        requestBrowser();
+      });
     }
   }
 
-  void queueTest(BrowserTest test) {
+  void enqueueTest(BrowserTest test) {
     testQueue.add(test);
+    requestBrowser();
   }
 
   void printDoubleReportingTests() {
@@ -1252,44 +1245,30 @@
     }
   }
 
-  Future<bool> terminate() {
+  // TODO(26191): Call a unified fatalError(), that shuts down all subprocesses.
+  // This just kills the browsers in this BrowserTestRunner instance.
+  Future terminate() async {
     var browsers = [];
     underTermination = true;
     testingServer.underTermination = true;
-    for (BrowserTestingStatus status in browserStatus.values) {
+    for (BrowserStatus status in browserStatus.values) {
       browsers.add(status.browser);
       if (status.nextTestTimeout != null) {
         status.nextTestTimeout.cancel();
         status.nextTestTimeout = null;
       }
     }
-    // Success if all the browsers closed successfully.
-    bool success = true;
-    Future closeBrowser(Browser b) {
-      return b.close().then((bool closeSucceeded) {
-        if (!closeSucceeded) {
-          success = false;
-        }
-      });
+    for (Browser b in browsers) {
+      await b.close();
     }
-    return Future.forEach(browsers, closeBrowser).then((_) {
-      testingServer.errorReportingServer.close();
-      printDoubleReportingTests();
-      return success;
-    });
-  }
-
-  Browser getInstance() {
-    if (browserName == 'ff') browserName = 'firefox';
-    var path = Locations.getBrowserLocation(browserName, configuration);
-    var browser = new Browser.byName(browserName, path, checkedMode);
-    browser.logger = logger;
-    return browser;
+    testingServer.errorReportingServer.close();
+    printDoubleReportingTests();
   }
 }
 
 class BrowserTestingServer {
   final Map configuration;
+
   /// Interface of the testing server:
   ///
   /// GET /driver/BROWSER_ID -- This will get the driver page to fetch
@@ -1326,9 +1305,10 @@
 
   Future start() {
     var test_driver_error_port = configuration['test_driver_error_port'];
-    return HttpServer.bind(localIp, test_driver_error_port)
-      .then(setupErrorServer)
-      .then(setupDispatchingServer);
+    return HttpServer
+        .bind(localIp, test_driver_error_port)
+        .then(setupErrorServer)
+        .then(setupDispatchingServer);
   }
 
   void setupErrorServer(HttpServer server) {
@@ -1336,18 +1316,20 @@
     void errorReportingHandler(HttpRequest request) {
       StringBuffer buffer = new StringBuffer();
       request.transform(UTF8.decoder).listen((data) {
-          buffer.write(data);
-        }, onDone: () {
-          String back = buffer.toString();
-          request.response.headers.set("Access-Control-Allow-Origin", "*");
-          request.response.done.catchError((error) {
-              DebugLogger.error("Error getting error from browser"
-                                "on uri ${request.uri.path}: $error");
-            });
-          request.response.close();
-          DebugLogger.error("Error from browser on : "
-                            "${request.uri.path}, data:  $back");
-        }, onError: (error) { print(error); });
+        buffer.write(data);
+      }, onDone: () {
+        String back = buffer.toString();
+        request.response.headers.set("Access-Control-Allow-Origin", "*");
+        request.response.done.catchError((error) {
+          DebugLogger.error("Error getting error from browser"
+              "on uri ${request.uri.path}: $error");
+        });
+        request.response.close();
+        DebugLogger.error("Error from browser on : "
+            "${request.uri.path}, data:  $back");
+      }, onError: (error) {
+        print(error);
+      });
     }
     void errorHandler(e) {
       if (!underTermination) print("Error occured in httpserver: $e");
@@ -1358,58 +1340,56 @@
   void setupDispatchingServer(_) {
     DispatchingServer server = configuration['_servers_'].server;
     void noCache(request) {
-        request.response.headers.set("Cache-Control",
-                                     "no-cache, no-store, must-revalidate");
+      request.response.headers
+          .set("Cache-Control", "no-cache, no-store, must-revalidate");
     }
-    int testId(request) =>
-        int.parse(request.uri.queryParameters["id"]);
+    int testId(request) => int.parse(request.uri.queryParameters["id"]);
     String browserId(request, prefix) =>
         request.uri.path.substring(prefix.length + 1);
 
-
     server.addHandler(reportPath, (HttpRequest request) {
       noCache(request);
-      handleReport(request, browserId(request, reportPath),
-                   testId(request), isStatusUpdate: false);
+      handleReport(request, browserId(request, reportPath), testId(request),
+          isStatusUpdate: false);
     });
     server.addHandler(statusUpdatePath, (HttpRequest request) {
       noCache(request);
-      handleReport(request, browserId(request, statusUpdatePath),
-                   testId(request), isStatusUpdate: true);
+      handleReport(
+          request, browserId(request, statusUpdatePath), testId(request),
+          isStatusUpdate: true);
     });
     server.addHandler(startedPath, (HttpRequest request) {
       noCache(request);
-      handleStarted(request, browserId(request, startedPath),
-                   testId(request));
+      handleStarted(request, browserId(request, startedPath), testId(request));
     });
 
     makeSendPageHandler(String prefix) => (HttpRequest request) {
-      noCache(request);
-      var textResponse = "";
-      if (prefix == driverPath) {
-        textResponse = getDriverPage(browserId(request, prefix));
-        request.response.headers.set('Content-Type', 'text/html');
-      }
-      if (prefix == nextTestPath) {
-        textResponse = getNextTest(browserId(request, prefix));
-        request.response.headers.set('Content-Type', 'text/plain');
-      }
-      request.response.write(textResponse);
-      request.listen((_) {}, onDone: request.response.close);
-      request.response.done.catchError((error) {
-        if (!underTermination) {
-          print("URI ${request.uri}");
-          print("Textresponse $textResponse");
-          throw "Error returning content to browser: $error";
-        }
-      });
-    };
+          noCache(request);
+          var textResponse = "";
+          if (prefix == driverPath) {
+            textResponse = getDriverPage(browserId(request, prefix));
+            request.response.headers.set('Content-Type', 'text/html');
+          }
+          if (prefix == nextTestPath) {
+            textResponse = getNextTest(browserId(request, prefix));
+            request.response.headers.set('Content-Type', 'text/plain');
+          }
+          request.response.write(textResponse);
+          request.listen((_) {}, onDone: request.response.close);
+          request.response.done.catchError((error) {
+            if (!underTermination) {
+              print("URI ${request.uri}");
+              print("Textresponse $textResponse");
+              throw "Error returning content to browser: $error";
+            }
+          });
+        };
     server.addHandler(driverPath, makeSendPageHandler(driverPath));
     server.addHandler(nextTestPath, makeSendPageHandler(nextTestPath));
   }
 
   void handleReport(HttpRequest request, String browserId, var testId,
-                    {bool isStatusUpdate}) {
+      {bool isStatusUpdate}) {
     StringBuffer buffer = new StringBuffer();
     request.transform(UTF8.decoder).listen((data) {
       buffer.write(data);
@@ -1422,7 +1402,9 @@
         testDoneCallBack(browserId, back, testId);
       }
       // TODO(ricow): We should do something smart if we get an error here.
-    }, onError: (error) { DebugLogger.error("$error"); });
+    }, onError: (error) {
+      DebugLogger.error("$error");
+    });
   }
 
   void handleStarted(HttpRequest request, String browserId, var testId) {
@@ -1436,7 +1418,9 @@
       String back = buffer.toString();
       request.response.close();
       testStartedCallBack(browserId, back, testId);
-    }, onError: (error) { DebugLogger.error("$error"); });
+    }, onError: (error) {
+      DebugLogger.error("$error");
+    });
   }
 
   String getNextTest(String browserId) {
@@ -1452,7 +1436,7 @@
   String getDriverUrl(String browserId) {
     if (errorReportingServer == null) {
       print("Bad browser testing server, you are not started yet. Can't "
-            "produce driver url");
+          "produce driver url");
       exit(1);
       // This should never happen - exit immediately;
     }
@@ -1460,7 +1444,6 @@
     return "http://$localIp:$port/driver/$browserId";
   }
 
-
   String getDriverPage(String browserId) {
     var errorReportingUrl =
         "http://$localIp:${errorReportingServer.port}/$browserId";
diff --git a/tools/testing/dart/browser_perf_testing/pubspec.yaml b/tools/testing/dart/browser_perf_testing/pubspec.yaml
deleted file mode 100644
index b033e13..0000000
--- a/tools/testing/dart/browser_perf_testing/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: browser_perf_testing
-version: 0.0.1
-author: Dart Team <misc@dartlang.org>
-description: Framework for running performance benchmarks in the browser with our testing framework. 
-homepage: http://www.dartlang.org
-dependencies:
-  path: any
-  args: any
-dev_dependencies:
-environment:
diff --git a/tools/testing/dart/browser_test.dart b/tools/testing/dart/browser_test.dart
index 63d8de0..1236b55 100644
--- a/tools/testing/dart/browser_test.dart
+++ b/tools/testing/dart/browser_test.dart
@@ -6,9 +6,7 @@
 
 import 'path.dart';
 
-String getHtmlContents(String title,
-                       String scriptType,
-                       Path sourceScript) {
+String getHtmlContents(String title, String scriptType, Path sourceScript) {
   return """
 <!DOCTYPE html>
 <html>
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index d826263..9118fc8 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -22,21 +22,33 @@
 import "test_suite.dart";
 import "test_configurations.dart";
 
-const List<String> COMMON_ARGUMENTS =
-    const <String>['--report', '--progress=diff', 'co19'];
+const List<String> COMMON_ARGUMENTS = const <String>[
+  '--report',
+  '--progress=diff',
+  'co19'
+];
 
 const List<List<String>> COMMAND_LINES = const <List<String>>[
-    const <String>['-mrelease,debug', '-rvm', '-cnone'],
-    const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
-    const <String>['-mrelease', '-rnone', '-cdart2analyzer'],
-    const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
-    const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
-                   '--minified'],
-    const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
-                   '--checked'],
-    const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk',
-                   '--checked'],
-    const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk'],
+  const <String>['-mrelease,debug', '-rvm', '-cnone'],
+  const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
+  const <String>['-mrelease', '-rnone', '-cdart2analyzer'],
+  const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
+  const <String>[
+    '-mrelease',
+    '-rd8,jsshell',
+    '-cdart2js',
+    '--use-sdk',
+    '--minified'
+  ],
+  const <String>[
+    '-mrelease',
+    '-rd8,jsshell',
+    '-cdart2js',
+    '--use-sdk',
+    '--checked'
+  ],
+  const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk', '--checked'],
+  const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk'],
 ];
 
 void main(List<String> args) {
@@ -55,4 +67,3 @@
     testConfigurations(configurations);
   }
 }
-
diff --git a/tools/testing/dart/co19_test_config.dart b/tools/testing/dart/co19_test_config.dart
index 813038d..c331f93 100644
--- a/tools/testing/dart/co19_test_config.dart
+++ b/tools/testing/dart/co19_test_config.dart
@@ -11,15 +11,14 @@
   RegExp _testRegExp = new RegExp(r"t[0-9]{2}.dart$");
 
   Co19TestSuite(Map configuration)
-      : super(configuration,
-              "co19",
-              new Path("tests/co19/src"),
-              ["tests/co19/co19-co19.status",
-               "tests/co19/co19-analyzer.status",
-               "tests/co19/co19-analyzer2.status",
-               "tests/co19/co19-runtime.status",
-               "tests/co19/co19-dart2js.status",
-               "tests/co19/co19-dartium.status"]);
+      : super(configuration, "co19", new Path("tests/co19/src"), [
+          "tests/co19/co19-co19.status",
+          "tests/co19/co19-analyzer.status",
+          "tests/co19/co19-analyzer2.status",
+          "tests/co19/co19-runtime.status",
+          "tests/co19/co19-dart2js.status",
+          "tests/co19/co19-dartium.status"
+        ]);
 
   bool isTestFile(String filename) => _testRegExp.hasMatch(filename);
   bool get listRecursively => true;
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 5c8d41d..7b1e5f6 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -4,20 +4,13 @@
 
 library compiler_configuration;
 
-import 'dart:io' show
-    Platform;
+import 'dart:io' show Platform;
 
-import 'runtime_configuration.dart' show
-    RuntimeConfiguration;
+import 'runtime_configuration.dart' show RuntimeConfiguration;
 
-import 'test_runner.dart' show
-    Command,
-    CommandBuilder,
-    CompilationCommand;
+import 'test_runner.dart' show Command, CommandBuilder, CompilationCommand;
 
-import 'test_suite.dart' show
-    TestInformation,
-    TestUtils;
+import 'test_suite.dart' show TestInformation, TestUtils;
 
 /// Grouping of a command with its expected result.
 class CommandArtifact {
@@ -35,9 +28,7 @@
 Uri nativeDirectoryToUri(String nativePath) {
   Uri uri = new Uri.file(nativePath);
   String path = uri.path;
-  return (path == '' || path.endsWith('/'))
-      ? uri
-      : Uri.parse('$uri/');
+  return (path == '' || path.endsWith('/')) ? uri : Uri.parse('$uri/');
 }
 
 abstract class CompilerConfiguration {
@@ -61,36 +52,48 @@
     bool useSdk = configuration['use_sdk'];
     bool isCsp = configuration['csp'];
     bool useCps = configuration['cps_ir'];
+    // TODO(26060): Remove the browser multiplier when issue resolved.
+    bool isBrowser = configuration['browser'];
 
     switch (compiler) {
       case 'dart2analyzer':
         return new AnalyzerCompilerConfiguration(
-            isDebug: isDebug, isChecked: isChecked,
-            isHostChecked: isHostChecked, useSdk: useSdk);
+            isDebug: isDebug,
+            isChecked: isChecked,
+            isHostChecked: isHostChecked,
+            useSdk: useSdk);
       case 'dart2js':
         return new Dart2jsCompilerConfiguration(
-            isDebug: isDebug, isChecked: isChecked,
-            isHostChecked: isHostChecked, useCps: useCps, useSdk: useSdk,
-            isCsp: isCsp, extraDart2jsOptions:
+            isDebug: isDebug,
+            isChecked: isChecked,
+            isHostChecked: isHostChecked,
+            useCps: useCps,
+            useSdk: useSdk,
+            isCsp: isCsp,
+            isBrowser: isBrowser,
+            extraDart2jsOptions:
                 TestUtils.getExtraOptions(configuration, 'dart2js_options'));
       case 'dart2app':
         return new Dart2AppSnapshotCompilerConfiguration(
             isDebug: isDebug, isChecked: isChecked);
       case 'precompiler':
         return new PrecompilerCompilerConfiguration(
-            isDebug: isDebug, isChecked: isChecked,
+            isDebug: isDebug,
+            isChecked: isChecked,
             arch: configuration['arch']);
       case 'none':
         return new NoneCompilerConfiguration(
-            isDebug: isDebug, isChecked: isChecked,
-            isHostChecked: isHostChecked, useSdk: useSdk);
+            isDebug: isDebug,
+            isChecked: isChecked,
+            isHostChecked: isHostChecked,
+            useSdk: useSdk);
       default:
         throw "Unknown compiler '$compiler'";
     }
   }
 
-  CompilerConfiguration._subclass({
-      this.isDebug: false,
+  CompilerConfiguration._subclass(
+      {this.isDebug: false,
       this.isChecked: false,
       this.isHostChecked: false,
       this.useSdk: false});
@@ -126,9 +129,7 @@
   }
 
   List<String> computeCompilerArguments(vmOptions, sharedOptions, args) {
-    return new List<String>()
-        ..addAll(sharedOptions)
-        ..addAll(args);
+    return new List<String>()..addAll(sharedOptions)..addAll(args);
   }
 
   List<String> computeRuntimeArguments(
@@ -145,15 +146,13 @@
 
 /// The "none" compiler.
 class NoneCompilerConfiguration extends CompilerConfiguration {
-
-  NoneCompilerConfiguration({
-      bool isDebug,
-      bool isChecked,
-      bool isHostChecked,
-      bool useSdk})
+  NoneCompilerConfiguration(
+      {bool isDebug, bool isChecked, bool isHostChecked, bool useSdk})
       : super._subclass(
-          isDebug: isDebug, isChecked: isChecked,
-          isHostChecked: isHostChecked, useSdk: useSdk);
+            isDebug: isDebug,
+            isChecked: isChecked,
+            isHostChecked: isHostChecked,
+            useSdk: useSdk);
 
   bool get hasCompiler => false;
 
@@ -171,9 +170,9 @@
       args.add('--enable_type_checks');
     }
     return args
-        ..addAll(vmOptions)
-        ..addAll(sharedOptions)
-        ..addAll(originalArguments);
+      ..addAll(vmOptions)
+      ..addAll(sharedOptions)
+      ..addAll(originalArguments);
   }
 }
 
@@ -183,15 +182,13 @@
   static Map<String, List<Uri>> _bootstrapDependenciesCache =
       new Map<String, List<Uri>>();
 
-  Dart2xCompilerConfiguration(
-      this.moniker,
-      {bool isDebug,
-      bool isChecked,
-      bool isHostChecked,
-      bool useSdk})
+  Dart2xCompilerConfiguration(this.moniker,
+      {bool isDebug, bool isChecked, bool isHostChecked, bool useSdk})
       : super._subclass(
-          isDebug: isDebug, isChecked: isChecked,
-          isHostChecked: isHostChecked, useSdk: useSdk);
+            isDebug: isDebug,
+            isChecked: isChecked,
+            isHostChecked: isHostChecked,
+            useSdk: useSdk);
 
   String computeCompilerPath(String buildDir) {
     var prefix = 'sdk/bin';
@@ -219,17 +216,24 @@
     arguments.add('--out=$outputFileName');
 
     return commandBuilder.getCompilationCommand(
-        moniker, outputFileName, !useSdk,
+        moniker,
+        outputFileName,
+        !useSdk,
         bootstrapDependencies(buildDir),
         computeCompilerPath(buildDir),
-        arguments, environmentOverrides);
+        arguments,
+        environmentOverrides);
   }
 
   List<Uri> bootstrapDependencies(String buildDir) {
     if (!useSdk) return const <Uri>[];
-    return _bootstrapDependenciesCache.putIfAbsent(buildDir, () =>
-      [Uri.base.resolveUri(nativeDirectoryToUri(buildDir))
-               .resolve('dart-sdk/bin/snapshots/dart2js.dart.snapshot')]);
+    return _bootstrapDependenciesCache.putIfAbsent(
+        buildDir,
+        () => [
+              Uri.base
+                  .resolveUri(nativeDirectoryToUri(buildDir))
+                  .resolve('dart-sdk/bin/snapshots/dart2js.dart.snapshot')
+            ]);
   }
 }
 
@@ -237,29 +241,33 @@
 class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration {
   final bool isCsp;
   final bool useCps;
+  final bool isBrowser;
   final List<String> extraDart2jsOptions;
   // We cache the extended environment to save memory.
   static Map<String, String> cpsFlagCache;
   static Map<String, String> environmentOverridesCacheObject;
 
-  Dart2jsCompilerConfiguration({
-      bool isDebug,
+  Dart2jsCompilerConfiguration(
+      {bool isDebug,
       bool isChecked,
       bool isHostChecked,
       bool useSdk,
       bool this.useCps,
       bool this.isCsp,
+      bool this.isBrowser,
       this.extraDart2jsOptions})
-      : super(
-          'dart2js',
-          isDebug: isDebug, isChecked: isChecked,
-          isHostChecked: isHostChecked, useSdk: useSdk);
+      : super('dart2js',
+            isDebug: isDebug,
+            isChecked: isChecked,
+            isHostChecked: isHostChecked,
+            useSdk: useSdk);
 
   int computeTimeoutMultiplier() {
     int multiplier = 1;
     if (isDebug) multiplier *= 4;
     if (isChecked) multiplier *= 2;
     if (isHostChecked) multiplier *= 16;
+    if (isBrowser) multiplier *= 2;  // TODO(26060): Remove when issue fixed.
     return multiplier;
   }
 
@@ -271,16 +279,10 @@
       Map<String, String> environmentOverrides) {
     List compilerArguments = new List.from(arguments)
       ..addAll(extraDart2jsOptions);
-    return new CommandArtifact(
-        <Command>[
-            this.computeCompilationCommand(
-                '$tempDir/out.js',
-                buildDir,
-                CommandBuilder.instance,
-                compilerArguments,
-                environmentOverrides)],
-        '$tempDir/out.js',
-        'application/javascript');
+    return new CommandArtifact(<Command>[
+      this.computeCompilationCommand('$tempDir/out.js', buildDir,
+          CommandBuilder.instance, compilerArguments, environmentOverrides)
+    ], '$tempDir/out.js', 'application/javascript');
   }
 
   List<String> computeRuntimeArguments(
@@ -291,25 +293,22 @@
       List<String> sharedOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
-    Uri sdk = useSdk ?
-        nativeDirectoryToUri(buildDir).resolve('dart-sdk/') :
-        nativeDirectoryToUri(TestUtils.dartDir.toNativePath()).resolve('sdk/');
-    Uri preambleDir = sdk.resolve(
-        'lib/_internal/js_runtime/lib/preambles/');
+    Uri sdk = useSdk
+        ? nativeDirectoryToUri(buildDir).resolve('dart-sdk/')
+        : nativeDirectoryToUri(TestUtils.dartDir.toNativePath())
+            .resolve('sdk/');
+    Uri preambleDir = sdk.resolve('lib/_internal/js_runtime/lib/preambles/');
     return runtimeConfiguration.dart2jsPreambles(preambleDir)
-        ..add(artifact.filename);
+      ..add(artifact.filename);
   }
 }
 
-
 class PrecompilerCompilerConfiguration extends CompilerConfiguration {
   final String arch;
 
-  PrecompilerCompilerConfiguration({
-      bool isDebug,
-      bool isChecked,
-      String arch})
-    : super._subclass(isDebug: isDebug, isChecked: isChecked), arch = arch;
+  PrecompilerCompilerConfiguration({bool isDebug, bool isChecked, String arch})
+      : super._subclass(isDebug: isDebug, isChecked: isChecked),
+        arch = arch;
 
   int computeTimeoutMultiplier() {
     int multiplier = 2;
@@ -324,28 +323,14 @@
       CommandBuilder commandBuilder,
       List arguments,
       Map<String, String> environmentOverrides) {
-    return new CommandArtifact(
-        <Command>[
-            this.computeCompilationCommand(
-                tempDir,
-                buildDir,
-                CommandBuilder.instance,
-                arguments,
-                environmentOverrides),
-            this.computeAssembleCommand(
-                tempDir,
-                buildDir,
-                CommandBuilder.instance,
-                arguments,
-                environmentOverrides),
-            this.computeRemoveAssemblyCommand(
-                tempDir,
-                buildDir,
-                CommandBuilder.instance,
-                arguments,
-                environmentOverrides)],
-        '$tempDir',
-        'application/dart-precompiled');
+    return new CommandArtifact(<Command>[
+      this.computeCompilationCommand(tempDir, buildDir, CommandBuilder.instance,
+          arguments, environmentOverrides),
+      this.computeAssembleCommand(tempDir, buildDir, CommandBuilder.instance,
+          arguments, environmentOverrides),
+      this.computeRemoveAssemblyCommand(tempDir, buildDir,
+          CommandBuilder.instance, arguments, environmentOverrides)
+    ], '$tempDir', 'application/dart-precompiled');
   }
 
   CompilationCommand computeCompilationCommand(
@@ -359,10 +344,8 @@
     args.add("--gen-precompiled-snapshot=$tempDir");
     args.addAll(arguments);
 
-    return commandBuilder.getCompilationCommand(
-        'precompiler', tempDir, !useSdk,
-        bootstrapDependencies(buildDir),
-        exec, args, environmentOverrides);
+    return commandBuilder.getCompilationCommand('precompiler', tempDir, !useSdk,
+        bootstrapDependencies(buildDir), exec, args, environmentOverrides);
   }
 
   CompilationCommand computeAssembleCommand(
@@ -401,16 +384,16 @@
     }
 
     var exec = cc;
-    var args = [shared,
-                cc_flags,
-                '-o',
-                '$tempDir/$libname',
-                '$tempDir/precompiled.S'];
+    var args = [
+      shared,
+      cc_flags,
+      '-o',
+      '$tempDir/$libname',
+      '$tempDir/precompiled.S'
+    ];
 
-    return commandBuilder.getCompilationCommand(
-        'assemble', tempDir, !useSdk,
-        bootstrapDependencies(buildDir),
-        exec, args, environmentOverrides);
+    return commandBuilder.getCompilationCommand('assemble', tempDir, !useSdk,
+        bootstrapDependencies(buildDir), exec, args, environmentOverrides);
   }
 
   // This step reduces the amount of space needed to run the precompilation
@@ -425,32 +408,35 @@
     var args = ['$tempDir/precompiled.S'];
 
     return commandBuilder.getCompilationCommand(
-        'remove_assembly', tempDir, !useSdk,
+        'remove_assembly',
+        tempDir,
+        !useSdk,
         bootstrapDependencies(buildDir),
-        exec, args, environmentOverrides);
+        exec,
+        args,
+        environmentOverrides);
   }
 
   List<String> filterVmOptions(List<String> vmOptions) {
     var filtered = new List.from(vmOptions);
     filtered.removeWhere(
-      (option) => option.startsWith("--optimization-counter-threshold"));
+        (option) => option.startsWith("--optimization-counter-threshold"));
     filtered.removeWhere(
-      (option) => option.startsWith("--optimization_counter_threshold"));
+        (option) => option.startsWith("--optimization_counter_threshold"));
     return filtered;
   }
 
-  List<String> computeCompilerArguments(vmOptions,
-                                        sharedOptions,
-                                        originalArguments) {
+  List<String> computeCompilerArguments(
+      vmOptions, sharedOptions, originalArguments) {
     List<String> args = [];
     if (isChecked) {
       args.add('--enable_asserts');
       args.add('--enable_type_checks');
     }
     return args
-        ..addAll(filterVmOptions(vmOptions))
-        ..addAll(sharedOptions)
-        ..addAll(originalArguments);
+      ..addAll(filterVmOptions(vmOptions))
+      ..addAll(sharedOptions)
+      ..addAll(originalArguments);
   }
 
   List<String> computeRuntimeArguments(
@@ -467,17 +453,14 @@
       args.add('--enable_type_checks');
     }
     return args
-        ..addAll(vmOptions)
-        ..addAll(sharedOptions)
-        ..addAll(originalArguments);
+      ..addAll(vmOptions)
+      ..addAll(sharedOptions)
+      ..addAll(originalArguments);
   }
 }
 
-
 class Dart2AppSnapshotCompilerConfiguration extends CompilerConfiguration {
-  Dart2AppSnapshotCompilerConfiguration({
-      bool isDebug,
-      bool isChecked})
+  Dart2AppSnapshotCompilerConfiguration({bool isDebug, bool isChecked})
       : super._subclass(isDebug: isDebug, isChecked: isChecked);
 
   int computeTimeoutMultiplier() {
@@ -494,16 +477,10 @@
       List arguments,
       Map<String, String> environmentOverrides) {
     String outputName = computeOutputName(tempDir);
-    return new CommandArtifact(
-        <Command>[
-            this.computeCompilationCommand(
-                outputName,
-                buildDir,
-                CommandBuilder.instance,
-                arguments,
-                environmentOverrides)],
-        outputName,
-        'application/dart-snapshot');
+    return new CommandArtifact(<Command>[
+      this.computeCompilationCommand(outputName, buildDir,
+          CommandBuilder.instance, arguments, environmentOverrides)
+    ], outputName, 'application/dart-snapshot');
   }
 
   String computeOutputName(String tempDir) {
@@ -523,23 +500,26 @@
     args.addAll(arguments);
 
     return commandBuilder.getCompilationCommand(
-        'dart2snapshot', outputName, !useSdk,
+        'dart2snapshot',
+        outputName,
+        !useSdk,
         bootstrapDependencies(buildDir),
-        exec, args, environmentOverrides);
+        exec,
+        args,
+        environmentOverrides);
   }
 
-  List<String> computeCompilerArguments(vmOptions,
-                                        sharedOptions,
-                                        originalArguments) {
+  List<String> computeCompilerArguments(
+      vmOptions, sharedOptions, originalArguments) {
     List<String> args = [];
     if (isChecked) {
       args.add('--enable_asserts');
       args.add('--enable_type_checks');
     }
     return args
-        ..addAll(vmOptions)
-        ..addAll(sharedOptions)
-        ..addAll(originalArguments);
+      ..addAll(vmOptions)
+      ..addAll(sharedOptions)
+      ..addAll(originalArguments);
   }
 
   List<String> computeRuntimeArguments(
@@ -556,22 +536,20 @@
       args.add('--enable_type_checks');
     }
     return args
-        ..addAll(vmOptions)
-        ..addAll(sharedOptions)
-        ..addAll(originalArguments);
+      ..addAll(vmOptions)
+      ..addAll(sharedOptions)
+      ..addAll(originalArguments);
   }
 }
 
-
 class AnalyzerCompilerConfiguration extends CompilerConfiguration {
   AnalyzerCompilerConfiguration(
-      {bool isDebug,
-      bool isChecked,
-      bool isHostChecked,
-      bool useSdk})
+      {bool isDebug, bool isChecked, bool isHostChecked, bool useSdk})
       : super._subclass(
-          isDebug: isDebug, isChecked: isChecked,
-          isHostChecked: isHostChecked, useSdk: useSdk);
+            isDebug: isDebug,
+            isChecked: isChecked,
+            isHostChecked: isHostChecked,
+            useSdk: useSdk);
 
   int computeTimeoutMultiplier() {
     return 4;
@@ -605,14 +583,12 @@
     if (isChecked) {
       arguments.add('--enable_type_checks');
     }
-    return new CommandArtifact(
-        <Command>[
-            commandBuilder.getAnalysisCommand(
-                'dart2analyzer', computeCompilerPath(buildDir), arguments,
-                environmentOverrides,
-                flavor: 'dart2analyzer')],
-        null, null); // Since this is not a real compilation, no artifacts are
-                     // produced.
+    return new CommandArtifact(<Command>[
+      commandBuilder.getAnalysisCommand('dart2analyzer',
+          computeCompilerPath(buildDir), arguments, environmentOverrides,
+          flavor: 'dart2analyzer')
+    ], null, null); // Since this is not a real compilation, no artifacts are
+    // produced.
   }
 
   List<String> computeRuntimeArguments(
diff --git a/tools/testing/dart/dependency_graph.dart b/tools/testing/dart/dependency_graph.dart
index 1de7b9e..abdcf50 100644
--- a/tools/testing/dart/dependency_graph.dart
+++ b/tools/testing/dart/dependency_graph.dart
@@ -7,7 +7,6 @@
 import 'dart:async';
 import 'utils.dart';
 
-
 /*
  * [Graph] represents a datastructure for representing an DAG (directed acyclic
  * graph). Each node in the graph is in a given [NodeState] and can have data
@@ -114,12 +113,12 @@
 
 class NodeState extends UniqueObject {
   static NodeState Initialized = new NodeState._("Initialized");
-  static NodeState Waiting  = new NodeState._("Waiting");
-  static NodeState Enqueuing  = new NodeState._("Enqueuing");
-  static NodeState Processing  = new NodeState._("Running");
-  static NodeState Successful  = new NodeState._("Successful");
-  static NodeState Failed  = new NodeState._("Failed");
-  static NodeState UnableToRun  = new NodeState._("UnableToRun");
+  static NodeState Waiting = new NodeState._("Waiting");
+  static NodeState Enqueuing = new NodeState._("Enqueuing");
+  static NodeState Processing = new NodeState._("Running");
+  static NodeState Successful = new NodeState._("Successful");
+  static NodeState Failed = new NodeState._("Failed");
+  static NodeState UnableToRun = new NodeState._("UnableToRun");
 
   final String name;
 
diff --git a/tools/testing/dart/drt_updater.dart b/tools/testing/dart/drt_updater.dart
index 3f34885..ee5a628 100644
--- a/tools/testing/dart/drt_updater.dart
+++ b/tools/testing/dart/drt_updater.dart
@@ -28,7 +28,11 @@
     if (!isActive) {
       isActive = true;
       print('Updating $name.');
-      onUpdated = [() {updated = true;} ];
+      onUpdated = [
+        () {
+          updated = true;
+        }
+      ];
       _updatingProcess = Process.run('python', _getUpdateCommand);
       _updatingProcess.then(_onUpdatedHandler).catchError((e) {
         print("Error starting $script process: $e");
@@ -57,7 +61,7 @@
       print(result.stderr);
       exit(1);
     }
-    for (var callback in onUpdated ) callback();
+    for (var callback in onUpdated) callback();
   }
 }
 
@@ -69,17 +73,15 @@
   if (runtime == 'drt' && configuration['drt'] == '') {
     // Download the default content shell from Google Storage.
     if (_contentShellUpdater == null) {
-      _contentShellUpdater = new _DartiumUpdater('Content Shell',
-                                                 'tools/get_archive.py',
-                                                 'drt');
+      _contentShellUpdater =
+          new _DartiumUpdater('Content Shell', 'tools/get_archive.py', 'drt');
     }
     return _contentShellUpdater;
   } else if (runtime == 'dartium' && configuration['dartium'] == '') {
     // Download the default Dartium from Google Storage.
     if (_dartiumUpdater == null) {
-      _dartiumUpdater = new _DartiumUpdater('Dartium Chrome',
-                                            'tools/get_archive.py',
-                                            'dartium');
+      _dartiumUpdater = new _DartiumUpdater(
+          'Dartium Chrome', 'tools/get_archive.py', 'dartium');
     }
     return _dartiumUpdater;
   } else {
diff --git a/tools/testing/dart/html_test.dart b/tools/testing/dart/html_test.dart
index 0f69eed..dfa555f 100644
--- a/tools/testing/dart/html_test.dart
+++ b/tools/testing/dart/html_test.dart
@@ -31,15 +31,15 @@
   var match = htmlAnnotation.firstMatch(contents);
   if (match == null) return null;
   var annotation = JSON.decode(match[1]);
-  if (annotation is! Map || annotation['expectedMessages'] is! List ||
+  if (annotation is! Map ||
+      annotation['expectedMessages'] is! List ||
       annotation['scripts'] is! List) {
     DebugLogger.warning("File $filename does not have expected annotation."
         " Should have {'scripts':[...], 'expectedMessages':[...]}");
     return null;
   }
   return new HtmlTestInformation(new Path(filename),
-                                 annotation['expectedMessages'],
-                                 annotation['scripts']);
+      annotation['expectedMessages'], annotation['scripts']);
 }
 
 String getContents(HtmlTestInformation info, bool compileToJS) {
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 1cfdb65..429ddeac 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -7,11 +7,10 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'dart:convert' show
-    HtmlEscape;
+import 'dart:convert' show HtmlEscape;
 
 import 'path.dart';
-import 'test_suite.dart';  // For TestUtils.
+import 'test_suite.dart'; // For TestUtils.
 // TODO(efortuna): Rewrite to not use the args library and simply take an
 // expected number of arguments, so test.dart doesn't rely on the args library?
 // See discussion on https://codereview.chromium.org/11931025/.
@@ -23,9 +22,8 @@
   Map<String, Function> _handlers = new Map<String, Function>();
   Function _notFound;
 
-  DispatchingServer(this.server,
-                    void onError(e),
-                    void this._notFound(HttpRequest request)) {
+  DispatchingServer(
+      this.server, void onError(e), void this._notFound(HttpRequest request)) {
     server.listen(_dispatchRequest, onError: onError);
   }
 
@@ -46,8 +44,6 @@
   }
 }
 
-
-
 /// Interface of the HTTP server:
 ///
 /// /echo: This will stream the data received in the request stream back
@@ -77,37 +73,37 @@
   TestUtils.setDartDirUri(Platform.script.resolve('../../..'));
   /** Convenience method for local testing. */
   var parser = new ArgParser();
-  parser.addOption('port', abbr: 'p',
+  parser.addOption('port',
+      abbr: 'p',
       help: 'The main server port we wish to respond to requests.',
       defaultsTo: '0');
-  parser.addOption('crossOriginPort', abbr: 'c',
+  parser.addOption('crossOriginPort',
+      abbr: 'c',
       help: 'A different port that accepts request from the main server port.',
       defaultsTo: '0');
-  parser.addFlag('help', abbr: 'h', negatable: false,
-      help: 'Print this usage information.');
+  parser.addFlag('help',
+      abbr: 'h', negatable: false, help: 'Print this usage information.');
   parser.addOption('build-directory', help: 'The build directory to use.');
   parser.addOption('package-root', help: 'The package root to use.');
-  parser.addOption('network', help: 'The network interface to use.',
-      defaultsTo: '0.0.0.0');
-  parser.addFlag('csp', help: 'Use Content Security Policy restrictions.',
-      defaultsTo: false);
-  parser.addOption('runtime', help: 'The runtime we are using (for csp flags).',
-      defaultsTo: 'none');
+  parser.addOption('network',
+      help: 'The network interface to use.', defaultsTo: '0.0.0.0');
+  parser.addFlag('csp',
+      help: 'Use Content Security Policy restrictions.', defaultsTo: false);
+  parser.addOption('runtime',
+      help: 'The runtime we are using (for csp flags).', defaultsTo: 'none');
 
   var args = parser.parse(arguments);
   if (args['help']) {
     print(parser.getUsage());
   } else {
     var servers = new TestingServers(new Path(args['build-directory']),
-                                     args['csp'],
-                                     args['runtime'],
-                                     null,
-                                     args['package-root']);
+        args['csp'], args['runtime'], null, args['package-root']);
     var port = int.parse(args['port']);
     var crossOriginPort = int.parse(args['crossOriginPort']);
-    servers.startServers(args['network'],
-                         port: port,
-                         crossOriginPort: crossOriginPort).then((_) {
+    servers
+        .startServers(args['network'],
+            port: port, crossOriginPort: crossOriginPort)
+        .then((_) {
       DebugLogger.info('Server listening on port ${servers.port}');
       DebugLogger.info('Server listening on port ${servers.crossOriginPort}');
     });
@@ -138,16 +134,16 @@
   final String runtime;
   DispatchingServer _server;
 
-  TestingServers(Path buildDirectory,
-                 this.useContentSecurityPolicy,
-                 [String this.runtime = 'none', String dartDirectory,
-                  String packageRoot]) {
+  TestingServers(Path buildDirectory, this.useContentSecurityPolicy,
+      [String this.runtime = 'none',
+      String dartDirectory,
+      String packageRoot]) {
     _buildDirectory = TestUtils.absolutePath(buildDirectory);
-    _dartDirectory = dartDirectory == null ? TestUtils.dartDir
-        : new Path(dartDirectory);
-    _packageRoot = packageRoot == null ?
-      _buildDirectory.append('packages') :
-      new Path(packageRoot);
+    _dartDirectory =
+        dartDirectory == null ? TestUtils.dartDir : new Path(dartDirectory);
+    _packageRoot = packageRoot == null
+        ? _buildDirectory.append('packages')
+        : new Path(packageRoot);
   }
 
   int get port => _serverList[0].port;
@@ -166,8 +162,7 @@
     return _startHttpServer(host, port: port).then((server) {
       _server = server;
       return _startHttpServer(host,
-                              port: crossOriginPort,
-                              allowedPort:_serverList[0].port);
+          port: crossOriginPort, allowedPort: _serverList[0].port);
     });
   }
 
@@ -178,8 +173,8 @@
     var buildDirectory = _buildDirectory.toNativePath();
     var csp = useContentSecurityPolicy ? '--csp ' : '';
     return '$dart $script -p $port -c $crossOriginPort $csp'
-           '--build-directory=$buildDirectory --runtime=$runtime '
-           '--package-root=$_packageRoot';
+        '--build-directory=$buildDirectory --runtime=$runtime '
+        '--package-root=$_packageRoot';
   }
 
   void stopServers() {
@@ -208,12 +203,11 @@
     });
   }
 
-  void _handleFileOrDirectoryRequest(HttpRequest request,
-                                     int allowedPort) {
+  void _handleFileOrDirectoryRequest(HttpRequest request, int allowedPort) {
     // Enable browsers to cache file/directory responses.
     var response = request.response;
-    response.headers.set("Cache-Control",
-                         "max-age=$_CACHE_EXPIRATION_IN_SECONDS");
+    response.headers
+        .set("Cache-Control", "max-age=$_CACHE_EXPIRATION_IN_SECONDS");
     var path = _getFilePathFromRequestPath(request.uri.path);
     if (path != null) {
       var file = new File(path.toNativePath());
@@ -235,9 +229,11 @@
       });
     } else {
       if (request.uri.path == '/') {
-        var entries = [new _Entry('root_dart', 'root_dart/'),
-                       new _Entry('root_build', 'root_build/'),
-                       new _Entry('echo', 'echo')];
+        var entries = [
+          new _Entry('root_dart', 'root_dart/'),
+          new _Entry('root_build', 'root_build/'),
+          new _Entry('echo', 'echo')
+        ];
         _sendDirectoryListing(entries, request, response);
       } else {
         _sendNotFound(request);
@@ -285,12 +281,10 @@
       var relativePath;
       if (pathSegments[0] == PREFIX_BUILDDIR) {
         basePath = _buildDirectory;
-        relativePath = new Path(
-            pathSegments.skip(1).join('/'));
+        relativePath = new Path(pathSegments.skip(1).join('/'));
       } else if (pathSegments[0] == PREFIX_DARTDIR) {
         basePath = _dartDirectory;
-        relativePath = new Path(
-            pathSegments.skip(1).join('/'));
+        relativePath = new Path(pathSegments.skip(1).join('/'));
       }
       var packagesIndex = pathSegments.indexOf('packages');
       if (packagesIndex != -1) {
@@ -309,24 +303,21 @@
     var completer = new Completer();
     var entries = [];
 
-    directory.list().listen(
-      (FileSystemEntity fse) {
-        var filename = new Path(fse.path).filename;
-        if (fse is File) {
-          entries.add(new _Entry(filename, filename));
-        } else if (fse is Directory) {
-          entries.add(new _Entry(filename, '$filename/'));
-        }
-      },
-      onDone: () {
-        completer.complete(entries);
-      });
+    directory.list().listen((FileSystemEntity fse) {
+      var filename = new Path(fse.path).filename;
+      if (fse is File) {
+        entries.add(new _Entry(filename, filename));
+      } else if (fse is Directory) {
+        entries.add(new _Entry(filename, '$filename/'));
+      }
+    }, onDone: () {
+      completer.complete(entries);
+    });
     return completer.future;
   }
 
-  void _sendDirectoryListing(List<_Entry> entries,
-                             HttpRequest request,
-                             HttpResponse response) {
+  void _sendDirectoryListing(
+      List<_Entry> entries, HttpRequest request, HttpResponse response) {
     response.headers.set('Content-Type', 'text/html');
     var header = '''<!DOCTYPE html>
     <html>
@@ -344,7 +335,6 @@
     </body>
     </html>''';
 
-
     entries.sort();
     response.write(header);
     for (var entry in entries) {
@@ -360,26 +350,21 @@
     });
   }
 
-  void _sendFileContent(HttpRequest request,
-                        HttpResponse response,
-                        int allowedPort,
-                        Path path,
-                        File file) {
+  void _sendFileContent(HttpRequest request, HttpResponse response,
+      int allowedPort, Path path, File file) {
     if (allowedPort != -1) {
       var headerOrigin = request.headers.value('Origin');
       var allowedOrigin;
       if (headerOrigin != null) {
         var origin = Uri.parse(headerOrigin);
         // Allow loading from http://*:$allowedPort in browsers.
-        allowedOrigin =
-          '${origin.scheme}://${origin.host}:${allowedPort}';
+        allowedOrigin = '${origin.scheme}://${origin.host}:${allowedPort}';
       } else {
         // IE10 appears to be bugged and is not sending the Origin header
         // when making CORS requests to the same domain but different port.
         allowedOrigin = '*';
       }
 
-
       response.headers.set("Access-Control-Allow-Origin", allowedOrigin);
       response.headers.set('Access-Control-Allow-Credentials', 'true');
     } else {
@@ -392,8 +377,10 @@
       // whereas Firefox and IE10 use X-Content-Security-Policy. Safari
       // still uses the WebKit- prefixed version.
       var content_header_value = "script-src 'self'; object-src 'self'";
-      for (var header in ["Content-Security-Policy",
-                          "X-Content-Security-Policy"]) {
+      for (var header in [
+        "Content-Security-Policy",
+        "X-Content-Security-Policy"
+      ]) {
         response.headers.set(header, content_header_value);
       }
       if (const ["safari"].contains(runtime)) {
@@ -426,7 +413,7 @@
     }
     if (!isHarmlessPath(request.uri.path)) {
       DebugLogger.warning('HttpServer: could not find file for request path: '
-                          '"${request.uri.path}"');
+          '"${request.uri.path}"');
     }
     var response = request.response;
     response.statusCode = HttpStatus.NOT_FOUND;
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index 005cdc0..d39bc9a 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -61,27 +61,28 @@
 //   ddd /// 07: static type warning, dynamic type error
 //   fff
 
-void ExtractTestsFromMultitest(Path filePath,
-                               Map<String, String> tests,
-                               Map<String, Set<String>> outcomes) {
+void ExtractTestsFromMultitest(Path filePath, Map<String, String> tests,
+    Map<String, Set<String>> outcomes) {
   // Read the entire file into a byte buffer and transform it to a
   // String. This will treat the file as ascii but the only parts
   // we are interested in will be ascii in any case.
   List bytes = new File(filePath.toNativePath()).readAsBytesSync();
   String contents = decodeUtf8(bytes);
   int first_newline = contents.indexOf('\n');
-  final String line_separator =
-      (first_newline == 0 || contents[first_newline - 1] != '\r')
-      ? '\n'
-      : '\r\n';
+  final String line_separator = (first_newline == 0 ||
+      contents[first_newline - 1] != '\r') ? '\n' : '\r\n';
   List<String> lines = contents.split(line_separator);
   if (lines.last == '') lines.removeLast();
   bytes = null;
   contents = null;
-  Set<String> validMultitestOutcomes = new Set<String>.from(
-      ['ok', 'compile-time error', 'runtime error',
-       'static type warning', 'dynamic type error',
-       'checked mode compile-time error']);
+  Set<String> validMultitestOutcomes = new Set<String>.from([
+    'ok',
+    'compile-time error',
+    'runtime error',
+    'static type warning',
+    'dynamic type error',
+    'checked mode compile-time error'
+  ]);
 
   // Create the set of multitests, which will have a new test added each
   // time we see a multitest line with a new key.
@@ -96,8 +97,8 @@
     lineCount++;
     var annotation = new _Annotation.from(line);
     if (annotation != null) {
-      testsAsLines.putIfAbsent(annotation.key,
-          () => new List<String>.from(testsAsLines["none"]));
+      testsAsLines.putIfAbsent(
+          annotation.key, () => new List<String>.from(testsAsLines["none"]));
       // Add line to test with annotation.key as key, empty line to the rest.
       for (var key in testsAsLines.keys) {
         testsAsLines[key].add(annotation.key == key ? line : "");
@@ -172,8 +173,8 @@
     var annotation = new _Annotation();
     annotation.key = parts[0];
     annotation.rest = parts[1];
-    annotation.outcomesList = annotation.rest.split(',')
-        .map((s) => s.trim()).toList();
+    annotation.outcomesList =
+        annotation.rest.split(',').map((s) => s.trim()).toList();
     return annotation;
   }
 }
@@ -219,8 +220,8 @@
   return foundImports;
 }
 
-Future doMultitest(Path filePath, String outputDir, Path suiteDir,
-                   CreateTest doTest) {
+Future doMultitest(
+    Path filePath, String outputDir, Path suiteDir, CreateTest doTest) {
   void writeFile(String filepath, String content) {
     final File file = new File(filepath);
 
@@ -254,8 +255,8 @@
       TestUtils.mkdirRecursive(targetDir, importDir);
     }
     // Copy file.
-    futureCopies.add(TestUtils.copyFile(sourceDir.join(importPath),
-                                        targetDir.join(importPath)));
+    futureCopies.add(TestUtils.copyFile(
+        sourceDir.join(importPath), targetDir.join(importPath)));
   }
 
   // Wait until all imports are copied before scheduling test cases.
@@ -272,21 +273,17 @@
       bool isNegativeIfChecked = outcome.contains('dynamic type error');
       bool hasCompileErrorIfChecked =
           outcome.contains('checked mode compile-time error');
-      doTest(multitestFilename,
-             filePath,
-             hasCompileError,
-             hasRuntimeErrors,
-             isNegativeIfChecked: isNegativeIfChecked,
-             hasCompileErrorIfChecked: hasCompileErrorIfChecked,
-             hasStaticWarning: hasStaticWarning,
-             multitestKey: key);
+      doTest(multitestFilename, filePath, hasCompileError, hasRuntimeErrors,
+          isNegativeIfChecked: isNegativeIfChecked,
+          hasCompileErrorIfChecked: hasCompileErrorIfChecked,
+          hasStaticWarning: hasStaticWarning,
+          multitestKey: key);
     }
 
     return null;
   });
 }
 
-
 Path CreateMultitestDirectory(String outputDir, Path suiteDir) {
   Directory generatedTestDir = new Directory('$outputDir/generated_tests');
   if (!new Directory(outputDir).existsSync()) {
diff --git a/tools/testing/dart/path.dart b/tools/testing/dart/path.dart
index 1e1bf7d..a3d35aa 100644
--- a/tools/testing/dart/path.dart
+++ b/tools/testing/dart/path.dart
@@ -13,9 +13,12 @@
   final bool isWindowsShare;
 
   Path(String source)
-      : _path = _clean(source), isWindowsShare = _isWindowsShare(source);
+      : _path = _clean(source),
+        isWindowsShare = _isWindowsShare(source);
 
-  Path.raw(String source) : _path = source, isWindowsShare = false;
+  Path.raw(String source)
+      : _path = source,
+        isWindowsShare = false;
 
   Path._internal(String this._path, bool this.isWindowsShare);
 
@@ -58,8 +61,7 @@
     // Throws exception if an impossible case is reached.
     if (base.isAbsolute != isAbsolute ||
         base.isWindowsShare != isWindowsShare) {
-      throw new ArgumentError(
-          "Invalid case of Path.relativeTo(base):\n"
+      throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
           "  Path and base must both be relative, or both absolute.\n"
           "  Arguments: $_path.relativeTo($base)");
     }
@@ -72,29 +74,26 @@
       bool pathHasDrive =
           _path.length >= 4 && _path[2] == ':' && _path[3] == '/';
       if (baseHasDrive && pathHasDrive) {
-        int baseDrive = basePath.codeUnitAt(1) | 32;  // Convert to uppercase.
+        int baseDrive = basePath.codeUnitAt(1) | 32; // Convert to uppercase.
         if (baseDrive >= 'a'.codeUnitAt(0) &&
             baseDrive <= 'z'.codeUnitAt(0) &&
             baseDrive == (_path.codeUnitAt(1) | 32)) {
-          if(basePath[1] != _path[1]) {
+          if (basePath[1] != _path[1]) {
             // Replace the drive letter in basePath with that from _path.
             basePath = '/${_path[1]}:/${basePath.substring(4)}';
             base = new Path(basePath);
           }
         } else {
-          throw new ArgumentError(
-              "Invalid case of Path.relativeTo(base):\n"
+          throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
               "  Base path and target path are on different Windows drives.\n"
               "  Arguments: $_path.relativeTo($base)");
         }
       } else if (baseHasDrive != pathHasDrive) {
-        throw new ArgumentError(
-            "Invalid case of Path.relativeTo(base):\n"
+        throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
             "  Base path must start with a drive letter if and "
             "only if target path does.\n"
             "  Arguments: $_path.relativeTo($base)");
       }
-
     }
     if (_path.startsWith(basePath)) {
       if (_path == basePath) return new Path('.');
@@ -125,8 +124,7 @@
     final segments = new List<String>();
 
     if (common < baseSegments.length && baseSegments[common] == '..') {
-      throw new ArgumentError(
-          "Invalid case of Path.relativeTo(base):\n"
+      throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
           "  Base path has more '..'s than path does.\n"
           "  Arguments: $_path.relativeTo($base)");
     }
@@ -140,12 +138,11 @@
       segments.add('.');
     }
     if (hasTrailingSeparator) {
-        segments.add('');
+      segments.add('');
     }
     return new Path(segments.join('/'));
   }
 
-
   Path join(Path further) {
     if (further.isAbsolute) {
       throw new ArgumentError(
@@ -175,19 +172,19 @@
     // Contains no segments that are '.'.
     // Absolute paths have no segments that are '..'.
     // All '..' segments of a relative path are at the beginning.
-    if (isEmpty) return false;  // The canonical form of '' is '.'.
+    if (isEmpty) return false; // The canonical form of '' is '.'.
     if (_path == '.') return true;
-    List segs = _path.split('/');  // Don't mask the getter 'segments'.
-    if (segs[0] == '') {  // Absolute path
-      segs[0] = null;  // Faster than removeRange().
-    } else {  // A canonical relative path may start with .. segments.
-      for (int pos = 0;
-           pos < segs.length && segs[pos] == '..';
-           ++pos) {
+    List segs = _path.split('/'); // Don't mask the getter 'segments'.
+    if (segs[0] == '') {
+      // Absolute path
+      segs[0] = null; // Faster than removeRange().
+    } else {
+      // A canonical relative path may start with .. segments.
+      for (int pos = 0; pos < segs.length && segs[pos] == '..'; ++pos) {
         segs[pos] = null;
       }
     }
-    if (segs.last == '') segs.removeLast();  // Path ends with /.
+    if (segs.last == '') segs.removeLast(); // Path ends with /.
     // No remaining segments can be ., .., or empty.
     return !segs.any((s) => s == '' || s == '.' || s == '..');
   }
@@ -196,10 +193,7 @@
     bool isAbs = isAbsolute;
     List segs = segments();
     String drive;
-    if (isAbs &&
-        !segs.isEmpty &&
-        segs[0].length == 2 &&
-        segs[0][1] == ':') {
+    if (isAbs && !segs.isEmpty && segs[0].length == 2 && segs[0][1] == ':') {
       drive = segs[0];
       segs.removeRange(0, 1);
     }
diff --git a/tools/testing/dart/record_and_replay.dart b/tools/testing/dart/record_and_replay.dart
index 68e67ce..022c35d 100644
--- a/tools/testing/dart/record_and_replay.dart
+++ b/tools/testing/dart/record_and_replay.dart
@@ -52,7 +52,7 @@
   var _cwd;
 
   TestCaseRecorder(this._outputPath) {
-    _cwd  = Directory.current.path;
+    _cwd = Directory.current.path;
   }
 
   void nextCommand(ProcessCommand command, int timeout) {
@@ -63,11 +63,11 @@
     var arguments = makePathsRelativeToDart(_cwd, command.arguments);
 
     var commandExecution = {
-      'name' : command.displayName,
-      'command' : {
-        'timeout_limit' : timeout,
-        'executable' : command.executable,
-        'arguments' : arguments,
+      'name': command.displayName,
+      'command': {
+        'timeout_limit': timeout,
+        'executable': command.executable,
+        'arguments': arguments,
       },
     };
     _recordedCommandInvocations.add(commandExecution);
@@ -86,7 +86,7 @@
   var _cwd;
 
   TestCaseOutputArchive() {
-    _cwd  = Directory.current.path;
+    _cwd = Directory.current.path;
   }
 
   void loadFromPath(Path recordingPath) {
@@ -95,7 +95,7 @@
     _commandOutputRecordings = {};
     for (var commandRecording in commandRecordings) {
       var key = _indexKey(commandRecording['command']['executable'],
-                          commandRecording['command']['arguments'].join(' '));
+          commandRecording['command']['arguments'].join(' '));
       _commandOutputRecordings[key] = commandRecording['command_output'];
     }
   }
@@ -111,13 +111,13 @@
     var command_output = _commandOutputRecordings[key];
     if (command_output == null) {
       print("Sorry, but there is no command output for ${command.displayName}"
-            " ($command)");
+          " ($command)");
       exit(42);
     }
 
     double seconds = command_output['duration'];
-    var duration = new Duration(seconds: seconds.round(),
-                                milliseconds: (seconds/1000).round());
+    var duration = new Duration(
+        seconds: seconds.round(), milliseconds: (seconds / 1000).round());
     var commandOutput = createCommandOutput(
         command,
         command_output['exit_code'],
@@ -133,4 +133,3 @@
     return "${executable}__$arguments";
   }
 }
-
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index 55cf8fe..8766322 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -4,17 +4,13 @@
 
 library runtime_configuration;
 
-import 'compiler_configuration.dart' show
-    CommandArtifact;
+import 'compiler_configuration.dart' show CommandArtifact;
 
 // TODO(ahe): Remove this import, we can precompute all the values required
 // from TestSuite once the refactoring is complete.
-import 'test_suite.dart' show
-    TestSuite;
+import 'test_suite.dart' show TestSuite;
 
-import 'test_runner.dart' show
-    Command,
-    CommandBuilder;
+import 'test_runner.dart' show Command, CommandBuilder;
 
 // TODO(ahe): I expect this class will become abstract very soon.
 class RuntimeConfiguration {
@@ -68,10 +64,8 @@
 
   RuntimeConfiguration._subclass();
 
-  int computeTimeoutMultiplier({
-      String mode,
-      bool isChecked: false,
-      String arch}) {
+  int computeTimeoutMultiplier(
+      {String mode, bool isChecked: false, String arch}) {
     return 1;
   }
 
@@ -90,8 +84,7 @@
 
 /// The 'none' runtime configuration.
 class NoneRuntimeConfiguration extends RuntimeConfiguration {
-  NoneRuntimeConfiguration()
-      : super._subclass();
+  NoneRuntimeConfiguration() : super._subclass();
 
   List<Command> computeRuntimeCommands(
       TestSuite suite,
@@ -106,8 +99,7 @@
 class CommandLineJavaScriptRuntime extends RuntimeConfiguration {
   final String moniker;
 
-  CommandLineJavaScriptRuntime(this.moniker)
-      : super._subclass();
+  CommandLineJavaScriptRuntime(this.moniker) : super._subclass();
 
   void checkArtifact(CommandArtifact artifact) {
     String type = artifact.mimeType;
@@ -119,8 +111,7 @@
 
 /// Chrome/V8-based development shell (d8).
 class D8RuntimeConfiguration extends CommandLineJavaScriptRuntime {
-  D8RuntimeConfiguration()
-      : super('d8');
+  D8RuntimeConfiguration() : super('d8');
 
   List<Command> computeRuntimeCommands(
       TestSuite suite,
@@ -131,8 +122,9 @@
     // TODO(ahe): Avoid duplication of this method between d8 and jsshell.
     checkArtifact(artifact);
     return <Command>[
-        commandBuilder.getJSCommandlineCommand(
-            moniker, suite.d8FileName, arguments, environmentOverrides)];
+      commandBuilder.getJSCommandlineCommand(
+          moniker, suite.d8FileName, arguments, environmentOverrides)
+    ];
   }
 
   List<String> dart2jsPreambles(Uri preambleDir) {
@@ -142,8 +134,7 @@
 
 /// Firefox/SpiderMonkey-based development shell (jsshell).
 class JsshellRuntimeConfiguration extends CommandLineJavaScriptRuntime {
-  JsshellRuntimeConfiguration()
-      : super('jsshell');
+  JsshellRuntimeConfiguration() : super('jsshell');
 
   List<Command> computeRuntimeCommands(
       TestSuite suite,
@@ -153,8 +144,9 @@
       Map<String, String> environmentOverrides) {
     checkArtifact(artifact);
     return <Command>[
-        commandBuilder.getJSCommandlineCommand(
-            moniker, suite.jsShellFileName, arguments, environmentOverrides)];
+      commandBuilder.getJSCommandlineCommand(
+          moniker, suite.jsShellFileName, arguments, environmentOverrides)
+    ];
   }
 
   List<String> dart2jsPreambles(Uri preambleDir) {
@@ -164,20 +156,17 @@
 
 /// Common runtime configuration for runtimes based on the Dart VM.
 class DartVmRuntimeConfiguration extends RuntimeConfiguration {
-  DartVmRuntimeConfiguration()
-      : super._subclass();
+  DartVmRuntimeConfiguration() : super._subclass();
 
-  int computeTimeoutMultiplier({
-      String mode,
-      bool isChecked: false,
-      String arch}) {
+  int computeTimeoutMultiplier(
+      {String mode, bool isChecked: false, String arch}) {
     int multiplier = 1;
     switch (arch) {
       case 'simarm':
       case 'arm':
       case 'simarmv6':
       case 'armv6':
-      case' simarmv5te':
+      case ' simarmv5te':
       case 'armv5te':
       case 'simmips':
       case 'mips':
@@ -195,16 +184,14 @@
 /// Runtime configuration for Content Shell.  We previously used a similar
 /// program named Dump Render Tree, hence the name.
 class DrtRuntimeConfiguration extends DartVmRuntimeConfiguration {
-  int computeTimeoutMultiplier({
-      String mode,
-      bool isChecked: false,
-      String arch}) {
+  int computeTimeoutMultiplier(
+      {String mode, bool isChecked: false, String arch}) {
     return 4 // Allow additional time for browser testing to run.
         // TODO(ahe): We might need to distinquish between DRT for running
         // JavaScript and Dart code.  I'm not convinced the inherited timeout
         // multiplier is relevant for JavaScript.
-        * super.computeTimeoutMultiplier(
-            mode: mode, isChecked: isChecked);
+        *
+        super.computeTimeoutMultiplier(mode: mode, isChecked: isChecked);
   }
 }
 
@@ -224,8 +211,9 @@
     String executable = suite.configuration['noopt']
         ? suite.dartVmNooptBinaryFileName
         : suite.dartVmBinaryFileName;
-    return <Command>[commandBuilder.getVmCommand(
-          executable, arguments, environmentOverrides)];
+    return <Command>[
+      commandBuilder.getVmCommand(executable, arguments, environmentOverrides)
+    ];
   }
 }
 
@@ -246,10 +234,10 @@
     augmentedArgs.add("--run-full-snapshot=${artifact.filename}");
     augmentedArgs.addAll(arguments);
 
-    return <Command>[commandBuilder.getVmCommand(
-          suite.dartVmProductBinaryFileName,
-          augmentedArgs,
-          environmentOverrides)];
+    return <Command>[
+      commandBuilder.getVmCommand(suite.dartVmProductBinaryFileName,
+          augmentedArgs, environmentOverrides)
+    ];
   }
 }
 
@@ -270,10 +258,10 @@
     augmentedArgs.add("--run-precompiled-snapshot=${artifact.filename}");
     augmentedArgs.addAll(arguments);
 
-    return <Command>[commandBuilder.getVmCommand(
-        suite.dartPrecompiledBinaryFileName,
-        augmentedArgs,
-        environmentOverrides)];
+    return <Command>[
+      commandBuilder.getVmCommand(suite.dartPrecompiledBinaryFileName,
+          augmentedArgs, environmentOverrides)
+    ];
   }
 }
 
diff --git a/tools/testing/dart/status_expression.dart b/tools/testing/dart/status_expression.dart
index 5cd0a34..c5b0b80 100644
--- a/tools/testing/dart/status_expression.dart
+++ b/tools/testing/dart/status_expression.dart
@@ -49,13 +49,11 @@
   static const String OR = "||";
 }
 
-
 class Tokenizer {
   String expression;
   List<String> tokens;
 
-  Tokenizer(String this.expression)
-    : tokens = new List<String>();
+  Tokenizer(String this.expression) : tokens = new List<String>();
 
   // Tokens are : "(", ")", "$", ",", "&&", "||", "==", "!=", and (maximal) \w+.
   static final testRegexp =
@@ -71,17 +69,14 @@
   }
 }
 
-
 abstract class BooleanExpression {
   bool evaluate(Map<String, String> environment);
 }
 
-
 abstract class SetExpression {
   Set<String> evaluate(Map<String, String> environment);
 }
 
-
 class Comparison implements BooleanExpression {
   TermVariable left;
   TermConstant right;
@@ -90,15 +85,14 @@
   Comparison(this.left, this.right, this.negate);
 
   bool evaluate(environment) {
-    return
-        negate != (left.termValue(environment) == right.termValue(environment));
+    return negate !=
+        (left.termValue(environment) == right.termValue(environment));
   }
 
   String toString() =>
       "(\$${left.name} ${negate ? '!=' : '=='} ${right.value})";
 }
 
-
 class TermVariable {
   String name;
 
@@ -107,15 +101,13 @@
   String termValue(environment) {
     var value = environment[name];
     if (value == null) {
-      throw new ExprEvaluationException(
-          "Could not find '$name' in environment "
+      throw new ExprEvaluationException("Could not find '$name' in environment "
           "while evaluating status file expression.");
     }
     return value.toString();
   }
 }
 
-
 class TermConstant {
   String value;
 
@@ -124,7 +116,6 @@
   String termValue(environment) => value;
 }
 
-
 class BooleanVariable implements BooleanExpression {
   TermVariable variable;
 
@@ -134,7 +125,6 @@
   String toString() => "(bool \$${variable.name})";
 }
 
-
 class BooleanOperation implements BooleanExpression {
   String op;
   BooleanExpression left;
@@ -142,13 +132,12 @@
 
   BooleanOperation(this.op, this.left, this.right);
 
-  bool evaluate(environment) => (op == Token.AND) ?
-      left.evaluate(environment) && right.evaluate(environment) :
-      left.evaluate(environment) || right.evaluate(environment);
+  bool evaluate(environment) => (op == Token.AND)
+      ? left.evaluate(environment) && right.evaluate(environment)
+      : left.evaluate(environment) || right.evaluate(environment);
   String toString() => "($left $op $right)";
 }
 
-
 class SetUnion implements SetExpression {
   SetExpression left;
   SetExpression right;
@@ -166,19 +155,18 @@
   String toString() => "($left || $right)";
 }
 
-
 class SetIf implements SetExpression {
   SetExpression left;
   BooleanExpression right;
 
   SetIf(this.left, this.right);
 
-  Set<String> evaluate(environment) => right.evaluate(environment) ?
-    left.evaluate(environment) : new Set<String>();
+  Set<String> evaluate(environment) => right.evaluate(environment)
+      ? left.evaluate(environment)
+      : new Set<String>();
   String toString() => "($left if $right)";
 }
 
-
 class SetConstant implements SetExpression {
   String value;
 
@@ -188,7 +176,6 @@
   String toString() => value;
 }
 
-
 // An iterator that allows peeking at the current token.
 class Scanner {
   List<String> tokens;
@@ -207,7 +194,6 @@
   }
 }
 
-
 class ExpressionParser {
   Scanner scanner;
 
@@ -217,7 +203,7 @@
 
   SetExpression parseSetUnion() {
     SetExpression left = parseSetIf();
-    while (scanner.hasMore() && scanner.current == Token.UNION){
+    while (scanner.hasMore() && scanner.current == Token.UNION) {
       scanner.advance();
       SetExpression right = parseSetIf();
       left = new SetUnion(left, right);
@@ -237,7 +223,7 @@
 
   SetExpression parseSetOr() {
     SetExpression left = parseSetAtomic();
-    while (scanner.hasMore() && scanner.current == Token.OR){
+    while (scanner.hasMore() && scanner.current == Token.OR) {
       scanner.advance();
       SetExpression right = parseSetAtomic();
       left = new SetUnion(left, right);
@@ -245,7 +231,6 @@
     return left;
   }
 
-
   SetExpression parseSetAtomic() {
     if (scanner.current == Token.LEFT_PAREN) {
       scanner.advance();
@@ -327,4 +312,3 @@
     }
   }
 }
-
diff --git a/tools/testing/dart/status_file_parser.dart b/tools/testing/dart/status_file_parser.dart
index 8c32e6e..8fa9bb7 100644
--- a/tools/testing/dart/status_file_parser.dart
+++ b/tools/testing/dart/status_file_parser.dart
@@ -25,8 +25,7 @@
   static Expectation MISSING_COMPILETIME_ERROR =
       byName('MissingCompileTimeError');
   static Expectation STATIC_WARNING = byName('StaticWarning');
-  static Expectation MISSING_STATIC_WARNING =
-      byName('MissingStaticWarning');
+  static Expectation MISSING_STATIC_WARNING = byName('MissingStaticWarning');
   static Expectation PUB_GET_ERROR = byName('PubGetError');
 
   // "meta expectations"
@@ -46,7 +45,7 @@
   }
 
   // Keep a map of all possible Expectation objects, initialized lazily.
-  static Map<String, Expectation>  _AllExpectations;
+  static Map<String, Expectation> _AllExpectations;
   static void _initialize() {
     if (_AllExpectations == null) {
       _AllExpectations = new Map<String, Expectation>();
@@ -89,9 +88,9 @@
   final bool isMetaExpectation;
 
   Expectation._(prettyName,
-                {Expectation this.group: null,
-                 bool this.isMetaExpectation: false})
-      : prettyName = prettyName, name = prettyName.toLowerCase();
+      {Expectation this.group: null, bool this.isMetaExpectation: false})
+      : prettyName = prettyName,
+        name = prettyName.toLowerCase();
 
   bool canBeOutcomeOf(Expectation expectation) {
     Expectation outcome = this;
@@ -107,7 +106,6 @@
   String toString() => prettyName;
 }
 
-
 final RegExp SplitComment = new RegExp("^([^#]*)(#.*)?\$");
 final RegExp HeaderPattern = new RegExp(r"^\[([^\]]+)\]");
 final RegExp RulePattern = new RegExp(r"\s*([^: ]*)\s*:(.*)");
@@ -129,7 +127,8 @@
   final int lineNumber;
 
   Section.always(this.statusFile, this.lineNumber)
-      : condition = null, testRules = new List<TestRule>();
+      : condition = null,
+        testRules = new List<TestRule>();
   Section(this.statusFile, this.condition, this.lineNumber)
       : testRules = new List<TestRule>();
 
@@ -141,18 +140,16 @@
   }
 }
 
-Future<TestExpectations> ReadTestExpectations(List<String> statusFilePaths,
-                                              Map environment) {
+Future<TestExpectations> ReadTestExpectations(
+    List<String> statusFilePaths, Map environment) {
   var testExpectations = new TestExpectations();
   return Future.wait(statusFilePaths.map((String statusFile) {
-    return ReadTestExpectationsInto(
-        testExpectations, statusFile, environment);
+    return ReadTestExpectationsInto(testExpectations, statusFile, environment);
   })).then((_) => testExpectations);
 }
 
-Future ReadTestExpectationsInto(TestExpectations expectations,
-                                String statusFilePath,
-                                environment) {
+Future ReadTestExpectationsInto(
+    TestExpectations expectations, String statusFilePath, environment) {
   var completer = new Completer();
   List<Section> sections = new List<Section>();
 
@@ -179,14 +176,11 @@
   }
   int lineNumber = 0;
   Stream<String> lines =
-      file.openRead()
-          .transform(UTF8.decoder)
-          .transform(new LineSplitter());
+      file.openRead().transform(UTF8.decoder).transform(new LineSplitter());
 
   Section currentSection = new Section.always(statusFile, -1);
   sections.add(currentSection);
 
-
   lines.listen((String line) {
     lineNumber++;
     Match match = SplitComment.firstMatch(line);
@@ -225,34 +219,28 @@
         if (issueString == null) issueString = match[2];
       }
       int issue = issueString != null ? int.parse(issueString) : null;
-      currentSection.testRules.add(
-          new TestRule(name, expression, issue, lineNumber));
+      currentSection.testRules
+          .add(new TestRule(name, expression, issue, lineNumber));
       return;
     }
 
     print("unmatched line: $line");
-  },
-  onDone: onDone);
+  }, onDone: onDone);
 }
 
-
 class TestRule {
   String name;
   SetExpression expression;
   int issue;
   int lineNumber;
 
-  TestRule(this.name,
-           this.expression,
-           this.issue,
-           this.lineNumber);
+  TestRule(this.name, this.expression, this.issue, this.lineNumber);
 
   bool get hasIssue => issue != null;
 
   String toString() => 'TestRule($name, $expression, $issue)';
 }
 
-
 class TestExpectations {
   // Only create one copy of each Set<Expectation>.
   // We just use .toString as a key, so we may make a few
diff --git a/tools/testing/dart/status_reporter.dart b/tools/testing/dart/status_reporter.dart
index 5841052..0f5e37b 100644
--- a/tools/testing/dart/status_reporter.dart
+++ b/tools/testing/dart/status_reporter.dart
@@ -6,78 +6,78 @@
 import 'dart:convert';
 
 List<Map> LINUX_COMBINATIONS = [
-    {
-      'runtimes' : ['none'],
-      'modes' : ['release'],
-      'archs' : ['x64'],
-      'compiler' : 'dart2analyzer'
-    },
-    {
-      'runtimes' : ['vm'],
-      'modes' : ['debug', 'release'],
-      'archs' : ['ia32', 'x64', 'simarm', 'simmips'],
-      'compiler' : 'none'
-    },
-    {
-      'runtimes' : ['d8', 'jsshell', 'chrome', 'ff'],
-      'modes' : ['release'],
-      'archs' : ['ia32'],
-      'compiler' : 'dart2js'
-    },
-    {
-      'runtimes' : ['dartium'],
-      'modes' : ['release', 'debug'],
-      'archs' : ['ia32'],
-      'compiler' : 'none'
-    },
+  {
+    'runtimes': ['none'],
+    'modes': ['release'],
+    'archs': ['x64'],
+    'compiler': 'dart2analyzer'
+  },
+  {
+    'runtimes': ['vm'],
+    'modes': ['debug', 'release'],
+    'archs': ['ia32', 'x64', 'simarm', 'simmips'],
+    'compiler': 'none'
+  },
+  {
+    'runtimes': ['d8', 'jsshell', 'chrome', 'ff'],
+    'modes': ['release'],
+    'archs': ['ia32'],
+    'compiler': 'dart2js'
+  },
+  {
+    'runtimes': ['dartium'],
+    'modes': ['release', 'debug'],
+    'archs': ['ia32'],
+    'compiler': 'none'
+  },
 ];
 
 List<Map> MACOS_COMBINATIONS = [
-    {
-      'runtimes' : ['vm'],
-      'modes' : ['debug', 'release'],
-      'archs' : ['ia32', 'x64'],
-      'compiler' : 'none'
-    },
-    {
-      'runtimes' : ['safari', 'safarimobilesim'],
-      'modes' : ['release'],
-      'archs' : ['ia32'],
-      'compiler' : 'dart2js'
-    },
-    {
-      'runtimes' : ['dartium'],
-      'modes' : ['release', 'debug'],
-      'archs' : ['ia32'],
-      'compiler' : 'none'
-    },
+  {
+    'runtimes': ['vm'],
+    'modes': ['debug', 'release'],
+    'archs': ['ia32', 'x64'],
+    'compiler': 'none'
+  },
+  {
+    'runtimes': ['safari', 'safarimobilesim'],
+    'modes': ['release'],
+    'archs': ['ia32'],
+    'compiler': 'dart2js'
+  },
+  {
+    'runtimes': ['dartium'],
+    'modes': ['release', 'debug'],
+    'archs': ['ia32'],
+    'compiler': 'none'
+  },
 ];
 
 List<Map> WINDOWS_COMBINATIONS = [
-    {
-      'runtimes' : ['vm'],
-      'modes' : ['debug', 'release'],
-      'archs' : ['ia32', 'x64'],
-      'compiler' : 'none'
-    },
-    {
-      'runtimes' : ['chrome', 'ff', 'ie11', 'ie10'],
-      'modes' : ['release'],
-      'archs' : ['ia32'],
-      'compiler' : 'dart2js'
-    },
-    {
-      'runtimes' : ['dartium'],
-      'modes' : ['release', 'debug'],
-      'archs' : ['ia32'],
-      'compiler' : 'none'
-    },
+  {
+    'runtimes': ['vm'],
+    'modes': ['debug', 'release'],
+    'archs': ['ia32', 'x64'],
+    'compiler': 'none'
+  },
+  {
+    'runtimes': ['chrome', 'ff', 'ie11', 'ie10'],
+    'modes': ['release'],
+    'archs': ['ia32'],
+    'compiler': 'dart2js'
+  },
+  {
+    'runtimes': ['dartium'],
+    'modes': ['release', 'debug'],
+    'archs': ['ia32'],
+    'compiler': 'none'
+  },
 ];
 
 Map<String, List<Map>> COMBINATIONS = {
-  'linux' : LINUX_COMBINATIONS,
-  'windows' : WINDOWS_COMBINATIONS,
-  'macos' : MACOS_COMBINATIONS
+  'linux': LINUX_COMBINATIONS,
+  'windows': WINDOWS_COMBINATIONS,
+  'macos': MACOS_COMBINATIONS
 };
 
 List<Map> getCombinations() {
@@ -165,8 +165,15 @@
         for (var runtime in combination['runtimes']) {
           var compiler = combination['compiler'];
 
-          var args = ['tools/test.py', '-m$mode', '-c$compiler', '-r$runtime',
-                      '-a$arch', '--report-in-json', '--use-sdk'];
+          var args = [
+            'tools/test.py',
+            '-m$mode',
+            '-c$compiler',
+            '-r$runtime',
+            '-a$arch',
+            '--report-in-json',
+            '--use-sdk'
+          ];
           var result = Process.runSync('python', args);
           if (result.exitCode != 0) {
             print(result.stdout);
@@ -202,7 +209,7 @@
           for (var key in keys) {
             var value = map[key];
             values.add(value);
-            var pct = 100*(value/total);
+            var pct = 100 * (value / total);
             values.add('${pct.toStringAsFixed(3)}%');
           }
 
diff --git a/tools/testing/dart/summary_report.dart b/tools/testing/dart/summary_report.dart
index 2f740b5..e62f772 100644
--- a/tools/testing/dart/summary_report.dart
+++ b/tools/testing/dart/summary_report.dart
@@ -37,7 +37,7 @@
         .any((expectation) => expectation.canBeOutcomeOf(Expectation.FAIL));
     bool containsPass = expectations.contains(Expectation.PASS);
     bool containsSkip = expectations
-      .any((expectation) => expectation.canBeOutcomeOf(Expectation.SKIP));
+        .any((expectation) => expectation.canBeOutcomeOf(Expectation.SKIP));
     bool containsSkipByDesign =
         expectations.contains(Expectation.SKIP_BY_DESIGN);
     bool containsCrash = expectations.contains(Expectation.CRASH);
@@ -100,19 +100,19 @@
   }
 
   Map<String, int> get values => {
-    'total': _total,
-    'skippedOther': skippedOther,
-    'skippedByDesign': _skippedByDesign,
-    'pass': _pass,
-    'noCrash': _noCrash,
-    'flakyCrash': _flakyCrash,
-    'failOk': _failOk,
-    'fail': _fail,
-    'crash': _crash,
-    'timeout': _timeout,
-    'compileErrorSkip': _compileErrorSkip,
-    'bogus': bogus
-  };
+        'total': _total,
+        'skippedOther': skippedOther,
+        'skippedByDesign': _skippedByDesign,
+        'pass': _pass,
+        'noCrash': _noCrash,
+        'flakyCrash': _flakyCrash,
+        'failOk': _failOk,
+        'fail': _fail,
+        'crash': _crash,
+        'timeout': _timeout,
+        'compileErrorSkip': _compileErrorSkip,
+        'bogus': bogus
+      };
 
   String get report => """Total: $_total tests
  * $_skipped tests will be skipped ($_skippedByDesign skipped by design)
diff --git a/tools/testing/dart/test_configurations.dart b/tools/testing/dart/test_configurations.dart
index c7d4a09..ff48273 100644
--- a/tools/testing/dart/test_configurations.dart
+++ b/tools/testing/dart/test_configurations.dart
@@ -26,27 +26,27 @@
  * moved to here, if possible.
 */
 final TEST_SUITE_DIRECTORIES = [
-    new Path('pkg'),
-    new Path('third_party/pkg_tested'),
-    new Path('runtime/tests/vm'),
-    new Path('runtime/observatory/tests/service'),
-    new Path('samples'),
-    new Path('samples-dev'),
-    new Path('tests/benchmark_smoke'),
-    new Path('tests/chrome'),
-    new Path('tests/compiler/dart2js'),
-    new Path('tests/compiler/dart2js_extra'),
-    new Path('tests/compiler/dart2js_native'),
-    new Path('tests/corelib'),
-    new Path('tests/html'),
-    new Path('tests/isolate'),
-    new Path('tests/language'),
-    new Path('tests/lib'),
-    new Path('tests/standalone'),
-    new Path('tests/try'),
-    new Path('tests/utils'),
-    new Path('utils/tests/css'),
-    new Path('utils/tests/peg'),
+  new Path('pkg'),
+  new Path('third_party/pkg_tested'),
+  new Path('runtime/tests/vm'),
+  new Path('runtime/observatory/tests/service'),
+  new Path('samples'),
+  new Path('samples-dev'),
+  new Path('tests/benchmark_smoke'),
+  new Path('tests/chrome'),
+  new Path('tests/compiler/dart2js'),
+  new Path('tests/compiler/dart2js_extra'),
+  new Path('tests/compiler/dart2js_native'),
+  new Path('tests/corelib'),
+  new Path('tests/html'),
+  new Path('tests/isolate'),
+  new Path('tests/language'),
+  new Path('tests/lib'),
+  new Path('tests/standalone'),
+  new Path('tests/try'),
+  new Path('tests/utils'),
+  new Path('utils/tests/css'),
+  new Path('utils/tests/peg'),
 ];
 
 void testConfigurations(List<Map> configurations) {
@@ -72,13 +72,15 @@
 
   if (recordingPath != null && recordingOutputPath != null) {
     print("Fatal: Can't have the '--record_to_file' and '--replay_from_file'"
-          "at the same time. Exiting ...");
+        "at the same time. Exiting ...");
     exit(1);
   }
 
-  if (!firstConf['append_logs'])  {
-    var files = [new File(TestUtils.flakyFileName()),
-                 new File(TestUtils.testOutcomeFileName())];
+  if (!firstConf['append_logs']) {
+    var files = [
+      new File(TestUtils.flakyFileName()),
+      new File(TestUtils.testOutcomeFileName())
+    ];
     for (var file in files) {
       if (file.existsSync()) {
         file.deleteSync();
@@ -86,18 +88,21 @@
     }
   }
 
-  DebugLogger.init(firstConf['write_debug_log'] ?
-      TestUtils.debugLogfile() : null, append: firstConf['append_logs']);
+  DebugLogger.init(
+      firstConf['write_debug_log'] ? TestUtils.debugLogfile() : null,
+      append: firstConf['append_logs']);
 
   // Print the configurations being run by this execution of
   // test.dart. However, don't do it if the silent progress indicator
   // is used. This is only needed because of the junit tests.
   if (progressIndicator != 'silent') {
-    List output_words = configurations.length > 1 ?
-        ['Test configurations:'] : ['Test configuration:'];
+    List output_words = configurations.length > 1
+        ? ['Test configurations:']
+        : ['Test configuration:'];
     for (Map conf in configurations) {
       List settings = ['compiler', 'runtime', 'mode', 'arch']
-          .map((name) => conf[name]).toList();
+          .map((name) => conf[name])
+          .toList();
       if (conf['checked']) settings.add('checked');
       if (conf['noopt']) settings.add('noopt');
       output_words.add(settings.join('_'));
@@ -114,9 +119,9 @@
   var maxBrowserProcesses = maxProcesses;
   if (configurations.length > 1 &&
       (configurations[0]['test_server_port'] != 0 ||
-       configurations[0]['test_server_cross_origin_port'] != 0)) {
+          configurations[0]['test_server_cross_origin_port'] != 0)) {
     print("If the http server ports are specified, only one configuration"
-          " may be run at a time");
+        " may be run at a time");
     exit(1);
   }
   for (var conf in configurations) {
@@ -127,11 +132,12 @@
       // The http server is available on window.location.port, and a second
       // server for cross-domain tests can be found by calling
       // getCrossOriginPortNumber().
-      var servers = new TestingServers(new Path(TestUtils.buildDir(conf)),
-                                       useContentSecurityPolicy,
-                                       conf['runtime'],
-                                       null,
-                                       conf['package_root']);
+      var servers = new TestingServers(
+          new Path(TestUtils.buildDir(conf)),
+          useContentSecurityPolicy,
+          conf['runtime'],
+          null,
+          conf['package_root']);
       serverFutures.add(servers.startServers(conf['local_ip'],
           port: conf['test_server_port'],
           crossOriginPort: conf['test_server_cross_origin_port']));
@@ -158,7 +164,7 @@
       // for mobile safari simultainiously.
       maxBrowserProcesses = 1;
     } else if (conf['runtime'] == 'chrome' &&
-               Platform.operatingSystem == 'macos') {
+        Platform.operatingSystem == 'macos') {
       // Chrome on mac results in random timeouts.
       // Issue: https://github.com/dart-lang/sdk/issues/23891
       // This change does not fix the problem.
@@ -180,8 +186,8 @@
         if (key == 'co19') {
           testSuites.add(new Co19TestSuite(conf));
         } else if (conf['compiler'] == 'none' &&
-                   conf['runtime'] == 'vm' &&
-                   key == 'vm') {
+            conf['runtime'] == 'vm' &&
+            key == 'vm') {
           // vm tests contain both cc tests (added here) and dart tests (added
           // in [TEST_SUITE_DIRECTORIES]).
           testSuites.add(new VMTestSuite(conf));
@@ -190,17 +196,17 @@
             testSuites.add(new AnalyzeLibraryTestSuite(conf));
           }
         } else if (conf['compiler'] == 'none' &&
-                   conf['runtime'] == 'vm' &&
-                   key == 'pkgbuild') {
+            conf['runtime'] == 'vm' &&
+            key == 'pkgbuild') {
           if (!conf['use_repository_packages'] &&
               !conf['use_public_packages']) {
             print("You need to use either --use-repository-packages or "
-                  "--use-public-packages with the pkgbuild test suite!");
+                "--use-public-packages with the pkgbuild test suite!");
             exit(1);
           }
           if (!conf['use_sdk']) {
             print("Running the 'pkgbuild' test suite requires "
-                  "passing the '--use-sdk' to test.py");
+                "passing the '--use-sdk' to test.py");
             exit(1);
           }
           testSuites.add(
@@ -211,8 +217,8 @@
       for (final testSuiteDir in TEST_SUITE_DIRECTORIES) {
         final name = testSuiteDir.filename;
         if (selectors.containsKey(name)) {
-          testSuites.add(
-              new StandardTestSuite.forDirectory(conf, testSuiteDir));
+          testSuites
+              .add(new StandardTestSuite.forDirectory(conf, testSuiteDir));
         }
       }
     }
@@ -252,9 +258,8 @@
       var printFailureSummary = progressIndicator != 'buildbot';
       eventListener.add(new TestFailurePrinter(printFailureSummary, formatter));
     }
-    eventListener.add(progressIndicatorFromName(progressIndicator,
-                                                startTime,
-                                                formatter));
+    eventListener.add(
+        progressIndicatorFromName(progressIndicator, startTime, formatter));
     if (printTiming) {
       eventListener.add(new TimingPrinter(startTime));
     }
@@ -279,16 +284,17 @@
   void startProcessQueue() {
     // [firstConf] is needed here, since the ProcessQueue needs to know the
     // settings of 'noBatch' and 'local_ip'
-    new ProcessQueue(firstConf,
-                     maxProcesses,
-                     maxBrowserProcesses,
-                     startTime,
-                     testSuites,
-                     eventListener,
-                     allTestsFinished,
-                     verbose,
-                     recordingPath,
-                     recordingOutputPath);
+    new ProcessQueue(
+        firstConf,
+        maxProcesses,
+        maxBrowserProcesses,
+        startTime,
+        testSuites,
+        eventListener,
+        allTestsFinished,
+        verbose,
+        recordingPath,
+        recordingOutputPath);
   }
 
   // Start all the HTTP servers required before starting the process queue.
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index 26d5249..9cbd3c2 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -11,10 +11,22 @@
 import "compiler_configuration.dart" show CompilerConfiguration;
 import "runtime_configuration.dart" show RuntimeConfiguration;
 
-const List<String> defaultTestSelectors =
-    const ['samples', 'standalone', 'corelib', 'co19', 'language',
-           'isolate', 'vm', 'html', 'benchmark_smoke',
-           'utils', 'lib', 'pkg', 'analyze_library', 'service'];
+const List<String> defaultTestSelectors = const [
+  'samples',
+  'standalone',
+  'corelib',
+  'co19',
+  'language',
+  'isolate',
+  'vm',
+  'html',
+  'benchmark_smoke',
+  'utils',
+  'lib',
+  'pkg',
+  'analyze_library',
+  'service'
+];
 
 /**
  * Specification of a single test option.
@@ -23,12 +35,9 @@
  * the Map returned from the [TestOptionParser] parse method.
  */
 class _TestOptionSpecification {
-  _TestOptionSpecification(this.name,
-                           this.description,
-                           this.keys,
-                           this.values,
-                           this.defaultValue,
-                           {this.type : 'string'});
+  _TestOptionSpecification(
+      this.name, this.description, this.keys, this.values, this.defaultValue,
+      {this.type: 'string'});
   String name;
   String description;
   List<String> keys;
@@ -45,16 +54,12 @@
    * Creates a test options parser initialized with the known options.
    */
   TestOptionsParser() {
-    _options =
-        [ new _TestOptionSpecification(
-              'mode',
-              'Mode in which to run the tests',
-              ['-m', '--mode'],
-              ['all', 'debug', 'release', 'product'],
-              'debug'),
-          new _TestOptionSpecification(
-              'compiler',
-              '''Specify any compilation step (if needed).
+    _options = [
+      new _TestOptionSpecification('mode', 'Mode in which to run the tests',
+          ['-m', '--mode'], ['all', 'debug', 'release', 'product'], 'debug'),
+      new _TestOptionSpecification(
+          'compiler',
+          '''Specify any compilation step (if needed).
 
    none: Do not compile the Dart code (run native Dart code on the VM).
          (only valid with the following runtimes: vm, drt)
@@ -69,14 +74,13 @@
 
    dart2app: Compile the Dart code into an app snapshot before running the test
           (only valid with the following runtimes: dart_product)''',
-              ['-c', '--compiler'],
-              ['none', 'precompiler', 'dart2js', 'dart2analyzer',
-               'dart2app'],
-              'none'),
-          // TODO(antonm): fix the option drt.
-          new _TestOptionSpecification(
-              'runtime',
-              '''Where the tests should be run.
+          ['-c', '--compiler'],
+          ['none', 'precompiler', 'dart2js', 'dart2analyzer', 'dart2app'],
+          'none'),
+      // TODO(antonm): fix the option drt.
+      new _TestOptionSpecification(
+          'runtime',
+          '''Where the tests should be run.
     vm: Run Dart code on the standalone dart vm.
 
     dart_precompiled: Run a precompiled snapshot on a variant of the standalone
@@ -103,372 +107,325 @@
 
     none: No runtime, compile only (for example, used for dart2analyzer static
           analysis tests).''',
-              ['-r', '--runtime'],
-              ['vm', 'dart_precompiled', 'dart_product',
-               'd8', 'jsshell', 'drt', 'dartium',
-               'ff', 'firefox',
-               'chrome', 'safari', 'ie9', 'ie10', 'ie11', 'opera',
-               'chromeOnAndroid', 'safarimobilesim',
-               'ContentShellOnAndroid', 'DartiumOnAndroid', 'none'],
-              'vm'),
-          new _TestOptionSpecification(
-              'arch',
-              'The architecture to run tests for',
-              ['-a', '--arch'],
-              ['all', 'ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64', 'mips',
-               'simarm', 'simarmv6', 'simarmv5te', 'simarm64', 'simmips'],
-              'x64'),
-          new _TestOptionSpecification(
-              'system',
-              'The operating system to run tests on',
-              ['-s', '--system'],
-              ['linux', 'macos', 'windows'],
-              Platform.operatingSystem),
-          new _TestOptionSpecification(
-              'checked',
-              'Run tests in checked mode',
-              ['--checked'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'host_checked',
-              'Run compiler in checked mode',
-              ['--host-checked'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'minified',
-              'Enable minification in the compiler',
-              ['--minified'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'csp',
-              'Run tests under Content Security Policy restrictions',
-              ['--csp'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'cps_ir',
-              'Run the compiler with the cps based backend',
-              ['--cps-ir'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'noopt',
-              'Run an in-place precompilation',
-              ['--noopt'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'timeout',
-              'Timeout in seconds',
-              ['-t', '--timeout'],
-              [],
-              -1,
-              type: 'int'),
-          new _TestOptionSpecification(
-              'progress',
-              'Progress indication mode',
-              ['-p', '--progress'],
-              ['compact', 'color', 'line', 'verbose',
-               'silent', 'status', 'buildbot', 'diff'],
-              'compact'),
-          new _TestOptionSpecification(
-              'failure-summary',
-              'Print failure summary at the end',
-              ['--failure-summary'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'step_name',
-              'Step name for use by -pbuildbot',
-              ['--step_name'],
-              [],
-              null),
-          new _TestOptionSpecification(
-              'report',
-              'Print a summary report of the number of tests, by expectation',
-              ['--report'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'tasks',
-              'The number of parallel tasks to run',
-              ['-j', '--tasks'],
-              [],
-              Platform.numberOfProcessors,
-              type: 'int'),
-          new _TestOptionSpecification(
-              'shards',
-              'The number of instances that the tests will be sharded over',
-              ['--shards'],
-              [],
-              1,
-              type: 'int'),
-          new _TestOptionSpecification(
-              'shard',
-              'The index of this instance when running in sharded mode',
-              ['--shard'],
-              [],
-              1,
-              type: 'int'),
-          new _TestOptionSpecification(
-              'help',
-              'Print list of options',
-              ['-h', '--help'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'verbose',
-              'Verbose output',
-              ['-v', '--verbose'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'list',
-              'List tests only, do not run them',
-              ['--list'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'report_in_json',
-              'When doing list, output result summary in json only.',
-              ['--report-in-json'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'time',
-              'Print timing information after running tests',
-              ['--time'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'dart',
-              'Path to dart executable',
-              ['--dart'],
-              [],
-              ''),
-          new _TestOptionSpecification(
-              'drt', // TODO(antonm): fix the option name.
-              'Path to content shell executable',
-              ['--drt'],
-              [],
-              ''),
-          new _TestOptionSpecification(
-              'dartium',
-              'Path to Dartium Chrome executable',
-              ['--dartium'],
-              [],
-              ''),
-          new _TestOptionSpecification(
-              'firefox',
-              'Path to firefox browser executable',
-              ['--firefox'],
-              [],
-              ''),
-          new _TestOptionSpecification(
-              'chrome',
-              'Path to chrome browser executable',
-              ['--chrome'],
-              [],
-              ''),
-          new _TestOptionSpecification(
-              'safari',
-              'Path to safari browser executable',
-              ['--safari'],
-              [],
-              ''),
-          new _TestOptionSpecification(
-              'use_sdk',
-              '''Use compiler or runtime from the SDK.
+          ['-r', '--runtime'],
+          [
+            'vm',
+            'dart_precompiled',
+            'dart_product',
+            'd8',
+            'jsshell',
+            'drt',
+            'dartium',
+            'ff',
+            'firefox',
+            'chrome',
+            'safari',
+            'ie9',
+            'ie10',
+            'ie11',
+            'opera',
+            'chromeOnAndroid',
+            'safarimobilesim',
+            'ContentShellOnAndroid',
+            'DartiumOnAndroid',
+            'none'
+          ],
+          'vm'),
+      new _TestOptionSpecification(
+          'arch',
+          'The architecture to run tests for',
+          ['-a', '--arch'],
+          [
+            'all',
+            'ia32',
+            'x64',
+            'arm',
+            'armv6',
+            'armv5te',
+            'arm64',
+            'mips',
+            'simarm',
+            'simarmv6',
+            'simarmv5te',
+            'simarm64',
+            'simmips'
+          ],
+          'x64'),
+      new _TestOptionSpecification(
+          'system',
+          'The operating system to run tests on',
+          ['-s', '--system'],
+          ['linux', 'macos', 'windows'],
+          Platform.operatingSystem),
+      new _TestOptionSpecification(
+          'checked', 'Run tests in checked mode', ['--checked'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification('host_checked',
+          'Run compiler in checked mode', ['--host-checked'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification('minified',
+          'Enable minification in the compiler', ['--minified'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'csp',
+          'Run tests under Content Security Policy restrictions',
+          ['--csp'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'cps_ir',
+          'Run the compiler with the cps based backend',
+          ['--cps-ir'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'noopt', 'Run an in-place precompilation', ['--noopt'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'timeout', 'Timeout in seconds', ['-t', '--timeout'], [], -1,
+          type: 'int'),
+      new _TestOptionSpecification(
+          'progress',
+          'Progress indication mode',
+          ['-p', '--progress'],
+          [
+            'compact',
+            'color',
+            'line',
+            'verbose',
+            'silent',
+            'status',
+            'buildbot',
+            'diff'
+          ],
+          'compact'),
+      new _TestOptionSpecification('failure-summary',
+          'Print failure summary at the end', ['--failure-summary'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification('step_name',
+          'Step name for use by -pbuildbot', ['--step_name'], [], null),
+      new _TestOptionSpecification(
+          'report',
+          'Print a summary report of the number of tests, by expectation',
+          ['--report'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'tasks',
+          'The number of parallel tasks to run',
+          ['-j', '--tasks'],
+          [],
+          Platform.numberOfProcessors,
+          type: 'int'),
+      new _TestOptionSpecification(
+          'shards',
+          'The number of instances that the tests will be sharded over',
+          ['--shards'],
+          [],
+          1,
+          type: 'int'),
+      new _TestOptionSpecification(
+          'shard',
+          'The index of this instance when running in sharded mode',
+          ['--shard'],
+          [],
+          1,
+          type: 'int'),
+      new _TestOptionSpecification(
+          'help', 'Print list of options', ['-h', '--help'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'verbose', 'Verbose output', ['-v', '--verbose'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'list', 'List tests only, do not run them', ['--list'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'report_in_json',
+          'When doing list, output result summary in json only.',
+          ['--report-in-json'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification('time',
+          'Print timing information after running tests', ['--time'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'dart', 'Path to dart executable', ['--dart'], [], ''),
+      new _TestOptionSpecification(
+          'drt', // TODO(antonm): fix the option name.
+          'Path to content shell executable',
+          ['--drt'],
+          [],
+          ''),
+      new _TestOptionSpecification('dartium',
+          'Path to Dartium Chrome executable', ['--dartium'], [], ''),
+      new _TestOptionSpecification('firefox',
+          'Path to firefox browser executable', ['--firefox'], [], ''),
+      new _TestOptionSpecification(
+          'chrome', 'Path to chrome browser executable', ['--chrome'], [], ''),
+      new _TestOptionSpecification(
+          'safari', 'Path to safari browser executable', ['--safari'], [], ''),
+      new _TestOptionSpecification(
+          'use_sdk',
+          '''Use compiler or runtime from the SDK.
 
 Normally, the compiler or runtimes in PRODUCT_DIR is tested, with this
 option, the compiler or runtime in PRODUCT_DIR/dart-sdk/bin is tested.
 
 Note: currently only implemented for dart2js.''',
-              ['--use-sdk'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'use_public_packages',
-              'For tests using packages: Use pub.dartlang.org packages '
-              'instead the ones in the repository.',
-              ['--use-public-packages'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'use_repository_packages',
-              'For tests using packages: Use pub.dartlang.org packages '
-              'but use overrides for the packages available in the '
-              'repository.',
-              ['--use-repository-packages'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'build_directory',
-              'The name of the build directory, where products are placed.',
-              ['--build-directory'],
-              [],
-              ''),
-          new _TestOptionSpecification(
-              'noBatch',
-              'Do not run tests in batch mode',
-              ['-n', '--nobatch'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'dart2js_batch',
-              'Run dart2js tests in batch mode',
-              ['--dart2js-batch'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'append_logs',
-              'Do not delete old logs but rather append to them.',
-              ['--append_logs'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'write_debug_log',
-              'Don\'t write debug messages to stdout but rather to a logfile.',
-              ['--write-debug-log'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'write_test_outcome_log',
-              'Write the outcome of all tests executed to a '
-              '"${TestUtils.flakyFileName()}" file.',
-              ['--write-test-outcome-log'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'clear_browser_cache',
-              'Browser specific clearing of caches(i.e., delete it).',
-              ['--clear_browser_cache'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'copy_coredumps',
-              'If we see a crash that we did not expect, copy the core dumps. '
-              'to /tmp',
-              ['--copy-coredumps'],
-              [],
-              false,
-              type: 'bool'),
-          new _TestOptionSpecification(
-              'local_ip',
-              'IP address the http servers should listen on.'
-              'This address is also used for browsers to connect.',
-              ['--local_ip'],
-              [],
-              '127.0.0.1'),
-          new _TestOptionSpecification(
-              'test_server_port',
-              'Port for test http server.',
-              ['--test_server_port'],
-              [],
-              0,
-              type: 'int'),
-          new _TestOptionSpecification(
-              'test_server_cross_origin_port',
-              'Port for test http server cross origin.',
-              ['--test_server_cross_origin_port'],
-              [],
-              0,
-              type: 'int'),
-          new _TestOptionSpecification(
-              'test_driver_port',
-              'Port for http test driver server.',
-              ['--test_driver_port'],
-              [],
-              0,
-              type: 'int'),
-          new _TestOptionSpecification(
-              'test_driver_error_port',
-              'Port for http test driver server errors.',
-              ['--test_driver_error_port'],
-              [],
-              0,
-              type: 'int'),
-          new _TestOptionSpecification(
-              'record_to_file',
-              'Records all the commands that need to be executed and writes it '
-              'out to a file.',
-              ['--record_to_file'],
-              [],
-              null),
-          new _TestOptionSpecification(
-              'replay_from_file',
-              'Records all the commands that need to be executed and writes it '
-              'out to a file.',
-              ['--replay_from_file'],
-              [],
-              null),
-          new _TestOptionSpecification(
-              'builder_tag',
-              'Machine specific options that is not captured by the regular '
-              'test options. Used to be able to make sane updates to the '
-              'status files.',
-              ['--builder-tag'],
-              [],
-              ''),
-          new _TestOptionSpecification(
-              'vm_options',
-              'Extra options to send to the vm when running',
-              ['--vm-options'],
-              [],
-              null),
-          new _TestOptionSpecification(
-              'dart2js_options',
-              'Extra options for dart2js compilation step',
-              ['--dart2js-options'],
-              [],
-              null),
-          new _TestOptionSpecification(
-              'suite_dir',
-              'Additional directory to add to the testing matrix',
-              ['--suite-dir'],
-              [],
-              null),
-          new _TestOptionSpecification(
-              'package_root',
-              'The package root to use for testing.',
-              ['--package-root'],
-              [],
-              null),
-          new _TestOptionSpecification(
-              'exclude_suite',
-              'Exclude suites from default selector, only works when no'
-              ' selector has been specified on the command line',
-              ['--exclude-suite'],
-              defaultTestSelectors,
-              null),];
+          ['--use-sdk'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'use_public_packages',
+          'For tests using packages: Use pub.dartlang.org packages '
+          'instead the ones in the repository.',
+          ['--use-public-packages'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'use_repository_packages',
+          'For tests using packages: Use pub.dartlang.org packages '
+          'but use overrides for the packages available in the '
+          'repository.',
+          ['--use-repository-packages'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'build_directory',
+          'The name of the build directory, where products are placed.',
+          ['--build-directory'],
+          [],
+          ''),
+      new _TestOptionSpecification('noBatch', 'Do not run tests in batch mode',
+          ['-n', '--nobatch'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification('dart2js_batch',
+          'Run dart2js tests in batch mode', ['--dart2js-batch'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'append_logs',
+          'Do not delete old logs but rather append to them.',
+          ['--append_logs'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'write_debug_log',
+          'Don\'t write debug messages to stdout but rather to a logfile.',
+          ['--write-debug-log'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'write_test_outcome_log',
+          'Write the outcome of all tests executed to a '
+          '"${TestUtils.flakyFileName()}" file.',
+          ['--write-test-outcome-log'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'clear_browser_cache',
+          'Browser specific clearing of caches(i.e., delete it).',
+          ['--clear_browser_cache'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'copy_coredumps',
+          'If we see a crash that we did not expect, copy the core dumps. '
+          'to /tmp',
+          ['--copy-coredumps'],
+          [],
+          false,
+          type: 'bool'),
+      new _TestOptionSpecification(
+          'local_ip',
+          'IP address the http servers should listen on.'
+          'This address is also used for browsers to connect.',
+          ['--local_ip'],
+          [],
+          '127.0.0.1'),
+      new _TestOptionSpecification('test_server_port',
+          'Port for test http server.', ['--test_server_port'], [], 0,
+          type: 'int'),
+      new _TestOptionSpecification(
+          'test_server_cross_origin_port',
+          'Port for test http server cross origin.',
+          ['--test_server_cross_origin_port'],
+          [],
+          0,
+          type: 'int'),
+      new _TestOptionSpecification('test_driver_port',
+          'Port for http test driver server.', ['--test_driver_port'], [], 0,
+          type: 'int'),
+      new _TestOptionSpecification(
+          'test_driver_error_port',
+          'Port for http test driver server errors.',
+          ['--test_driver_error_port'],
+          [],
+          0,
+          type: 'int'),
+      new _TestOptionSpecification(
+          'record_to_file',
+          'Records all the commands that need to be executed and writes it '
+          'out to a file.',
+          ['--record_to_file'],
+          [],
+          null),
+      new _TestOptionSpecification(
+          'replay_from_file',
+          'Records all the commands that need to be executed and writes it '
+          'out to a file.',
+          ['--replay_from_file'],
+          [],
+          null),
+      new _TestOptionSpecification(
+          'builder_tag',
+          'Machine specific options that is not captured by the regular '
+          'test options. Used to be able to make sane updates to the '
+          'status files.',
+          ['--builder-tag'],
+          [],
+          ''),
+      new _TestOptionSpecification(
+          'vm_options',
+          'Extra options to send to the vm when running',
+          ['--vm-options'],
+          [],
+          null),
+      new _TestOptionSpecification(
+          'dart2js_options',
+          'Extra options for dart2js compilation step',
+          ['--dart2js-options'],
+          [],
+          null),
+      new _TestOptionSpecification(
+          'suite_dir',
+          'Additional directory to add to the testing matrix',
+          ['--suite-dir'],
+          [],
+          null),
+      new _TestOptionSpecification('package_root',
+          'The package root to use for testing.', ['--package-root'], [], null),
+      new _TestOptionSpecification(
+          'exclude_suite',
+          'Exclude suites from default selector, only works when no'
+          ' selector has been specified on the command line',
+          ['--exclude-suite'],
+          defaultTestSelectors,
+          null),
+    ];
   }
 
-
   /**
    * Parse a list of strings as test options.
    *
@@ -541,7 +498,6 @@
         continue;
       }
 
-
       // Multiple uses of a flag are an error, because there is no
       // naturally correct way to handle conflicting options.
       if (configuration.containsKey(spec.name)) {
@@ -586,18 +542,33 @@
     List<Map> expandedConfigs = _expandConfigurations(configuration);
     List<Map> result = expandedConfigs.where(_isValidConfig).toList();
     for (var config in result) {
-     config['_reproducing_arguments_'] =
-         _constructReproducingCommandArguments(config);
+      config['_reproducing_arguments_'] =
+          _constructReproducingCommandArguments(config);
     }
     return result.isEmpty ? null : result;
   }
 
   // For printing out reproducing command lines, we don't want to add these
   // options.
-  Set<String>  _blacklistedOptions = new Set<String>.from([
-    'progress', 'failure-summary', 'step_name', 'report', 'tasks', 'verbose',
-    'time', 'dart', 'drt', 'dartium', 'firefox', 'chrome', 'safari',
-    'build_directory', 'append_logs', 'local_ip', 'shard', 'shards',
+  Set<String> _blacklistedOptions = new Set<String>.from([
+    'progress',
+    'failure-summary',
+    'step_name',
+    'report',
+    'tasks',
+    'verbose',
+    'time',
+    'dart',
+    'drt',
+    'dartium',
+    'firefox',
+    'chrome',
+    'safari',
+    'build_directory',
+    'append_logs',
+    'local_ip',
+    'shard',
+    'shards',
   ]);
 
   List<String> _constructReproducingCommandArguments(Map config) {
@@ -648,9 +619,22 @@
         // runs test.py -c dart2js -r drt,none the dart2js_none and
         // dart2js_drt will be duplicating work. If later we don't need 'none'
         // with dart2js, we should remove it from here.
-        validRuntimes = const ['d8', 'jsshell', 'drt', 'none', 'dartium',
-                               'ff', 'chrome', 'safari', 'ie9', 'ie10', 'ie11',
-                               'opera', 'chromeOnAndroid', 'safarimobilesim'];
+        validRuntimes = const [
+          'd8',
+          'jsshell',
+          'drt',
+          'none',
+          'dartium',
+          'ff',
+          'chrome',
+          'safari',
+          'ie9',
+          'ie10',
+          'ie11',
+          'opera',
+          'chromeOnAndroid',
+          'safarimobilesim'
+        ];
         break;
       case 'dart2analyzer':
         validRuntimes = const ['none'];
@@ -662,8 +646,13 @@
         validRuntimes = const ['dart_precompiled'];
         break;
       case 'none':
-        validRuntimes = const ['vm', 'drt', 'dartium',
-                               'ContentShellOnAndroid', 'DartiumOnAndroid'];
+        validRuntimes = const [
+          'vm',
+          'drt',
+          'dartium',
+          'ContentShellOnAndroid',
+          'DartiumOnAndroid'
+        ];
         break;
     }
     if (!validRuntimes.contains(config['runtime'])) {
@@ -680,13 +669,13 @@
     if (config['shard'] < 1 || config['shard'] > config['shards']) {
       isValid = false;
       print("Error: shard index is ${config['shard']} out of "
-            "${config['shards']} shards");
+          "${config['shards']} shards");
     }
 
     if (config['use_repository_packages'] && config['use_public_packages']) {
       isValid = false;
       print("Cannot have both --use-repository-packages and "
-            "--use-public-packages");
+          "--use-public-packages");
     }
 
     return isValid;
@@ -743,7 +732,7 @@
     // in that test suite. If no selectors are explicitly given use
     // the default suite patterns.
     var selectors = configuration['selectors'];
-    if (selectors is !Map) {
+    if (selectors is! Map) {
       if (selectors == null) {
         if (configuration['suite_dir'] != null) {
           var suite_path = new Path(configuration['suite_dir']);
@@ -752,8 +741,9 @@
           selectors = new List.from(defaultTestSelectors);
         }
 
-        var exclude_suites = configuration['exclude_suite'] != null ?
-              configuration['exclude_suite'].split(',') : [];
+        var exclude_suites = configuration['exclude_suite'] != null
+            ? configuration['exclude_suite'].split(',')
+            : [];
         for (var exclude in exclude_suites) {
           if (selectors.contains(exclude)) {
             selectors.remove(exclude);
@@ -777,7 +767,7 @@
         }
         if (selectorMap.containsKey(suite)) {
           print("Error: '$suite/$pattern'.  Only one test selection"
-                " pattern is allowed to start with '$suite/'");
+              " pattern is allowed to start with '$suite/'");
           exit(1);
         }
         selectorMap[suite] = new RegExp(pattern);
@@ -816,8 +806,8 @@
     if (configuration['timeout'] == -1) {
       int compilerMulitiplier =
           new CompilerConfiguration(configuration).computeTimeoutMultiplier();
-      int runtimeMultiplier =
-          new RuntimeConfiguration(configuration).computeTimeoutMultiplier(
+      int runtimeMultiplier = new RuntimeConfiguration(configuration)
+          .computeTimeoutMultiplier(
               mode: configuration['mode'],
               isChecked: configuration['checked'],
               arch: configuration['arch']);
@@ -847,7 +837,6 @@
     return result;
   }
 
-
   /**
    * Print out usage information.
    */
@@ -864,7 +853,8 @@
       print('${option.name}: ${option.description}.');
       for (var name in option.keys) {
         assert(name.startsWith('-'));
-        var buffer = new StringBuffer();;
+        var buffer = new StringBuffer();
+        ;
         buffer.write(name);
         if (option.type == 'bool') {
           assert(option.values.isEmpty);
@@ -891,7 +881,6 @@
     }
   }
 
-
   /**
    * Find the test option specification for a given option key.
    */
@@ -905,6 +894,5 @@
     exit(1);
   }
 
-
   List<_TestOptionSpecification> _options;
 }
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 0fbb767..3fdfbf3 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -61,19 +61,19 @@
   }
 }
 
-
 List<String> _buildFailureOutput(TestCase test,
-                                 [Formatter formatter = const Formatter()]) {
-
+    [Formatter formatter = const Formatter()]) {
   List<String> getLinesWithoutCarriageReturn(List<int> output) {
-    return decodeUtf8(output).replaceAll('\r\n', '\n')
-        .replaceAll('\r', '\n').split('\n');
+    return decodeUtf8(output)
+        .replaceAll('\r\n', '\n')
+        .replaceAll('\r', '\n')
+        .split('\n');
   }
 
   List<String> output = new List<String>();
   output.add('');
   output.add(formatter.failed('FAILED: ${test.configurationString}'
-                              ' ${test.displayName}'));
+      ' ${test.displayName}'));
   StringBuffer expected = new StringBuffer();
   expected.write('Expected: ');
   for (var expectation in test.expectedOutcomes) {
@@ -82,8 +82,8 @@
   output.add(expected.toString());
   output.add('Actual: ${test.result}');
   if (!test.lastCommandOutput.hasTimedOut) {
-    if (test.commandOutputs.length != test.commands.length
-        && !test.expectCompileError) {
+    if (test.commandOutputs.length != test.commands.length &&
+        !test.expectCompileError) {
       output.add('Unexpected compile-time error.');
     } else {
       if (test.expectCompileError) {
@@ -123,8 +123,7 @@
   }
   if (test is BrowserTestCase) {
     // Additional command for rerunning the steps locally after the fact.
-    var command =
-      test.configuration["_servers_"].httpServerCommandline();
+    var command = test.configuration["_servers_"].httpServerCommandline();
     output.add('');
     output.add('To retest, run:  $command');
   }
@@ -152,20 +151,19 @@
 }
 
 String _buildSummaryEnd(int failedTests) {
-    if (failedTests == 0) {
-      return '\n===\n=== All tests succeeded\n===\n';
-    } else {
-      var pluralSuffix = failedTests != 1 ? 's' : '';
-      return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n';
-    }
+  if (failedTests == 0) {
+    return '\n===\n=== All tests succeeded\n===\n';
+  } else {
+    var pluralSuffix = failedTests != 1 ? 's' : '';
+    return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n';
+  }
 }
 
-
 class EventListener {
-  void testAdded() { }
-  void done(TestCase test) { }
-  void allTestsKnown() { }
-  void allDone() { }
+  void testAdded() {}
+  void done(TestCase test) {}
+  void allTestsKnown() {}
+  void allDone() {}
 }
 
 class ExitCodeSetter extends EventListener {
@@ -226,10 +224,22 @@
    *  },
    */
 
-  static final INTERESTED_CONFIGURATION_PARAMETERS =
-      ['mode', 'arch', 'compiler', 'runtime', 'checked', 'host_checked',
-       'minified', 'csp', 'system', 'vm_options', 'use_sdk',
-       'use_repository_packages', 'use_public_packages', 'builder_tag'];
+  static final INTERESTED_CONFIGURATION_PARAMETERS = [
+    'mode',
+    'arch',
+    'compiler',
+    'runtime',
+    'checked',
+    'host_checked',
+    'minified',
+    'csp',
+    'system',
+    'vm_options',
+    'use_sdk',
+    'use_repository_packages',
+    'use_public_packages',
+    'builder_tag'
+  ];
 
   IOSink _sink;
 
@@ -248,22 +258,20 @@
     for (var command in test.commands) {
       var output = test.commandOutputs[command];
       if (output != null) {
-        double duration = output.time.inMicroseconds/1000.0;
+        double duration = output.time.inMicroseconds / 1000.0;
         totalDuration += duration;
-        commandResults.add({
-          'name': command.displayName,
-          'duration': duration,
-        });
+        commandResults
+            .add({'name': command.displayName, 'duration': duration,});
       }
     }
     _writeTestOutcomeRecord({
-      'name' : name,
-      'configuration' : configuration,
-      'test_result' : {
-        'outcome' : outcome,
-        'expected_outcomes' : expectations,
-        'duration' : totalDuration,
-        'command_results' : commandResults,
+      'name': name,
+      'configuration': configuration,
+      'test_result': {
+        'outcome': outcome,
+        'expected_outcomes': expectations,
+        'duration': totalDuration,
+        'command_results': commandResults,
       },
     });
   }
@@ -281,7 +289,6 @@
   }
 }
 
-
 class UnexpectedCrashDumpArchiver extends EventListener {
   void done(TestCase test) {
     if (test.unexpectedOutput && test.result == Expectation.CRASH) {
@@ -294,19 +301,20 @@
         var binBaseName = new Path(binName).filename;
         if (binFile.existsSync()) {
           var tmpPath = new Path(Directory.systemTemp.path);
-          var dir = new Path(TestUtils.mkdirRecursive(tmpPath,
-              new Path('coredump_${test.lastCommandOutput.pid}')).path);
+          var dir = new Path(TestUtils
+              .mkdirRecursive(
+                  tmpPath, new Path('coredump_${test.lastCommandOutput.pid}'))
+              .path);
           TestUtils.copyFile(new Path(name), dir.append(name));
           TestUtils.copyFile(new Path(binName), dir.append(binBaseName));
           print("\nCopied core dump and binary for unexpected crash to: "
-                "$dir");
+              "$dir");
         }
       }
     }
   }
 }
 
-
 class SummaryPrinter extends EventListener {
   final bool jsonOnly;
 
@@ -323,7 +331,6 @@
   }
 }
 
-
 class TimingPrinter extends EventListener {
   final _command2testCases = new Map<Command, List<TestCase>>();
   final _commandOutputs = new Set<CommandOutput>();
@@ -357,8 +364,8 @@
       }).join(', ');
 
       print('${commandOutput.time} - '
-            '${command.displayName} - '
-            '$testCasesDescription');
+          '${command.displayName} - '
+          '$testCasesDescription');
     }
   }
 }
@@ -377,7 +384,6 @@
     _printFailureSummary();
   }
 
-
   void _printFailureOutput(TestCase test) {
     String status = '${test.displayName}: ${test.result}';
     List<String> configs =
@@ -405,12 +411,11 @@
             runtimeToConfiguration.putIfAbsent(runtime, () => <String>[]);
         runtimeConfigs.add(config);
       }
-      runtimeToConfiguration.forEach((String runtime,
-                                      List<String> runtimeConfigs) {
+      runtimeToConfiguration
+          .forEach((String runtime, List<String> runtimeConfigs) {
         runtimeConfigs.sort((a, b) => a.compareTo(b));
-        List<String> statuses =
-            groupedStatuses.putIfAbsent('$runtime: $runtimeConfigs',
-                                        () => <String>[]);
+        List<String> statuses = groupedStatuses.putIfAbsent(
+            '$runtime: $runtimeConfigs', () => <String>[]);
         statuses.add(status);
       });
     });
@@ -432,15 +437,14 @@
 
   void done(TestCase test) {
     for (var commandOutput in test.commandOutputs.values) {
-      if (commandOutput.compilationSkipped)
-        _skippedCompilations++;
+      if (commandOutput.compilationSkipped) _skippedCompilations++;
     }
   }
 
   void allDone() {
     if (_skippedCompilations > 0) {
       print('\n$_skippedCompilations compilations were skipped because '
-            'the previous output was already up to date\n');
+          'the previous output was already up to date\n');
     }
   }
 }
@@ -460,24 +464,23 @@
 
   static Stream<Directory> getLeftOverTemporaryDirectories() {
     var regExp = _getTemporaryDirectoryRegexp();
-    return Directory.systemTemp.list().where(
-        (FileSystemEntity fse) {
-          if (fse is Directory) {
-            if (regExp.hasMatch(new Path(fse.path).filename)) {
-              return true;
-            }
-          }
-          return false;
-        });
+    return Directory.systemTemp.list().where((FileSystemEntity fse) {
+      if (fse is Directory) {
+        if (regExp.hasMatch(new Path(fse.path).filename)) {
+          return true;
+        }
+      }
+      return false;
+    });
   }
 
   void allDone() {
     getLeftOverTemporaryDirectories().length.then((int count) {
       if (count > MIN_NUMBER_OF_TEMP_DIRS) {
         DebugLogger.warning("There are ${count} directories "
-                            "in the system tempdir "
-                            "('${Directory.systemTemp.path}')! "
-                            "Maybe left over directories?\n");
+            "in the system tempdir "
+            "('${Directory.systemTemp.path}')! "
+            "Maybe left over directories?\n");
       }
     }).catchError((error) {
       DebugLogger.warning("Could not list temp directories, got: $error");
@@ -495,15 +498,13 @@
   }
 }
 
-
 class TestFailurePrinter extends EventListener {
   bool _printSummary;
   var _formatter;
   var _failureSummary = <String>[];
-  var _failedTests= 0;
+  var _failedTests = 0;
 
-  TestFailurePrinter(this._printSummary,
-                     [this._formatter = const Formatter()]);
+  TestFailurePrinter(this._printSummary, [this._formatter = const Formatter()]);
 
   void done(TestCase test) {
     if (test.unexpectedOutput) {
@@ -538,8 +539,9 @@
 class ProgressIndicator extends EventListener {
   ProgressIndicator(this._startTime);
 
-
-  void testAdded() { _foundTests++; }
+  void testAdded() {
+    _foundTests++;
+  }
 
   void done(TestCase test) {
     if (test.unexpectedOutput) {
@@ -566,8 +568,7 @@
 }
 
 abstract class CompactIndicator extends ProgressIndicator {
-  CompactIndicator(DateTime startTime)
-      : super(startTime);
+  CompactIndicator(DateTime startTime) : super(startTime);
 
   void allDone() {
     if (_failedTests > 0) {
@@ -582,7 +583,6 @@
   void _printProgress();
 }
 
-
 class CompactProgressIndicator extends CompactIndicator {
   Formatter _formatter;
 
@@ -595,18 +595,15 @@
     var passedPadded = _pad(_passedTests.toString(), 5);
     var failedPadded = _pad(_failedTests.toString(), 5);
     Duration d = (new DateTime.now()).difference(_startTime);
-    var progressLine =
-        '\r[${_timeString(d)} | $progressPadded% | '
+    var progressLine = '\r[${_timeString(d)} | $progressPadded% | '
         '+${_formatter.passed(passedPadded)} | '
         '-${_formatter.failed(failedPadded)}]';
     stdout.write(progressLine);
   }
 }
 
-
 class VerboseProgressIndicator extends ProgressIndicator {
-  VerboseProgressIndicator(DateTime startTime)
-      : super(startTime);
+  VerboseProgressIndicator(DateTime startTime) : super(startTime);
 
   void _printDoneProgress(TestCase test) {
     var status = 'pass';
@@ -617,7 +614,6 @@
   }
 }
 
-
 class BuildbotProgressIndicator extends ProgressIndicator {
   static String stepName;
   var _failureSummary = <String>[];
@@ -657,10 +653,8 @@
   }
 }
 
-
-EventListener progressIndicatorFromName(String name,
-                                        DateTime startTime,
-                                        Formatter formatter) {
+EventListener progressIndicatorFromName(
+    String name, DateTime startTime, Formatter formatter) {
   switch (name) {
     case 'compact':
       return new CompactProgressIndicator(startTime, formatter);
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 0fe9f18..0d64136 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -39,10 +39,14 @@
 
 // Some IO tests use these variables and get confused if the host environment
 // variables are inherited so they are excluded.
-const List<String> EXCLUDED_ENVIRONMENT_VARIABLES =
-    const ['http_proxy', 'https_proxy', 'no_proxy',
-           'HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY'];
-
+const List<String> EXCLUDED_ENVIRONMENT_VARIABLES = const [
+  'http_proxy',
+  'https_proxy',
+  'no_proxy',
+  'HTTP_PROXY',
+  'HTTPS_PROXY',
+  'NO_PROXY'
+];
 
 /** A command executed as a step in a test case. */
 class Command {
@@ -70,7 +74,8 @@
     return _cachedHashCode;
   }
 
-  operator ==(other) => identical(this, other) ||
+  operator ==(other) =>
+      identical(this, other) ||
       (runtimeType == other.runtimeType && _equal(other));
 
   void _buildHashCode(HashCodeBuilder builder) {
@@ -78,8 +83,7 @@
   }
 
   bool _equal(Command other) =>
-      hashCode == other.hashCode &&
-      displayName == other.displayName;
+      hashCode == other.hashCode && displayName == other.displayName;
 
   String toString() => reproductionCommand;
 
@@ -99,10 +103,8 @@
   /** Working directory for the command */
   final String workingDirectory;
 
-  ProcessCommand._(String displayName, this.executable,
-                   this.arguments,
-                   [this.environmentOverrides = null,
-                    this.workingDirectory = null])
+  ProcessCommand._(String displayName, this.executable, this.arguments,
+      [this.environmentOverrides = null, this.workingDirectory = null])
       : super._(displayName) {
     if (io.Platform.operatingSystem == 'windows') {
       // Windows can't handle the first command if it is a .bat file or the like
@@ -130,11 +132,12 @@
   String get reproductionCommand {
     var env = new StringBuffer();
     environmentOverrides.forEach((key, value) =>
-        (io.Platform.operatingSystem == 'windows') ?
-            env.write('set $key=${escapeCommandLineArgument(value)} & ') :
-            env.write('$key=${escapeCommandLineArgument(value)} '));
+        (io.Platform.operatingSystem == 'windows')
+            ? env.write('set $key=${escapeCommandLineArgument(value)} & ')
+            : env.write('$key=${escapeCommandLineArgument(value)} '));
     var command = ([executable]..addAll(arguments))
-        .map(escapeCommandLineArgument).join(' ');
+        .map(escapeCommandLineArgument)
+        .join(' ');
     if (workingDirectory != null) {
       command = "$command (working directory: $workingDirectory)";
     }
@@ -149,13 +152,14 @@
   final bool _neverSkipCompilation;
   final List<Uri> _bootstrapDependencies;
 
-  CompilationCommand._(String displayName,
-                       this._outputFile,
-                       this._neverSkipCompilation,
-                       this._bootstrapDependencies,
-                       String executable,
-                       List<String> arguments,
-                       Map<String, String> environmentOverrides)
+  CompilationCommand._(
+      String displayName,
+      this._outputFile,
+      this._neverSkipCompilation,
+      this._bootstrapDependencies,
+      String executable,
+      List<String> arguments,
+      Map<String, String> environmentOverrides)
       : super._(displayName, executable, arguments, environmentOverrides);
 
   Future<bool> get outputIsUpToDate {
@@ -181,8 +185,8 @@
     return readDepsFile("$_outputFile.deps").then((dependencies) {
       if (dependencies != null) {
         dependencies.addAll(_bootstrapDependencies);
-        var jsOutputLastModified = TestUtils.lastModifiedCache.getLastModified(
-            new Uri(scheme: 'file', path: _outputFile));
+        var jsOutputLastModified = TestUtils.lastModifiedCache
+            .getLastModified(new Uri(scheme: 'file', path: _outputFile));
         if (jsOutputLastModified != null) {
           for (var dependency in dependencies) {
             var dependencyLastModified =
@@ -220,37 +224,36 @@
   AddFlagsKey(this.flags, this.env);
   // Just use object identity for environment map
   bool operator ==(other) =>
-    other is AddFlagsKey && flags == other.flags && env == other.env;
+      other is AddFlagsKey && flags == other.flags && env == other.env;
   int get hashCode => flags.hashCode ^ env.hashCode;
 }
 
 class ContentShellCommand extends ProcessCommand {
-  ContentShellCommand._(String executable,
-                        String htmlFile,
-                        List<String> options,
-                        List<String> dartFlags,
-                        Map<String, String> environmentOverrides)
-      : super._("content_shell",
-               executable,
-               _getArguments(options, htmlFile),
-               _getEnvironment(environmentOverrides, dartFlags));
+  ContentShellCommand._(
+      String executable,
+      String htmlFile,
+      List<String> options,
+      List<String> dartFlags,
+      Map<String, String> environmentOverrides)
+      : super._("content_shell", executable, _getArguments(options, htmlFile),
+            _getEnvironment(environmentOverrides, dartFlags));
 
   // Cache the modified environments in a map from the old environment and
   // the string of Dart flags to the new environment.  Avoid creating new
   // environment object for each command object.
-  static Map<AddFlagsKey, Map> environments =
-      new Map<AddFlagsKey, Map>();
+  static Map<AddFlagsKey, Map> environments = new Map<AddFlagsKey, Map>();
 
   static Map _getEnvironment(Map env, List<String> dartFlags) {
     var needDartFlags = dartFlags != null && dartFlags.length > 0;
     if (needDartFlags) {
       if (env == null) {
-        env = const { };
+        env = const {};
       }
       var flags = dartFlags.join(' ');
-      return environments.putIfAbsent(new AddFlagsKey(flags, env),
+      return environments.putIfAbsent(
+          new AddFlagsKey(flags, env),
           () => new Map.from(env)
-              ..addAll({'DART_FLAGS': flags, 'DART_FORWARDING_PRINT': '1'}));
+            ..addAll({'DART_FLAGS': flags, 'DART_FORWARDING_PRINT': '1'}));
     }
     return env;
   }
@@ -270,11 +273,10 @@
   final Map configuration;
   final bool retry;
 
-  BrowserTestCommand._(String _browser,
-                       this.url,
-                       this.configuration,
-                       this.retry)
-      : super._(_browser), browser = _browser;
+  BrowserTestCommand._(
+      String _browser, this.url, this.configuration, this.retry)
+      : super._(_browser),
+        browser = _browser;
 
   void _buildHashCode(HashCodeBuilder builder) {
     super._buildHashCode(builder);
@@ -292,10 +294,12 @@
       retry == other.retry;
 
   String get reproductionCommand {
-    var parts = [io.Platform.resolvedExecutable,
-                'tools/testing/dart/launch_browser.dart',
-                browser,
-                url];
+    var parts = [
+      io.Platform.resolvedExecutable,
+      'tools/testing/dart/launch_browser.dart',
+      browser,
+      url
+    ];
     return parts.map(escapeCommandLineArgument).join(' ');
   }
 
@@ -304,11 +308,8 @@
 
 class BrowserHtmlTestCommand extends BrowserTestCommand {
   List<String> expectedMessages;
-  BrowserHtmlTestCommand._(String browser,
-                           String url,
-                           Map configuration,
-                           this.expectedMessages,
-                           bool retry)
+  BrowserHtmlTestCommand._(String browser, String url, Map configuration,
+      this.expectedMessages, bool retry)
       : super._(browser, url, configuration, retry);
 
   void _buildHashCode(HashCodeBuilder builder) {
@@ -324,11 +325,8 @@
 class AnalysisCommand extends ProcessCommand {
   final String flavor;
 
-  AnalysisCommand._(this.flavor,
-                    String displayName,
-                    String executable,
-                    List<String> arguments,
-                    Map<String, String> environmentOverrides)
+  AnalysisCommand._(this.flavor, String displayName, String executable,
+      List<String> arguments, Map<String, String> environmentOverrides)
       : super._(displayName, executable, arguments, environmentOverrides);
 
   void _buildHashCode(HashCodeBuilder builder) {
@@ -337,40 +335,34 @@
   }
 
   bool _equal(AnalysisCommand other) =>
-      super._equal(other) &&
-      flavor == other.flavor;
+      super._equal(other) && flavor == other.flavor;
 }
 
 class VmCommand extends ProcessCommand {
-  VmCommand._(String executable,
-              List<String> arguments,
-              Map<String,String> environmentOverrides)
+  VmCommand._(String executable, List<String> arguments,
+      Map<String, String> environmentOverrides)
       : super._("vm", executable, arguments, environmentOverrides);
 }
 
 class JSCommandlineCommand extends ProcessCommand {
-  JSCommandlineCommand._(String displayName,
-                         String executable,
-                         List<String> arguments,
-                         [Map<String, String> environmentOverrides = null])
-      : super._(displayName,
-                executable,
-                arguments,
-                environmentOverrides);
+  JSCommandlineCommand._(
+      String displayName, String executable, List<String> arguments,
+      [Map<String, String> environmentOverrides = null])
+      : super._(displayName, executable, arguments, environmentOverrides);
 }
 
 class PubCommand extends ProcessCommand {
   final String command;
 
-  PubCommand._(String pubCommand,
-               String pubExecutable,
-               String pubspecYamlDirectory,
-               String pubCacheDirectory)
-      : super._('pub_$pubCommand',
-                new io.File(pubExecutable).absolute.path,
-                [pubCommand],
-                {'PUB_CACHE' : pubCacheDirectory},
-                pubspecYamlDirectory), command = pubCommand;
+  PubCommand._(String pubCommand, String pubExecutable,
+      String pubspecYamlDirectory, String pubCacheDirectory)
+      : super._(
+            'pub_$pubCommand',
+            new io.File(pubExecutable).absolute.path,
+            [pubCommand],
+            {'PUB_CACHE': pubCacheDirectory},
+            pubspecYamlDirectory),
+        command = pubCommand;
 
   void _buildHashCode(HashCodeBuilder builder) {
     super._buildHashCode(builder);
@@ -378,8 +370,7 @@
   }
 
   bool _equal(PubCommand other) =>
-      super._equal(other) &&
-      command == other.command;
+      super._equal(other) && command == other.command;
 }
 
 /* [ScriptCommand]s are executed by dart code. */
@@ -394,7 +385,7 @@
   final String _destinationDirectory;
 
   CleanDirectoryCopyCommand._(this._sourceDirectory, this._destinationDirectory)
-    : super._('dir_copy');
+      : super._('dir_copy');
 
   String get reproductionCommand =>
       "Copying '$_sourceDirectory' to '$_destinationDirectory'.";
@@ -440,10 +431,9 @@
   String _destinationFile;
   Map<String, Map> _dependencyOverrides;
 
-  ModifyPubspecYamlCommand._(this._pubspecYamlFile,
-                             this._destinationFile,
-                             this._dependencyOverrides)
-    : super._("modify_pubspec") {
+  ModifyPubspecYamlCommand._(
+      this._pubspecYamlFile, this._destinationFile, this._dependencyOverrides)
+      : super._("modify_pubspec") {
     assert(_pubspecYamlFile.endsWith("pubspec.yaml"));
     assert(_destinationFile.endsWith("pubspec.yaml"));
   }
@@ -455,9 +445,9 @@
   Future<ScriptCommandOutputImpl> run() {
     var watch = new Stopwatch()..start();
 
-    var pubspecLockFile =
-        _destinationFile.substring(0, _destinationFile.length - ".yaml".length)
-        + ".lock";
+    var pubspecLockFile = _destinationFile.substring(
+            0, _destinationFile.length - ".yaml".length) +
+        ".lock";
 
     var file = new io.File(_pubspecYamlFile);
     var destinationFile = new io.File(_destinationFile);
@@ -465,15 +455,14 @@
     return file.readAsString().then((String yamlString) {
       var dependencyOverrideSection = new StringBuffer();
       if (_dependencyOverrides.isNotEmpty) {
-        dependencyOverrideSection.write(
-            "\n"
+        dependencyOverrideSection.write("\n"
             "# This section was autogenerated by test.py!\n"
             "dependency_overrides:\n");
         _dependencyOverrides.forEach((String packageName, Map override) {
           dependencyOverrideSection.write("  $packageName:\n");
           override.forEach((overrideKey, overrideValue) {
-            dependencyOverrideSection.write(
-                "    $overrideKey: $overrideValue\n");
+            dependencyOverrideSection
+                .write("    $overrideKey: $overrideValue\n");
           });
         });
       }
@@ -529,9 +518,9 @@
       }
       var link = new io.Link(_link);
 
-      return link.exists()
-          .then((bool exists) { if (exists) return link.delete(); })
-          .then((_) => link.create(_target));
+      return link.exists().then((bool exists) {
+        if (exists) return link.delete();
+      }).then((_) => link.create(_target));
     }).then((_) {
       return new ScriptCommandOutputImpl(
           this, Expectation.PASS, "", watch.elapsed);
@@ -548,9 +537,7 @@
   }
 
   bool _equal(MakeSymlinkCommand other) =>
-      super._equal(other) &&
-      _link == other._link &&
-      _target == other._target;
+      super._equal(other) && _link == other._link && _target == other._target;
 }
 
 class CommandBuilder {
@@ -566,45 +553,46 @@
     _cleared = true;
   }
 
-  ContentShellCommand getContentShellCommand(String executable,
-                                             String htmlFile,
-                                             List<String> options,
-                                             List<String> dartFlags,
-                                             Map<String, String> environment) {
+  ContentShellCommand getContentShellCommand(
+      String executable,
+      String htmlFile,
+      List<String> options,
+      List<String> dartFlags,
+      Map<String, String> environment) {
     ContentShellCommand command = new ContentShellCommand._(
         executable, htmlFile, options, dartFlags, environment);
     return _getUniqueCommand(command);
   }
 
-  BrowserTestCommand getBrowserTestCommand(String browser,
-                                           String url,
-                                           Map configuration,
-                                           bool retry) {
+  BrowserTestCommand getBrowserTestCommand(
+      String browser, String url, Map configuration, bool retry) {
     var command = new BrowserTestCommand._(browser, url, configuration, retry);
     return _getUniqueCommand(command);
   }
 
-  BrowserHtmlTestCommand getBrowserHtmlTestCommand(String browser,
-                                               String url,
-                                               Map configuration,
-                                               List<String> expectedMessages,
-                                               bool retry) {
+  BrowserHtmlTestCommand getBrowserHtmlTestCommand(String browser, String url,
+      Map configuration, List<String> expectedMessages, bool retry) {
     var command = new BrowserHtmlTestCommand._(
         browser, url, configuration, expectedMessages, retry);
     return _getUniqueCommand(command);
   }
 
-  CompilationCommand getCompilationCommand(String displayName,
-                                           outputFile,
-                                           neverSkipCompilation,
-                                           List<Uri> bootstrapDependencies,
-                                           String executable,
-                                           List<String> arguments,
-                                           Map<String, String> environment) {
-    var command =
-        new CompilationCommand._(
-            displayName, outputFile, neverSkipCompilation,
-            bootstrapDependencies, executable, arguments, environment);
+  CompilationCommand getCompilationCommand(
+      String displayName,
+      outputFile,
+      neverSkipCompilation,
+      List<Uri> bootstrapDependencies,
+      String executable,
+      List<String> arguments,
+      Map<String, String> environment) {
+    var command = new CompilationCommand._(
+        displayName,
+        outputFile,
+        neverSkipCompilation,
+        bootstrapDependencies,
+        executable,
+        arguments,
+        environment);
     return _getUniqueCommand(command);
   }
 
@@ -616,41 +604,36 @@
     return _getUniqueCommand(command);
   }
 
-  VmCommand getVmCommand(String executable,
-                         List<String> arguments,
-                         Map<String, String> environmentOverrides) {
+  VmCommand getVmCommand(String executable, List<String> arguments,
+      Map<String, String> environmentOverrides) {
     var command = new VmCommand._(executable, arguments, environmentOverrides);
     return _getUniqueCommand(command);
   }
 
   Command getJSCommandlineCommand(String displayName, executable, arguments,
-                                  [environment = null]) {
-    var command = new JSCommandlineCommand._(displayName, executable, arguments,
-                                             environment);
+      [environment = null]) {
+    var command = new JSCommandlineCommand._(
+        displayName, executable, arguments, environment);
     return _getUniqueCommand(command);
   }
 
   Command getProcessCommand(String displayName, executable, arguments,
-                     [environment = null, workingDirectory = null]) {
-    var command = new ProcessCommand._(displayName, executable, arguments,
-                                       environment, workingDirectory);
+      [environment = null, workingDirectory = null]) {
+    var command = new ProcessCommand._(
+        displayName, executable, arguments, environment, workingDirectory);
     return _getUniqueCommand(command);
   }
 
   Command getCopyCommand(String sourceDirectory, String destinationDirectory) {
-    var command = new CleanDirectoryCopyCommand._(sourceDirectory,
-                                                  destinationDirectory);
+    var command =
+        new CleanDirectoryCopyCommand._(sourceDirectory, destinationDirectory);
     return _getUniqueCommand(command);
   }
 
-  Command getPubCommand(String pubCommand,
-                        String pubExecutable,
-                        String pubspecYamlDirectory,
-                        String pubCacheDirectory) {
-    var command = new PubCommand._(pubCommand,
-                                   pubExecutable,
-                                   pubspecYamlDirectory,
-                                   pubCacheDirectory);
+  Command getPubCommand(String pubCommand, String pubExecutable,
+      String pubspecYamlDirectory, String pubCacheDirectory) {
+    var command = new PubCommand._(
+        pubCommand, pubExecutable, pubspecYamlDirectory, pubCacheDirectory);
     return _getUniqueCommand(command);
   }
 
@@ -659,7 +642,7 @@
   }
 
   Command getModifyPubspecCommand(String pubspecYamlFile, Map depsOverrides,
-                                  {String destinationFile: null}) {
+      {String destinationFile: null}) {
     if (destinationFile == null) destinationFile = pubspecYamlFile;
     return _getUniqueCommand(new ModifyPubspecYamlCommand._(
         pubspecYamlFile, destinationFile, depsOverrides));
@@ -716,7 +699,8 @@
    * compiling multiple sources that are run in isolation.
    */
   List<Command> commands;
-  Map<Command, CommandOutput> commandOutputs = new Map<Command,CommandOutput>();
+  Map<Command, CommandOutput> commandOutputs =
+      new Map<Command, CommandOutput>();
 
   Map configuration;
   String displayName;
@@ -724,19 +708,16 @@
   int hash = 0;
   Set<Expectation> expectedOutcomes;
 
-  TestCase(this.displayName,
-           this.commands,
-           this.configuration,
-           this.expectedOutcomes,
-           {isNegative: false,
-            TestInformation info: null}) {
+  TestCase(this.displayName, this.commands, this.configuration,
+      this.expectedOutcomes,
+      {isNegative: false, TestInformation info: null}) {
     if (isNegative || displayName.contains("negative_test")) {
       _expectations |= IS_NEGATIVE;
     }
     if (info != null) {
       _setExpectations(info);
-      hash = info.originTestPath.relativeTo(TestUtils.dartDir)
-          .toString().hashCode;
+      hash =
+          info.originTestPath.relativeTo(TestUtils.dartDir).toString().hashCode;
     }
   }
 
@@ -777,8 +758,8 @@
   CommandOutput get lastCommandOutput {
     if (commandOutputs.length == 0) {
       throw new Exception("CommandOutputs is empty, maybe no command was run? ("
-                          "displayName: '$displayName', "
-                          "configurationString: '$configurationString')");
+          "displayName: '$displayName', "
+          "configurationString: '$configurationString')");
     }
     return commandOutputs[commands[commandOutputs.length - 1]];
   }
@@ -786,8 +767,8 @@
   Command get lastCommandExecuted {
     if (commandOutputs.length == 0) {
       throw new Exception("CommandOutputs is empty, maybe no command was run? ("
-                          "displayName: '$displayName', "
-                          "configurationString: '$configurationString')");
+          "displayName: '$displayName', "
+          "configurationString: '$configurationString')");
     }
     return commands[commandOutputs.length - 1];
   }
@@ -815,34 +796,34 @@
   }
 
   bool get isFlaky {
-      if (expectedOutcomes.contains(Expectation.SKIP) ||
-          expectedOutcomes.contains(Expectation.SKIP_BY_DESIGN)) {
-        return false;
-      }
+    if (expectedOutcomes.contains(Expectation.SKIP) ||
+        expectedOutcomes.contains(Expectation.SKIP_BY_DESIGN)) {
+      return false;
+    }
 
-      return expectedOutcomes
-        .where((expectation) => !expectation.isMetaExpectation).length > 1;
+    return expectedOutcomes
+            .where((expectation) => !expectation.isMetaExpectation)
+            .length >
+        1;
   }
 
   bool get isFinished {
     return commandOutputs.length > 0 &&
         (!lastCommandOutput.successful ||
-         commands.length == commandOutputs.length);
+            commands.length == commandOutputs.length);
   }
 }
 
-
 /**
  * BrowserTestCase has an extra compilation command that is run in a separate
  * process, before the regular test is run as in the base class [TestCase].
  * If the compilation command fails, then the rest of the test is not run.
  */
 class BrowserTestCase extends TestCase {
-
-  BrowserTestCase(displayName, commands, configuration,
-                  expectedOutcomes, info, isNegative, this._testingUrl)
-    : super(displayName, commands, configuration,
-            expectedOutcomes, isNegative: isNegative, info: info);
+  BrowserTestCase(displayName, commands, configuration, expectedOutcomes, info,
+      isNegative, this._testingUrl)
+      : super(displayName, commands, configuration, expectedOutcomes,
+            isNegative: isNegative, info: info);
 
   String _testingUrl;
 
@@ -858,14 +839,13 @@
     return testOutput.contains("unittest-suite-success");
   }
 
-  Expectation _negateOutcomeIfIncompleteAsyncTest(Expectation outcome,
-                                                  String testOutput) {
+  Expectation _negateOutcomeIfIncompleteAsyncTest(
+      Expectation outcome, String testOutput) {
     // If this is an asynchronous test and the asynchronous operation didn't
     // complete successfully, it's outcome is Expectation.FAIL.
     // TODO: maybe we should introduce a AsyncIncomplete marker or so
     if (outcome == Expectation.PASS) {
-      if (_isAsyncTest(testOutput) &&
-          !_isAsyncTestSuccessful(testOutput)) {
+      if (_isAsyncTest(testOutput) && !_isAsyncTestSuccessful(testOutput)) {
         return Expectation.FAIL;
       }
     }
@@ -930,14 +910,15 @@
   bool alreadyPrintedWarning = false;
 
   // TODO(kustermann): Remove testCase from this class.
-  CommandOutputImpl(Command this.command,
-                    int this.exitCode,
-                    bool this.timedOut,
-                    List<int> this.stdout,
-                    List<int> this.stderr,
-                    Duration this.time,
-                    bool this.compilationSkipped,
-                    int this.pid) {
+  CommandOutputImpl(
+      Command this.command,
+      int this.exitCode,
+      bool this.timedOut,
+      List<int> this.stdout,
+      List<int> this.stderr,
+      Duration this.time,
+      bool this.compilationSkipped,
+      int this.pid) {
     diagnostics = [];
   }
 
@@ -991,8 +972,8 @@
     return testCase.isNegative ? !didFail(testCase) : didFail(testCase);
   }
 
-  Expectation _negateOutcomeIfNegativeTest(Expectation outcome,
-                                           bool isNegative) {
+  Expectation _negateOutcomeIfNegativeTest(
+      Expectation outcome, bool isNegative) {
     if (!isNegative) return outcome;
 
     if (outcome.canBeOutcomeOf(Expectation.FAIL)) {
@@ -1012,21 +993,9 @@
   bool _failedBecauseOfMissingXDisplay;
 
   BrowserCommandOutputImpl(
-      command,
-      exitCode,
-      timedOut,
-      stdout,
-      stderr,
-      time,
-      compilationSkipped) :
-    super(command,
-          exitCode,
-          timedOut,
-          stdout,
-          stderr,
-          time,
-          compilationSkipped,
-          0) {
+      command, exitCode, timedOut, stdout, stderr, time, compilationSkipped)
+      : super(command, exitCode, timedOut, stdout, stderr, time,
+            compilationSkipped, 0) {
     _failedBecauseOfMissingXDisplay = _didFailBecauseOfMissingXDisplay();
     if (_failedBecauseOfMissingXDisplay) {
       DebugLogger.warning("Warning: Test failure because of missing XDisplay");
@@ -1128,7 +1097,7 @@
       }
       if (!containsFail && !containsPass) {
         DebugLogger.warning("Test had neither 'FAIL' nor 'PASS' in stdout. "
-                            "($command)");
+            "($command)");
         return true;
       }
       if (containsFail) {
@@ -1137,43 +1106,31 @@
       assert(containsPass);
       if (exitCode != 0) {
         var message = "All tests passed, but exitCode != 0. "
-                      "Actual exitcode: $exitCode. "
-                      "($command)";
+            "Actual exitcode: $exitCode. "
+            "($command)";
         DebugLogger.warning(message);
         diagnostics.add(message);
       }
       return (!hasCrashed &&
-              exitCode != 0 &&
-              (!isWindows || exitCode != WHITELISTED_CONTENTSHELL_EXITCODE));
+          exitCode != 0 &&
+          (!isWindows || exitCode != WHITELISTED_CONTENTSHELL_EXITCODE));
     }
     DebugLogger.warning("Couldn't find 'Content-Type: text/plain' in output. "
-                        "($command).");
+        "($command).");
     return true;
   }
 }
 
 class HTMLBrowserCommandOutputImpl extends BrowserCommandOutputImpl {
- HTMLBrowserCommandOutputImpl(
-      command,
-      exitCode,
-      timedOut,
-      stdout,
-      stderr,
-      time,
-      compilationSkipped) :
-    super(command,
-          exitCode,
-          timedOut,
-          stdout,
-          stderr,
-          time,
-          compilationSkipped);
+  HTMLBrowserCommandOutputImpl(
+      command, exitCode, timedOut, stdout, stderr, time, compilationSkipped)
+      : super(command, exitCode, timedOut, stdout, stderr, time,
+            compilationSkipped);
 
   bool didFail(TestCase testCase) {
     return _getOutcome() != Expectation.PASS;
   }
 
-
   bool get _browserTestFailure {
     // We should not need to convert back and forward.
     var output = decodeUtf8(super.stdout);
@@ -1183,10 +1140,16 @@
 }
 
 class BrowserTestJsonResult {
-  static const ALLOWED_TYPES =
-      const ['sync_exception', 'window_onerror', 'script_onerror',
-             'window_compilationerror', 'print', 'message_received', 'dom',
-             'debug'];
+  static const ALLOWED_TYPES = const [
+    'sync_exception',
+    'window_onerror',
+    'script_onerror',
+    'window_compilationerror',
+    'print',
+    'message_received',
+    'dom',
+    'debug'
+  ];
 
   final Expectation outcome;
   final String htmlDom;
@@ -1198,7 +1161,7 @@
     void validate(String assertion, bool value) {
       if (!value) {
         throw "InvalidFormat sent from browser driving page: $assertion:\n\n"
-               "$content";
+            "$content";
       }
     }
 
@@ -1218,12 +1181,11 @@
           var value = entry['value'];
           var timestamp = entry['timestamp'];
 
-          validate("'type' of an entry must be a String",
-                   type is String);
+          validate("'type' of an entry must be a String", type is String);
           validate("'type' has to be in $ALLOWED_TYPES.",
-                   ALLOWED_TYPES.contains(type));
-          validate("'timestamp' of an entry must be a number",
-                   timestamp is num);
+              ALLOWED_TYPES.contains(type));
+          validate(
+              "'timestamp' of an entry must be a number", timestamp is num);
 
           messagesByType[type].add(value);
         }
@@ -1238,7 +1200,7 @@
         return new BrowserTestJsonResult(
             _getOutcome(messagesByType), dom, events);
       }
-    } catch(error) {
+    } catch (error) {
       // If something goes wrong, we know the content was not in the correct
       // JSON format. So we can't parse it.
       // The caller is responsible for falling back to the old way of
@@ -1275,11 +1237,11 @@
     // the unittest implementation posts these messages using
     // "window.postMessage()" instead of the normal "print()" them.
 
-    var isAsyncTest = searchForMsg(['print', 'message_received'],
-                                   'unittest-suite-wait-for-done');
+    var isAsyncTest = searchForMsg(
+        ['print', 'message_received'], 'unittest-suite-wait-for-done');
     var isAsyncSuccess =
         searchForMsg(['print', 'message_received'], 'unittest-suite-success') ||
-        searchForMsg(['print', 'message_received'], 'unittest-suite-done');
+            searchForMsg(['print', 'message_received'], 'unittest-suite-done');
 
     if (isAsyncTest) {
       if (isAsyncSuccess) {
@@ -1301,22 +1263,23 @@
 }
 
 class BrowserControllerTestOutcome extends CommandOutputImpl
-                                   with UnittestSuiteMessagesMixin {
+    with UnittestSuiteMessagesMixin {
   BrowserTestOutput _result;
   Expectation _rawOutcome;
 
-  factory BrowserControllerTestOutcome(Command command,
-                                       BrowserTestOutput result) {
+  factory BrowserControllerTestOutcome(
+      Command command, BrowserTestOutput result) {
     void validate(String assertion, bool value) {
       if (!value) {
         throw "InvalidFormat sent from browser driving page: $assertion:\n\n"
-              "${result.lastKnownMessage}";
+            "${result.lastKnownMessage}";
       }
     }
 
     String indent(String string, int numSpaces) {
       var spaces = new List.filled(numSpaces, ' ').join('');
-      return string.replaceAll('\r\n', '\n')
+      return string
+          .replaceAll('\r\n', '\n')
           .split('\n')
           .map((line) => "$spaces$line")
           .join('\n');
@@ -1344,13 +1307,13 @@
     if (result.didTimeout) {
       if (result.delayUntilTestStarted != null) {
         stderr = "This test timed out. The delay until the test actually "
-                 "started was: ${result.delayUntilTestStarted}.";
+            "started was: ${result.delayUntilTestStarted}.";
       } else {
         // TODO(ricow/kustermann) as soon as we record the state periodically,
         // we will have more information and can remove this warning.
         stderr = "This test has not notified test.py that it started running. "
-                 "This could be a bug in test.py! "
-                 "Please contact ricow/whesse";
+            "This could be a bug in test.py! "
+            "Please contact ricow/whesse";
       }
     }
 
@@ -1360,8 +1323,7 @@
       stdout = "message:\n${indent(result.lastKnownMessage, 2)}\n\n";
     }
 
-    stderr =
-        '$stderr\n\n'
+    stderr = '$stderr\n\n'
         'BrowserOutput while running the test (* EXPERIMENTAL *):\n'
         'BrowserOutput.stdout:\n'
         '${indent(result.browserOutput.stdout.toString(), 2)}\n'
@@ -1369,20 +1331,23 @@
         '${indent(result.browserOutput.stderr.toString(), 2)}\n'
         '\n';
     return new BrowserControllerTestOutcome._internal(
-      command, result, outcome, encodeUtf8(stdout), encodeUtf8(stderr));
+        command, result, outcome, encodeUtf8(stdout), encodeUtf8(stderr));
   }
 
   BrowserControllerTestOutcome._internal(
-      Command command, BrowserTestOutput result, this._rawOutcome,
-      List<int> stdout, List<int> stderr)
+      Command command,
+      BrowserTestOutput result,
+      this._rawOutcome,
+      List<int> stdout,
+      List<int> stderr)
       : super(command, 0, result.didTimeout, stdout, stderr, result.duration,
-              false, 0) {
+            false, 0) {
     _result = result;
   }
 
   Expectation result(TestCase testCase) {
     // Handle timeouts first
-    if (_result.didTimeout)  return Expectation.TIMEOUT;
+    if (_result.didTimeout) return Expectation.TIMEOUT;
 
     // Multitests are handled specially
     if (testCase.hasRuntimeError) {
@@ -1394,7 +1359,6 @@
   }
 }
 
-
 class AnalysisCommandOutputImpl extends CommandOutputImpl {
   // An error line has 8 fields that look like:
   // ERROR|COMPILER|MISSING_SOURCE|file:/tmp/t.dart|15|1|24|Missing source.
@@ -1403,21 +1367,10 @@
   final int FILENAME = 3;
   final int FORMATTED_ERROR = 7;
 
-  AnalysisCommandOutputImpl(command,
-                            exitCode,
-                            timedOut,
-                            stdout,
-                            stderr,
-                            time,
-                            compilationSkipped) :
-    super(command,
-          exitCode,
-          timedOut,
-          stdout,
-          stderr,
-          time,
-          compilationSkipped,
-          0);
+  AnalysisCommandOutputImpl(
+      command, exitCode, timedOut, stdout, stderr, time, compilationSkipped)
+      : super(command, exitCode, timedOut, stdout, stderr, time,
+            compilationSkipped, 0);
 
   Expectation result(TestCase testCase) {
     // TODO(kustermann): If we run the analyzer not in batch mode, make sure
@@ -1455,9 +1408,8 @@
       return Expectation.STATIC_WARNING;
     }
 
-    assert (errors.length == 0 && warnings.length == 0);
-    assert (!testCase.hasCompileError &&
-            !testCase.hasStaticWarning);
+    assert(errors.length == 0 && warnings.length == 0);
+    assert(!testCase.hasCompileError && !testCase.hasStaticWarning);
     return Expectation.PASS;
   }
 
@@ -1468,7 +1420,7 @@
       StringBuffer field = new StringBuffer();
       List<String> result = [];
       bool escaped = false;
-      for (var i = 0 ; i < line.length; i++) {
+      for (var i = 0; i < line.length; i++) {
         var c = line[i];
         if (!escaped && c == '\\') {
           escaped = true;
@@ -1503,13 +1455,12 @@
 }
 
 class VmCommandOutputImpl extends CommandOutputImpl
-                          with UnittestSuiteMessagesMixin {
+    with UnittestSuiteMessagesMixin {
   static const DART_VM_EXITCODE_COMPILE_TIME_ERROR = 254;
   static const DART_VM_EXITCODE_UNCAUGHT_EXCEPTION = 255;
 
   VmCommandOutputImpl(Command command, int exitCode, bool timedOut,
-                      List<int> stdout, List<int> stderr, Duration time,
-                      int pid)
+      List<int> stdout, List<int> stderr, Duration time, int pid)
       : super(command, exitCode, timedOut, stdout, stderr, time, false, pid);
 
   Expectation result(TestCase testCase) {
@@ -1553,11 +1504,16 @@
 class CompilationCommandOutputImpl extends CommandOutputImpl {
   static const DART2JS_EXITCODE_CRASH = 253;
 
-  CompilationCommandOutputImpl(Command command, int exitCode, bool timedOut,
-      List<int> stdout, List<int> stderr, Duration time,
+  CompilationCommandOutputImpl(
+      Command command,
+      int exitCode,
+      bool timedOut,
+      List<int> stdout,
+      List<int> stderr,
+      Duration time,
       bool compilationSkipped)
       : super(command, exitCode, timedOut, stdout, stderr, time,
-              compilationSkipped, 0);
+            compilationSkipped, 0);
 
   Expectation result(TestCase testCase) {
     // Handle general crash/timeout detection.
@@ -1596,7 +1552,7 @@
 }
 
 class JsCommandlineOutputImpl extends CommandOutputImpl
-                              with UnittestSuiteMessagesMixin {
+    with UnittestSuiteMessagesMixin {
   JsCommandlineOutputImpl(Command command, int exitCode, bool timedOut,
       List<int> stdout, List<int> stderr, Duration time)
       : super(command, exitCode, timedOut, stdout, stderr, time, false, 0);
@@ -1620,7 +1576,7 @@
 class PubCommandOutputImpl extends CommandOutputImpl {
   PubCommandOutputImpl(PubCommand command, int exitCode, bool timedOut,
       List<int> stdout, List<int> stderr, Duration time)
-  : super(command, exitCode, timedOut, stdout, stderr, time, false, 0);
+      : super(command, exitCode, timedOut, stdout, stderr, time, false, 0);
 
   Expectation result(TestCase testCase) {
     // Handle crashes and timeouts first
@@ -1641,8 +1597,8 @@
   final Expectation _result;
 
   ScriptCommandOutputImpl(ScriptCommand command, this._result,
-                          String scriptExecutionInformation, Duration time)
-  : super(command, 0, false, [], [], time, false, 0) {
+      String scriptExecutionInformation, Duration time)
+      : super(command, 0, false, [], [], time, false, 0) {
     var lines = scriptExecutionInformation.split("\n");
     diagnostics.addAll(lines);
   }
@@ -1652,29 +1608,20 @@
   bool get canRunDependendCommands => _result == Expectation.PASS;
 
   bool get successful => _result == Expectation.PASS;
-
 }
 
-CommandOutput createCommandOutput(Command command,
-                                  int exitCode,
-                                  bool timedOut,
-                                  List<int> stdout,
-                                  List<int> stderr,
-                                  Duration time,
-                                  bool compilationSkipped,
-                                  [int pid = 0]) {
+CommandOutput createCommandOutput(Command command, int exitCode, bool timedOut,
+    List<int> stdout, List<int> stderr, Duration time, bool compilationSkipped,
+    [int pid = 0]) {
   if (command is ContentShellCommand) {
     return new BrowserCommandOutputImpl(
-        command, exitCode, timedOut, stdout, stderr,
-        time, compilationSkipped);
+        command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
   } else if (command is BrowserTestCommand) {
     return new HTMLBrowserCommandOutputImpl(
-        command, exitCode, timedOut, stdout, stderr,
-        time, compilationSkipped);
+        command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
   } else if (command is AnalysisCommand) {
     return new AnalysisCommandOutputImpl(
-        command, exitCode, timedOut, stdout, stderr,
-        time, compilationSkipped);
+        command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
   } else if (command is VmCommand) {
     return new VmCommandOutputImpl(
         command, exitCode, timedOut, stdout, stderr, time, pid);
@@ -1694,12 +1641,10 @@
         command, exitCode, timedOut, stdout, stderr, time);
   }
 
-  return new CommandOutputImpl(
-      command, exitCode, timedOut, stdout, stderr,
+  return new CommandOutputImpl(command, exitCode, timedOut, stdout, stderr,
       time, compilationSkipped, pid);
 }
 
-
 /**
  * An OutputLog records the output from a test, but truncates it if
  * it is longer than MAX_HEAD characters, and just keeps the head and
@@ -1734,10 +1679,9 @@
     }
   }
 
-  List<int> _truncatedTail() =>
-    tail.length > TAIL_LENGTH ?
-        tail.sublist(tail.length - TAIL_LENGTH) :
-        tail;
+  List<int> _truncatedTail() => tail.length > TAIL_LENGTH
+      ? tail.sublist(tail.length - TAIL_LENGTH)
+      : tail;
 
   List<int> toList() {
     if (complete == null) {
@@ -1751,7 +1695,8 @@
 
 *****************************************************************************
 
-""".codeUnits);
+"""
+            .codeUnits);
         complete.addAll(_truncatedTail());
       } else if (tail != null) {
         complete.addAll(tail);
@@ -1801,11 +1746,10 @@
         _commandComplete(0);
       } else {
         var processEnvironment = _createProcessEnvironment();
-        Future processFuture =
-            io.Process.start(command.executable,
-                             command.arguments,
-                             environment: processEnvironment,
-                             workingDirectory: command.workingDirectory);
+        Future processFuture = io.Process.start(
+            command.executable, command.arguments,
+            environment: processEnvironment,
+            workingDirectory: command.workingDirectory);
         processFuture.then((io.Process process) {
           StreamSubscription stdoutSubscription =
               _drainStream(process.stdout, stdout);
@@ -1871,14 +1815,14 @@
               });
             }
 
-            Future.wait([stdoutCompleter.future,
-                         stderrCompleter.future]).then((_) {
+            Future.wait([stdoutCompleter.future, stderrCompleter.future]).then(
+                (_) {
               _commandComplete(exitCode);
             });
           });
 
-          timeoutTimer = new Timer(new Duration(seconds: timeout),
-                                   timeoutHandler);
+          timeoutTimer =
+              new Timer(new Duration(seconds: timeout), timeoutHandler);
         }).catchError((e) {
           // TODO(floitsch): should we try to report the stacktrace?
           print("Process error:");
@@ -1912,8 +1856,8 @@
     return commandOutput;
   }
 
-  StreamSubscription _drainStream(Stream<List<int>> source,
-                                  OutputLog destination) {
+  StreamSubscription _drainStream(
+      Stream<List<int>> source, OutputLog destination) {
     return source.listen(destination.add);
   }
 
@@ -1957,7 +1901,7 @@
   BatchRunnerProcess();
 
   Future<CommandOutput> runCommand(String runnerType, ProcessCommand command,
-                                   int timeout, List<String> arguments) {
+      int timeout, List<String> arguments) {
     assert(_completer == null);
     assert(!_currentlyRunning);
 
@@ -2011,15 +1955,14 @@
     _status = null;
     _stdoutCompleter = new Completer();
     _stderrCompleter = new Completer();
-    _timer = new Timer(new Duration(seconds: timeout),
-                       _timeoutHandler);
+    _timer = new Timer(new Duration(seconds: timeout), _timeoutHandler);
 
     var line = _createArgumentsLine(_arguments, timeout);
     _process.stdin.write(line);
     _stdoutSubscription.resume();
     _stderrSubscription.resume();
-    Future.wait([_stdoutCompleter.future,
-                 _stderrCompleter.future]).then((_) => _reportResult());
+    Future.wait([_stdoutCompleter.future, _stderrCompleter.future]).then(
+        (_) => _reportResult());
   }
 
   String _createArgumentsLine(List<String> arguments, int timeout) {
@@ -2034,13 +1977,14 @@
     var exitCode = 0;
     if (outcome == "CRASH") exitCode = CRASHING_BROWSER_EXITCODE;
     if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1;
-    var output = createCommandOutput(_command,
-                        exitCode,
-                        (outcome == "TIMEOUT"),
-                        _testStdout.toList(),
-                        _testStderr.toList(),
-                        new DateTime.now().difference(_startTime),
-                        false);
+    var output = createCommandOutput(
+        _command,
+        exitCode,
+        (outcome == "TIMEOUT"),
+        _testStdout.toList(),
+        _testStderr.toList(),
+        new DateTime.now().difference(_startTime),
+        false);
     assert(_completer != null);
     _completer.complete(output);
     _completer = null;
@@ -2055,7 +1999,8 @@
         _stdoutSubscription.cancel();
         _stderrSubscription.cancel();
         _startProcess(_reportResult);
-      } else {  // No active test case running.
+      } else {
+        // No active test case running.
         _process = null;
       }
     }
@@ -2077,16 +2022,13 @@
         environment[key] = _processEnvironmentOverrides[key];
       }
     }
-    Future processFuture = io.Process.start(executable,
-                                            arguments,
-                                            environment: environment);
+    Future processFuture =
+        io.Process.start(executable, arguments, environment: environment);
     processFuture.then((io.Process p) {
       _process = p;
 
       var _stdoutStream =
-          _process.stdout
-              .transform(UTF8.decoder)
-              .transform(new LineSplitter());
+          _process.stdout.transform(UTF8.decoder).transform(new LineSplitter());
       _stdoutSubscription = _stdoutStream.listen((String line) {
         if (line.startsWith('>>> TEST')) {
           _status = line;
@@ -2107,9 +2049,7 @@
       _stdoutSubscription.pause();
 
       var _stderrStream =
-          _process.stderr
-              .transform(UTF8.decoder)
-              .transform(new LineSplitter());
+          _process.stderr.transform(UTF8.decoder).transform(new LineSplitter());
       _stderrSubscription = _stderrStream.listen((String line) {
         if (line.startsWith('>>> EOF STDERR')) {
           _stderrSubscription.pause();
@@ -2156,7 +2096,6 @@
   }
 }
 
-
 /**
  * [TestCaseEnqueuer] takes a list of TestSuites, generates TestCases and
  * builds a dependency graph of all commands in every TestSuite.
@@ -2223,7 +2162,6 @@
   }
 }
 
-
 /*
  * [CommandEnqueuer] will
  *  - change node.state to NodeState.Enqueuing as soon as all dependencies have
@@ -2232,11 +2170,15 @@
  *    have a state of NodeState.Failed/NodeState.UnableToRun.
  */
 class CommandEnqueuer {
-  static final INIT_STATES = [dgraph.NodeState.Initialized,
-                              dgraph.NodeState.Waiting];
-  static final FINISHED_STATES = [dgraph.NodeState.Successful,
-                                  dgraph.NodeState.Failed,
-                                  dgraph.NodeState.UnableToRun];
+  static final INIT_STATES = [
+    dgraph.NodeState.Initialized,
+    dgraph.NodeState.Waiting
+  ];
+  static final FINISHED_STATES = [
+    dgraph.NodeState.Successful,
+    dgraph.NodeState.Failed,
+    dgraph.NodeState.UnableToRun
+  ];
   final dgraph.Graph _graph;
 
   CommandEnqueuer(this._graph) {
@@ -2248,9 +2190,9 @@
     });
 
     eventCondition((e) => e is dgraph.StateChangedEvent).listen((event) {
-      if ([dgraph.NodeState.Waiting,
-           dgraph.NodeState.Processing].contains(event.from)) {
-        if (FINISHED_STATES.contains(event.to)){
+      if ([dgraph.NodeState.Waiting, dgraph.NodeState.Processing]
+          .contains(event.from)) {
+        if (FINISHED_STATES.contains(event.to)) {
           for (var dependendNode in event.node.neededFor) {
             _changeNodeStateIfNecessary(dependendNode);
           }
@@ -2263,16 +2205,17 @@
   // changed it's state.
   void _changeNodeStateIfNecessary(dgraph.Node node) {
     if (INIT_STATES.contains(node.state)) {
-      bool anyDependenciesUnsuccessful = node.dependencies.any(
-          (dep) => [dgraph.NodeState.Failed,
-                    dgraph.NodeState.UnableToRun].contains(dep.state));
+      bool anyDependenciesUnsuccessful = node.dependencies.any((dep) => [
+            dgraph.NodeState.Failed,
+            dgraph.NodeState.UnableToRun
+          ].contains(dep.state));
 
       var newState = dgraph.NodeState.Waiting;
       if (anyDependenciesUnsuccessful) {
         newState = dgraph.NodeState.UnableToRun;
       } else {
-        bool allDependenciesSuccessful = node.dependencies.every(
-            (dep) => dep.state == dgraph.NodeState.Successful);
+        bool allDependenciesSuccessful = node.dependencies
+            .every((dep) => dep.state == dgraph.NodeState.Successful);
 
         if (allDependenciesSuccessful) {
           newState = dgraph.NodeState.Enqueuing;
@@ -2304,8 +2247,8 @@
   final TestCaseEnqueuer enqueuer;
 
   final Queue<Command> _runQueue = new Queue<Command>();
-  final _commandOutputStream =  new StreamController<CommandOutput>(sync: true);
-  final _completer =  new Completer();
+  final _commandOutputStream = new StreamController<CommandOutput>(sync: true);
+  final _completer = new Completer();
 
   int _numProcesses = 0;
   int _maxProcesses;
@@ -2314,23 +2257,23 @@
   bool _finishing = false;
   bool _verbose = false;
 
-  CommandQueue(this.graph, this.enqueuer, this.executor,
-               this._maxProcesses, this._maxBrowserProcesses, this._verbose) {
+  CommandQueue(this.graph, this.enqueuer, this.executor, this._maxProcesses,
+      this._maxBrowserProcesses, this._verbose) {
     var eventCondition = graph.events.where;
     eventCondition((event) => event is dgraph.StateChangedEvent)
         .listen((event) {
-          if (event.to == dgraph.NodeState.Enqueuing) {
-            assert(event.from == dgraph.NodeState.Initialized ||
-                   event.from == dgraph.NodeState.Waiting);
-            graph.changeState(event.node, dgraph.NodeState.Processing);
-            var command = event.node.userData;
-            if (event.node.dependencies.length > 0) {
-              _runQueue.addFirst(command);
-            } else {
-              _runQueue.add(command);
-            }
-            Timer.run(() => _tryRunNextCommand());
-          }
+      if (event.to == dgraph.NodeState.Enqueuing) {
+        assert(event.from == dgraph.NodeState.Initialized ||
+            event.from == dgraph.NodeState.Waiting);
+        graph.changeState(event.node, dgraph.NodeState.Processing);
+        var command = event.node.userData;
+        if (event.node.dependencies.length > 0) {
+          _runQueue.addFirst(command);
+        } else {
+          _runQueue.add(command);
+        }
+        Timer.run(() => _tryRunNextCommand());
+      }
     });
     // We're finished if the graph is sealed and all nodes are in a finished
     // state (Successful, Failed or UnableToRun).
@@ -2374,8 +2317,8 @@
       // If a command is part of many TestCases we set the timeout to be
       // the maximum over all [TestCase.timeout]s. At some point, we might
       // eliminate [TestCase.timeout] completely and move it to [Command].
-      int timeout = testCases.map((TestCase test) => test.timeout)
-          .fold(0, math.max);
+      int timeout =
+          testCases.map((TestCase test) => test.timeout).fold(0, math.max);
 
       if (_verbose) {
         print('Running "${command.displayName}" command: $command');
@@ -2422,7 +2365,7 @@
     print("CommandQueue state:");
     print("  Processes: used: $_numProcesses max: $_maxProcesses");
     print("  BrowserProcesses: used: $_numBrowserProcesses "
-          "max: $_maxBrowserProcesses");
+        "max: $_maxBrowserProcesses");
     print("  Finishing: $_finishing");
     print("  Queue (length = ${_runQueue.length}):");
     for (var command in _runQueue) {
@@ -2431,7 +2374,6 @@
   }
 }
 
-
 /*
  * [CommandExecutor] is responsible for executing commands. It will make sure
  * that the the following two constraints are satisfied
@@ -2494,7 +2436,7 @@
       return _runCommand(command, timeout).then((CommandOutput output) {
         if (retriesLeft > 0 && shouldRetryCommand(output)) {
           DebugLogger.warning("Rerunning Command: ($retriesLeft "
-                              "attempt(s) remains) [cmd: $command]");
+              "attempt(s) remains) [cmd: $command]");
           return runCommand(retriesLeft - 1);
         } else {
           return new Future.value(output);
@@ -2545,8 +2487,8 @@
     var completer = new Completer<CommandOutput>();
 
     var callback = (BrowserTestOutput output) {
-      completer.complete(
-          new BrowserControllerTestOutcome(browserCommand, output));
+      completer
+          .complete(new BrowserControllerTestOutcome(browserCommand, output));
     };
 
     BrowserTest browserTest;
@@ -2558,40 +2500,32 @@
     }
     _getBrowserTestRunner(browserCommand.browser, browserCommand.configuration)
         .then((testRunner) {
-      testRunner.queueTest(browserTest);
+      testRunner.enqueueTest(browserTest);
     });
 
     return completer.future;
   }
 
-  Future<BrowserTestRunner> _getBrowserTestRunner(String browser,
-                                                  Map configuration) {
+  Future<BrowserTestRunner> _getBrowserTestRunner(
+      String browser, Map configuration) async {
     var localIp = globalConfiguration['local_ip'];
-    var num_browsers = maxBrowserProcesses;
     if (_browserTestRunners[configuration] == null) {
       var testRunner = new BrowserTestRunner(
-            configuration, localIp, browser, num_browsers);
+          configuration, localIp, browser, maxBrowserProcesses);
       if (globalConfiguration['verbose']) {
         testRunner.logger = DebugLogger.info;
       }
       _browserTestRunners[configuration] = testRunner;
-      return testRunner.start().then((started) {
-        if (started) {
-          return testRunner;
-        }
-        print("Issue starting browser test runner");
-        io.exit(1);
-      });
+      await testRunner.start();
     }
-    return new Future.value(_browserTestRunners[configuration]);
+    return _browserTestRunners[configuration];
   }
 }
 
 class RecordingCommandExecutor implements CommandExecutor {
   TestCaseRecorder _recorder;
 
-  RecordingCommandExecutor(Path path)
-      : _recorder = new TestCaseRecorder(path);
+  RecordingCommandExecutor(Path path) : _recorder = new TestCaseRecorder(path);
 
   Future<CommandOutput> runCommand(node, ProcessCommand command, int timeout) {
     assert(node.dependencies.length == 0);
@@ -2613,8 +2547,7 @@
     if (environment == null) return true;
     return environment.length == 0 ||
         (environment.length == 1 &&
-         environment.containsKey("DART_CONFIGURATION"));
-
+            environment.containsKey("DART_CONFIGURATION"));
   }
 }
 
@@ -2650,7 +2583,7 @@
       // "xvfb-run" issue 7564, try re-running the test.
       bool containsFailureMsg(String line) {
         return line.contains(MESSAGE_CANNOT_OPEN_DISPLAY) ||
-               line.contains(MESSAGE_FAILED_TO_RUN_COMMAND);
+            line.contains(MESSAGE_FAILED_TO_RUN_COMMAND);
       }
       if (stdout.any(containsFailureMsg) || stderr.any(containsFailureMsg)) {
         return true;
@@ -2678,8 +2611,10 @@
  * closed.
  */
 class TestCaseCompleter {
-  static final COMPLETED_STATES = [dgraph.NodeState.Failed,
-                                   dgraph.NodeState.Successful];
+  static final COMPLETED_STATES = [
+    dgraph.NodeState.Failed,
+    dgraph.NodeState.Successful
+  ];
   final dgraph.Graph graph;
   final TestCaseEnqueuer enqueuer;
   final CommandQueue commandQueue;
@@ -2707,26 +2642,26 @@
     // changes.
     eventCondition((event) => event is dgraph.StateChangedEvent)
         .listen((dgraph.StateChangedEvent event) {
-          if (event.from == dgraph.NodeState.Processing &&
-              !finishedRemainingTestCases ) {
-            var command = event.node.userData;
+      if (event.from == dgraph.NodeState.Processing &&
+          !finishedRemainingTestCases) {
+        var command = event.node.userData;
 
-            assert(COMPLETED_STATES.contains(event.to));
-            assert(_outputs[command] != null);
+        assert(COMPLETED_STATES.contains(event.to));
+        assert(_outputs[command] != null);
 
-            _completeTestCasesIfPossible(enqueuer.command2testCases[command]);
-            _checkDone();
-          }
+        _completeTestCasesIfPossible(enqueuer.command2testCases[command]);
+        _checkDone();
+      }
     });
 
     // Listen also for GraphSealedEvent's. If there is not a single node in the
     // graph, we still want to finish after the graph was sealed.
     eventCondition((event) => event is dgraph.GraphSealedEvent)
         .listen((dgraph.GraphSealedEvent event) {
-          if (!_closed && enqueuer.remainingTestCases.isEmpty) {
-            _controller.close();
-            _closed = true;
-          }
+      if (!_closed && enqueuer.remainingTestCases.isEmpty) {
+        _controller.close();
+        _closed = true;
+      }
     });
   }
 
@@ -2770,7 +2705,6 @@
   }
 }
 
-
 class ProcessQueue {
   Map _globalConfiguration;
 
@@ -2778,32 +2712,28 @@
   final dgraph.Graph _graph = new dgraph.Graph();
   List<EventListener> _eventListener;
 
-  ProcessQueue(this._globalConfiguration,
-               maxProcesses,
-               maxBrowserProcesses,
-               DateTime startTime,
-               testSuites,
-               this._eventListener,
-               this._allDone,
-               [bool verbose = false,
-                String recordingOutputFile,
-                String recordedInputFile]) {
+  ProcessQueue(this._globalConfiguration, maxProcesses, maxBrowserProcesses,
+      DateTime startTime, testSuites, this._eventListener, this._allDone,
+      [bool verbose = false,
+      String recordingOutputFile,
+      String recordedInputFile]) {
     void setupForListing(TestCaseEnqueuer testCaseEnqueuer) {
-      _graph.events.where((event) => event is dgraph.GraphSealedEvent)
-        .listen((dgraph.GraphSealedEvent event) {
-          var testCases = new List.from(testCaseEnqueuer.remainingTestCases);
-          testCases.sort((a, b) => a.displayName.compareTo(b.displayName));
+      _graph.events
+          .where((event) => event is dgraph.GraphSealedEvent)
+          .listen((dgraph.GraphSealedEvent event) {
+        var testCases = new List.from(testCaseEnqueuer.remainingTestCases);
+        testCases.sort((a, b) => a.displayName.compareTo(b.displayName));
 
-          print("\nGenerating all matching test cases ....\n");
+        print("\nGenerating all matching test cases ....\n");
 
-          for (TestCase testCase in testCases) {
-            eventFinishedTestCase(testCase);
-            print("${testCase.displayName}   "
-                  "Expectations: ${testCase.expectedOutcomes.join(', ')}   "
-                  "Configuration: '${testCase.configurationString}'");
-          }
-          eventAllTestsKnown();
-        });
+        for (TestCase testCase in testCases) {
+          eventFinishedTestCase(testCase);
+          print("${testCase.displayName}   "
+              "Expectations: ${testCase.expectedOutcomes.join(', ')}   "
+              "Configuration: '${testCase.configurationString}'");
+        }
+        eventAllTestsKnown();
+      });
     }
 
     var testCaseEnqueuer;
@@ -2825,17 +2755,18 @@
         cancelDebugTimer();
         _debugTimer = new Timer(debugTimerDuration, () {
           print("The debug timer of test.dart expired. Please report this issue"
-                " to ricow/whesse and provide the following information:");
+              " to ricow/whesse and provide the following information:");
           print("");
           print("Graph is sealed: ${_graph.isSealed}");
           print("");
           _graph.DumpCounts();
           print("");
           var unfinishedNodeStates = [
-              dgraph.NodeState.Initialized,
-              dgraph.NodeState.Waiting,
-              dgraph.NodeState.Enqueuing,
-              dgraph.NodeState.Processing];
+            dgraph.NodeState.Initialized,
+            dgraph.NodeState.Waiting,
+            dgraph.NodeState.Enqueuing,
+            dgraph.NodeState.Processing
+          ];
 
           for (var nodeState in unfinishedNodeStates) {
             if (_graph.stateCount(nodeState) > 0) {
@@ -2849,7 +2780,7 @@
                   print("  Command: $command");
                   for (var testCase in testCases) {
                     print("    Enqueued by: ${testCase.configurationString} "
-                          "-- ${testCase.displayName}");
+                        "-- ${testCase.displayName}");
                   }
                   print("");
                 }
@@ -2870,9 +2801,10 @@
 
       // When the graph building is finished, notify event listeners.
       _graph.events
-        .where((event) => event is dgraph.GraphSealedEvent).listen((event) {
-          eventAllTestsKnown();
-        });
+          .where((event) => event is dgraph.GraphSealedEvent)
+          .listen((event) {
+        eventAllTestsKnown();
+      });
 
       // Queue commands as they become "runnable"
       var commandEnqueuer = new CommandEnqueuer(_graph);
@@ -2890,30 +2822,27 @@
 
       // Run "runnable commands" using [executor] subject to
       // maxProcesses/maxBrowserProcesses constraint
-      commandQueue = new CommandQueue(
-          _graph, testCaseEnqueuer, executor, maxProcesses, maxBrowserProcesses,
-          verbose);
+      commandQueue = new CommandQueue(_graph, testCaseEnqueuer, executor,
+          maxProcesses, maxBrowserProcesses, verbose);
 
       // Finish test cases when all commands were run (or some failed)
       var testCaseCompleter =
           new TestCaseCompleter(_graph, testCaseEnqueuer, commandQueue);
-      testCaseCompleter.finishedTestCases.listen(
-          (TestCase finishedTestCase) {
-            resetDebugTimer();
+      testCaseCompleter.finishedTestCases.listen((TestCase finishedTestCase) {
+        resetDebugTimer();
 
-            // If we're recording, we don't report any TestCases to listeners.
-            if (!recording) {
-              eventFinishedTestCase(finishedTestCase);
-            }
-          },
-          onDone: () {
-            // Wait until the commandQueue/execturo is done (it may need to stop
-            // batch runners, browser controllers, ....)
-            commandQueue.done.then((_) {
-              cancelDebugTimer();
-              eventAllTestsDone();
-            });
-          });
+        // If we're recording, we don't report any TestCases to listeners.
+        if (!recording) {
+          eventFinishedTestCase(finishedTestCase);
+        }
+      }, onDone: () {
+        // Wait until the commandQueue/execturo is done (it may need to stop
+        // batch runners, browser controllers, ....)
+        commandQueue.done.then((_) {
+          cancelDebugTimer();
+          eventAllTestsDone();
+        });
+      });
 
       resetDebugTimer();
     }
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index fd06d20..d288da8 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -27,21 +27,18 @@
 import "utils.dart";
 import "http_server.dart" show PREFIX_BUILDDIR, PREFIX_DARTDIR;
 
-import "compiler_configuration.dart" show
-    CommandArtifact,
-    CompilerConfiguration;
+import "compiler_configuration.dart"
+    show CommandArtifact, CompilerConfiguration;
 
-import "runtime_configuration.dart" show
-    RuntimeConfiguration;
+import "runtime_configuration.dart" show RuntimeConfiguration;
 
 import 'browser_test.dart';
 
-
 RegExp multiHtmlTestGroupRegExp = new RegExp(r"\s*[^/]\s*group\('[^,']*");
 RegExp multiHtmlTestRegExp = new RegExp(r"useHtmlIndividualConfiguration()");
 // Require at least one non-space character before '///'
 RegExp multiTestRegExp = new RegExp(r"\S *"
-                                    r"/// \w+:(.*)");
+    r"/// \w+:(.*)");
 RegExp dartExtension = new RegExp(r'\.dart$');
 
 /**
@@ -49,14 +46,12 @@
  */
 typedef bool Predicate<T>(T arg);
 
-typedef void CreateTest(Path filePath,
-                        Path originTestPath,
-                        bool hasCompileError,
-                        bool hasRuntimeError,
-                        {bool isNegativeIfChecked,
-                         bool hasCompileErrorIfChecked,
-                         bool hasStaticWarning,
-                         String multitestKey});
+typedef void CreateTest(Path filePath, Path originTestPath,
+    bool hasCompileError, bool hasRuntimeError,
+    {bool isNegativeIfChecked,
+    bool hasCompileErrorIfChecked,
+    bool hasStaticWarning,
+    String multitestKey});
 
 typedef void VoidFunction();
 
@@ -74,7 +69,6 @@
   return completer.future;
 }
 
-
 /** A completer that waits until all added [Future]s complete. */
 // TODO(rnystrom): Copied from web_components. Remove from here when it gets
 // added to dart:core. (See #6626.)
@@ -116,7 +110,6 @@
   Future<List> get future => _completer.future;
 }
 
-
 /**
  * A TestSuite represents a collection of tests.  It creates a [TestCase]
  * object for each test to be run, and passes the test cases to a callback.
@@ -132,10 +125,10 @@
   Map<String, String> _environmentOverrides;
 
   TestSuite(this.configuration, this.suiteName) {
-    TestUtils.buildDir(configuration);  // Sets configuration_directory.
+    TestUtils.buildDir(configuration); // Sets configuration_directory.
     if (configuration['configuration_directory'] != null) {
       _environmentOverrides = {
-        'DART_CONFIGURATION' : configuration['configuration_directory']
+        'DART_CONFIGURATION': configuration['configuration_directory']
       };
     }
   }
@@ -359,13 +352,14 @@
         .append(testUniqueName);
 
     TestUtils.mkdirRecursive(new Path('.'), generatedTestPath);
-    return new File(generatedTestPath.toNativePath()).absolute.path
+    return new File(generatedTestPath.toNativePath())
+        .absolute
+        .path
         .replaceAll('\\', '/');
   }
 
-  String buildTestCaseDisplayName(Path suiteDir,
-                                  Path originTestPath,
-                                  {String multitestName: ""}) {
+  String buildTestCaseDisplayName(Path suiteDir, Path originTestPath,
+      {String multitestName: ""}) {
     Path testNamePath = originTestPath.relativeTo(suiteDir);
     var directory = testNamePath.directoryPath;
     var filenameWithoutExt = testNamePath.filenameWithoutExtension;
@@ -391,10 +385,10 @@
     var checked = configuration['checked'] ? '-checked' : '';
     var minified = configuration['minified'] ? '-minified' : '';
     var sdk = configuration['use_sdk'] ? '-sdk' : '';
-    var packages = configuration['use_public_packages']
-        ? '-public_packages' : '';
+    var packages =
+        configuration['use_public_packages'] ? '-public_packages' : '';
     var dirName = "${configuration['compiler']}-${configuration['runtime']}"
-                  "$checked$minified$packages$sdk";
+        "$checked$minified$packages$sdk";
     return createGeneratedTestDirectoryHelper(
         "tests", dirName, testPath, optionsName);
   }
@@ -404,10 +398,10 @@
     var minified = configuration['minified'] ? '-minified' : '';
     var csp = configuration['csp'] ? '-csp' : '';
     var sdk = configuration['use_sdk'] ? '-sdk' : '';
-    var packages = configuration['use_public_packages']
-        ? '-public_packages' : '';
+    var packages =
+        configuration['use_public_packages'] ? '-public_packages' : '';
     var dirName = "${configuration['compiler']}"
-                  "$checked$minified$csp$packages$sdk";
+        "$checked$minified$csp$packages$sdk";
     return createGeneratedTestDirectoryHelper(
         "compilations", dirName, testPath, "");
   }
@@ -415,14 +409,16 @@
   String createPubspecCheckoutDirectory(Path directoryOfPubspecYaml) {
     var sdk = configuration['use_sdk'] ? '-sdk' : '';
     var pkg = configuration['use_public_packages']
-        ? 'public_packages' : 'repo_packages';
+        ? 'public_packages'
+        : 'repo_packages';
     return createGeneratedTestDirectoryHelper(
         "pubspec_checkouts", '$pkg$sdk', directoryOfPubspecYaml, "");
   }
 
   String createPubPackageBuildsDirectory(Path directoryOfPubspecYaml) {
     var pkg = configuration['use_public_packages']
-        ? 'public_packages' : 'repo_packages';
+        ? 'public_packages'
+        : 'repo_packages';
     return createGeneratedTestDirectoryHelper(
         "pub_package_builds", pkg, directoryOfPubspecYaml, "");
   }
@@ -434,19 +430,20 @@
     var dir = new Directory(path.toNativePath());
     return dir.exists().then((var exist) {
       if (!exist) return [];
-      return dir.list(recursive: false)
-      .where((fse) => fse is Directory)
-      .map((Directory directory) {
-        var fullPath = directory.absolute.path;
-        var packageName = new Path(fullPath).filename;
-        if (isValid(packageName)) {
-          return [packageName, path.append(packageName).toNativePath()];
-        }
-        return null;
-      })
-      .where((name) => name != null)
-      .toList();
-      });
+      return dir
+          .list(recursive: false)
+          .where((fse) => fse is Directory)
+          .map((Directory directory) {
+            var fullPath = directory.absolute.path;
+            var packageName = new Path(fullPath).filename;
+            if (isValid(packageName)) {
+              return [packageName, path.append(packageName).toNativePath()];
+            }
+            return null;
+          })
+          .where((name) => name != null)
+          .toList();
+    });
   }
 
   Future<Map> discoverPackagesInRepository() {
@@ -522,28 +519,25 @@
   Map buildPubspecDependencyOverrides(Map packageDirectories) {
     Map overrides = {};
     packageDirectories.forEach((String packageName, String fullPath) {
-      overrides[packageName] = { 'path' : fullPath };
+      overrides[packageName] = {'path': fullPath};
     });
     return overrides;
   }
-
 }
 
-
 Future<Iterable<String>> ccTestLister(String runnerPath) {
   return Process.run(runnerPath, ["--list"]).then((ProcessResult result) {
     if (result.exitCode != 0) {
       throw "Failed to list tests: '$runnerPath --list'. "
-            "Process exited with ${result.exitCode}";
+          "Process exited with ${result.exitCode}";
     }
     return result.stdout
-      .split('\n')
-      .map((line) => line.trim())
-      .where((name) => name.length > 0);
+        .split('\n')
+        .map((line) => line.trim())
+        .where((name) => name.length > 0);
   });
 }
 
-
 /**
  * A specialized [TestSuite] that runs tests written in C to unit test
  * the Dart virtual machine and its API.
@@ -559,11 +553,9 @@
   final String dartDir;
   List<String> statusFilePaths;
 
-  CCTestSuite(Map configuration,
-              String suiteName,
-              String runnerName,
-              this.statusFilePaths,
-              {this.testPrefix: ''})
+  CCTestSuite(Map configuration, String suiteName, String runnerName,
+      this.statusFilePaths,
+      {this.testPrefix: ''})
       : super(configuration, suiteName),
         dartDir = TestUtils.dartDir.toNativePath() {
     // For running the tests we use the given '$runnerName' binary
@@ -585,8 +577,7 @@
     // "suiteName/testName" for cc tests.
     String constructedName = '$suiteName/$testPrefix$testName';
 
-    var expectations = testExpectations.expectations(
-        '$testPrefix$testName');
+    var expectations = testExpectations.expectations('$testPrefix$testName');
 
     var args = TestUtils.standardOptions(configuration);
     args.add(testName);
@@ -616,7 +607,6 @@
   }
 }
 
-
 class TestInformation {
   Path filePath;
   Path originTestPath;
@@ -628,27 +618,36 @@
   bool hasStaticWarning;
   String multitestKey;
 
-  TestInformation(this.filePath, this.originTestPath, this.optionsFromFile,
-                  this.hasCompileError, this.hasRuntimeError,
-                  this.isNegativeIfChecked, this.hasCompileErrorIfChecked,
-                  this.hasStaticWarning,
-                  {this.multitestKey: ''}) {
+  TestInformation(
+      this.filePath,
+      this.originTestPath,
+      this.optionsFromFile,
+      this.hasCompileError,
+      this.hasRuntimeError,
+      this.isNegativeIfChecked,
+      this.hasCompileErrorIfChecked,
+      this.hasStaticWarning,
+      {this.multitestKey: ''}) {
     assert(filePath.isAbsolute);
   }
 }
 
-
 class HtmlTestInformation extends TestInformation {
   List<String> expectedMessages;
   List<String> scripts;
 
   HtmlTestInformation(Path filePath, this.expectedMessages, this.scripts)
-      : super(filePath, filePath,
-              {'isMultitest': false, 'isMultiHtmlTest': false},
-              false, false, false, false, false) {}
+      : super(
+            filePath,
+            filePath,
+            {'isMultitest': false, 'isMultiHtmlTest': false},
+            false,
+            false,
+            false,
+            false,
+            false) {}
 }
 
-
 /**
  * A standard [TestSuite] implementation that searches for tests in a
  * directory, and creates [TestCase]s that compile and/or run them.
@@ -664,12 +663,9 @@
   final extraVmOptions;
   List<Uri> _dart2JsBootstrapDependencies;
 
-  StandardTestSuite(Map configuration,
-                    String suiteName,
-                    Path suiteDirectory,
-                    this.statusFilePaths,
-                    {this.isTestFilePredicate,
-                    bool recursive: false})
+  StandardTestSuite(Map configuration, String suiteName, Path suiteDirectory,
+      this.statusFilePaths,
+      {this.isTestFilePredicate, bool recursive: false})
       : super(configuration, suiteName),
         dartDir = TestUtils.dartDir,
         listRecursively = recursive,
@@ -678,11 +674,14 @@
     if (!useSdk) {
       _dart2JsBootstrapDependencies = [];
     } else {
-      var snapshotPath = TestUtils.absolutePath(new Path(buildDir).join(
-          new Path('dart-sdk/bin/snapshots/'
-                   'utils_wrapper.dart.snapshot'))).toString();
-      _dart2JsBootstrapDependencies =
-          [new Uri(scheme: 'file', path: snapshotPath)];
+      var snapshotPath = TestUtils
+          .absolutePath(
+              new Path(buildDir).join(new Path('dart-sdk/bin/snapshots/'
+                  'utils_wrapper.dart.snapshot')))
+          .toString();
+      _dart2JsBootstrapDependencies = [
+        new Uri(scheme: 'file', path: snapshotPath)
+      ];
     }
   }
 
@@ -715,14 +714,14 @@
    */
   factory StandardTestSuite.forDirectory(Map configuration, Path directory) {
     var name = directory.filename;
-    var status_paths = ['$directory/$name.status',
-                        '$directory/.status',
-                        '$directory/${name}_dart2js.status',
-                        '$directory/${name}_analyzer2.status'];
+    var status_paths = [
+      '$directory/$name.status',
+      '$directory/.status',
+      '$directory/${name}_dart2js.status',
+      '$directory/${name}_analyzer2.status'
+    ];
 
-    return new StandardTestSuite(configuration,
-        name, directory,
-        status_paths,
+    return new StandardTestSuite(configuration, name, directory, status_paths,
         isTestFilePredicate: (filename) => filename.endsWith('_test.dart'),
         recursive: true);
   }
@@ -823,11 +822,12 @@
   }
 
   void enqueueDirectory(Directory dir, FutureGroup group) {
-    var lister = dir.list(recursive: listRecursively)
+    var lister = dir
+        .list(recursive: listRecursively)
         .where((fse) => fse is File)
         .forEach((File f) {
-          enqueueFile(f.path, group);
-        });
+      enqueueFile(f.path, group);
+    });
     group.add(lister);
   }
 
@@ -835,8 +835,8 @@
     if (isHtmlTestFile(filename)) {
       var info = htmlTest.getInformation(filename);
       if (info == null) {
-        DebugLogger.error(
-            "HtmlTest $filename does not contain required annotations");
+        DebugLogger
+            .error("HtmlTest $filename does not contain required annotations");
         return;
       }
       cachedTests.add(info);
@@ -852,11 +852,9 @@
     if (optionsFromFile['isMultitest']) {
       group.add(doMultitest(filePath, buildDir, suiteDir, createTestCase));
     } else {
-      createTestCase(filePath,
-                     filePath,
-                     optionsFromFile['hasCompileError'],
-                     optionsFromFile['hasRuntimeError'],
-                     hasStaticWarning: optionsFromFile['hasStaticWarning']);
+      createTestCase(filePath, filePath, optionsFromFile['hasCompileError'],
+          optionsFromFile['hasRuntimeError'],
+          hasStaticWarning: optionsFromFile['hasStaticWarning']);
     }
   }
 
@@ -864,15 +862,13 @@
     final existsCache = TestUtils.existsCache;
 
     Path root = TestUtils.dartDir;
-    assert ("$filePath".startsWith("$root"));
+    assert("$filePath".startsWith("$root"));
 
     // We start with the parent directory of [filePath] and go up until
     // the root directory (excluding the root).
-    List<String> segments =
-        filePath.directoryPath.relativeTo(root).segments();
+    List<String> segments = filePath.directoryPath.relativeTo(root).segments();
     while (segments.length > 0) {
-      var pubspecYamlPath =
-          new Path(segments.join('/')).append('pubspec.yaml');
+      var pubspecYamlPath = new Path(segments.join('/')).append('pubspec.yaml');
       if (existsCache.doesFileExist(pubspecYamlPath.toNativePath())) {
         return root.join(pubspecYamlPath);
       }
@@ -884,7 +880,7 @@
   void enqueueTestCaseFromTestInformation(TestInformation info) {
     String testName = buildTestCaseDisplayName(suiteDir, info.originTestPath,
         multitestName:
-          info.optionsFromFile['isMultitest'] ? info.multitestKey : "");
+            info.optionsFromFile['isMultitest'] ? info.multitestKey : "");
     Set<Expectation> expectations = testExpectations.expectations(testName);
     if (info is HtmlTestInformation) {
       enqueueHtmlTest(info, testName, expectations);
@@ -898,8 +894,7 @@
       var packageDir = pubspecYamlFile.directoryPath;
       var packageName = packageDir.filename;
 
-      var checkoutDirectory =
-          createPubspecCheckoutDirectory(packageDir);
+      var checkoutDirectory = createPubspecCheckoutDirectory(packageDir);
       var modifiedYamlFile = new Path(checkoutDirectory).append("pubspec.yaml");
       var pubCacheDirectory = new Path(checkoutDirectory).append("pub-cache");
       var newPackageRoot = new Path(checkoutDirectory).append("packages");
@@ -919,8 +914,8 @@
       // NOTE: We make a link in the package-root to pkg/expect, since
       // 'package:expect' is not available on pub.dartlang.org!
       var expectLink = newPackageRoot.append('expect');
-      var expectLinkTarget = TestUtils.dartDir
-          .append('pkg').append('expect').append('lib');
+      var expectLinkTarget =
+          TestUtils.dartDir.append('pkg').append('expect').append('lib');
 
       // Generate dependency overrides if we use repository packages.
       var packageDirectories = {};
@@ -951,10 +946,7 @@
       commands.add(CommandBuilder.instance.getMakeSymlinkCommand(
           expectLink.toNativePath(), expectLinkTarget.toNativePath()));
 
-      return {
-        'commands' : commands,
-        'package-root' : newPackageRoot,
-      };
+      return {'commands': commands, 'package-root': newPackageRoot,};
     }
 
     // If this test is inside a package, we will check if there is a
@@ -1003,24 +995,21 @@
             baseCommands, packageRoot, info, testName, expectations);
       }
     } else {
-      enqueueStandardTest(
-          baseCommands, info, testName, expectations);
+      enqueueStandardTest(baseCommands, info, testName, expectations);
     }
   }
 
-  void enqueueStandardTest(List<Command> baseCommands,
-                           TestInformation info,
-                           String testName,
-                           Set<Expectation> expectations) {
-    var commonArguments = commonArgumentsFromFile(info.filePath,
-                                                  info.optionsFromFile);
+  void enqueueStandardTest(List<Command> baseCommands, TestInformation info,
+      String testName, Set<Expectation> expectations) {
+    var commonArguments =
+        commonArgumentsFromFile(info.filePath, info.optionsFromFile);
 
     List<List<String>> vmOptionsList = getVmOptions(info.optionsFromFile);
     assert(!vmOptionsList.isEmpty);
 
     for (var vmOptionsVarient = 0;
-         vmOptionsVarient < vmOptionsList.length;
-         vmOptionsVarient++) {
+        vmOptionsVarient < vmOptionsList.length;
+        vmOptionsVarient++) {
       var vmOptions = vmOptionsList[vmOptionsVarient];
       var allVmOptions = vmOptions;
       if (!extraVmOptions.isEmpty) {
@@ -1028,15 +1017,11 @@
       }
 
       var commands = []..addAll(baseCommands);
-      commands.addAll(makeCommands(info, vmOptionsVarient,
-                                   allVmOptions, commonArguments));
-      enqueueNewTestCase(
-          new TestCase('$suiteName/$testName',
-                       commands,
-                       configuration,
-                       expectations,
-                       isNegative: isNegative(info),
-                       info: info));
+      commands.addAll(
+          makeCommands(info, vmOptionsVarient, allVmOptions, commonArguments));
+      enqueueNewTestCase(new TestCase(
+          '$suiteName/$testName', commands, configuration, expectations,
+          isNegative: isNegative(info), info: info));
     }
   }
 
@@ -1054,10 +1039,8 @@
     return negative;
   }
 
-  List<Command> makeCommands(TestInformation info,
-                             int vmOptionsVarient,
-                             var vmOptions,
-                             var args) {
+  List<Command> makeCommands(
+      TestInformation info, int vmOptionsVarient, var vmOptions, var args) {
     List<Command> commands = <Command>[];
     CompilerConfiguration compilerConfiguration =
         new CompilerConfiguration(configuration);
@@ -1066,10 +1049,8 @@
     List<String> compileTimeArguments = <String>[];
     String tempDir;
     if (compilerConfiguration.hasCompiler) {
-      compileTimeArguments =
-          compilerConfiguration.computeCompilerArguments(vmOptions,
-                                                         sharedOptions,
-                                                         args);
+      compileTimeArguments = compilerConfiguration.computeCompilerArguments(
+          vmOptions, sharedOptions, args);
       // Avoid doing this for analyzer.
       var path = info.filePath;
       if (vmOptionsVarient != 0) {
@@ -1101,38 +1082,38 @@
             runtimeConfiguration,
             buildDir,
             info,
-            vmOptions, sharedOptions, args,
+            vmOptions,
+            sharedOptions,
+            args,
             compilationArtifact);
 
     return commands
-        ..addAll(
-            runtimeConfiguration.computeRuntimeCommands(
-                this,
-                CommandBuilder.instance,
-                compilationArtifact,
-                runtimeArguments,
-                environmentOverrides));
+      ..addAll(runtimeConfiguration.computeRuntimeCommands(
+          this,
+          CommandBuilder.instance,
+          compilationArtifact,
+          runtimeArguments,
+          environmentOverrides));
   }
 
   CreateTest makeTestCaseCreator(Map optionsFromFile) {
-    return (Path filePath,
-            Path originTestPath,
-            bool hasCompileError,
-            bool hasRuntimeError,
-            {bool isNegativeIfChecked: false,
-             bool hasCompileErrorIfChecked: false,
-             bool hasStaticWarning: false,
-             String multitestKey}) {
+    return (Path filePath, Path originTestPath, bool hasCompileError,
+        bool hasRuntimeError,
+        {bool isNegativeIfChecked: false,
+        bool hasCompileErrorIfChecked: false,
+        bool hasStaticWarning: false,
+        String multitestKey}) {
       // Cache the test information for each test case.
-      var info = new TestInformation(filePath,
-                                     originTestPath,
-                                     optionsFromFile,
-                                     hasCompileError,
-                                     hasRuntimeError,
-                                     isNegativeIfChecked,
-                                     hasCompileErrorIfChecked,
-                                     hasStaticWarning,
-                                     multitestKey: multitestKey);
+      var info = new TestInformation(
+          filePath,
+          originTestPath,
+          optionsFromFile,
+          hasCompileError,
+          hasRuntimeError,
+          isNegativeIfChecked,
+          hasCompileErrorIfChecked,
+          hasStaticWarning,
+          multitestKey: multitestKey);
       cachedTests.add(info);
       enqueueTestCaseFromTestInformation(info);
     };
@@ -1179,15 +1160,16 @@
     if (subtestName != null) {
       parameters['group'] = subtestName;
     }
-    return new Uri(scheme: 'http',
-                   host: configuration['local_ip'],
-                   port: serverPort,
-                   path: pathComponent,
-                   queryParameters: parameters);
+    return new Uri(
+        scheme: 'http',
+        host: configuration['local_ip'],
+        port: serverPort,
+        path: pathComponent,
+        queryParameters: parameters);
   }
 
-  void _createWrapperFile(String dartWrapperFilename,
-                          Path localDartLibraryFilename) {
+  void _createWrapperFile(
+      String dartWrapperFilename, Path localDartLibraryFilename) {
     File file = new File(dartWrapperFilename);
     RandomAccessFile dartWrapper = file.openSync(mode: FileMode.WRITE);
 
@@ -1210,12 +1192,8 @@
    * subTestName, Set<String>> if we are running a browser multi-test (one
    * compilation and many browser runs).
    */
-  void enqueueBrowserTest(
-      List<Command> baseCommands,
-      Path packageRoot,
-      TestInformation info,
-      String testName,
-      expectations) {
+  void enqueueBrowserTest(List<Command> baseCommands, Path packageRoot,
+      TestInformation info, String testName, expectations) {
     RegExp badChars = new RegExp('[-=/]');
     List VmOptionsList = getVmOptions(info.optionsFromFile);
     bool multipleOptions = VmOptionsList.length > 1;
@@ -1223,18 +1201,11 @@
       String optionsName =
           multipleOptions ? vmOptions.join('-').replaceAll(badChars, '') : '';
       String tempDir = createOutputDirectory(info.filePath, optionsName);
-      enqueueBrowserTestWithOptions(
-          baseCommands,
-          packageRoot,
-          info,
-          testName,
-          expectations,
-          vmOptions,
-          tempDir);
+      enqueueBrowserTestWithOptions(baseCommands, packageRoot, info, testName,
+          expectations, vmOptions, tempDir);
     }
   }
 
-
   void enqueueBrowserTestWithOptions(
       List<Command> baseCommands,
       Path packageRoot,
@@ -1337,13 +1308,8 @@
     }
 
     if (compiler != 'none') {
-      commands.add(
-          _compileCommand(
-              dartWrapperFilename,
-              compiledDartWrapperFilename,
-              compiler,
-              tempDir,
-              optionsFromFile));
+      commands.add(_compileCommand(dartWrapperFilename,
+          compiledDartWrapperFilename, compiler, tempDir, optionsFromFile));
     }
 
     // some tests require compiling multiple input scripts.
@@ -1354,13 +1320,8 @@
       Path fromPath = filePath.directoryPath.join(namePath);
       if (compiler != 'none') {
         assert(namePath.extension == 'dart');
-        commands.add(
-            _compileCommand(
-                fromPath.toNativePath(),
-                '$tempDir/$fileName.js',
-                compiler,
-                tempDir,
-                optionsFromFile));
+        commands.add(_compileCommand(fromPath.toNativePath(),
+            '$tempDir/$fileName.js', compiler, tempDir, optionsFromFile));
       }
       if (compiler == 'none') {
         // For the tests that require multiple input scripts but are not
@@ -1371,13 +1332,12 @@
       }
     }
 
-
     // Variables for browser multi-tests.
     bool multitest = info.optionsFromFile['isMultiHtmlTest'];
     List<String> subtestNames =
         multitest ? info.optionsFromFile['subtestNames'] : [null];
     for (String subtestName in subtestNames) {
-    // Construct the command that executes the browser test
+      // Construct the command that executes the browser test
       List<Command> commandSet = new List<Command>.from(commands);
 
       var htmlPath_subtest = _createUrlPathFromFile(new Path(htmlPath));
@@ -1400,42 +1360,29 @@
           dartFlags.addAll(vmOptions);
         }
 
-        commandSet.add(
-            CommandBuilder.instance.getContentShellCommand(
-                contentShellFilename,
-                fullHtmlPath,
-                contentShellOptions,
-                dartFlags,
-                environmentOverrides));
+        commandSet.add(CommandBuilder.instance.getContentShellCommand(
+            contentShellFilename,
+            fullHtmlPath,
+            contentShellOptions,
+            dartFlags,
+            environmentOverrides));
       } else {
-        commandSet.add(
-            CommandBuilder.instance.getBrowserTestCommand(
-                runtime,
-                fullHtmlPath,
-                configuration,
-                !isNegative(info)));
+        commandSet.add(CommandBuilder.instance.getBrowserTestCommand(
+            runtime, fullHtmlPath, configuration, !isNegative(info)));
       }
 
       // Create BrowserTestCase and queue it.
       var fullTestName = multitest ? '$testName/$subtestName' : testName;
       var expectation = multitest ? expectations[fullTestName] : expectations;
-      var testCase = new BrowserTestCase(
-            '$suiteName/$fullTestName',
-            commandSet,
-            configuration,
-            expectation,
-            info,
-            isNegative(info),
-            fullHtmlPath);
+      var testCase = new BrowserTestCase('$suiteName/$fullTestName', commandSet,
+          configuration, expectation, info, isNegative(info), fullHtmlPath);
 
       enqueueNewTestCase(testCase);
     }
   }
 
   void enqueueHtmlTest(
-      HtmlTestInformation info,
-      String testName,
-      expectations) {
+      HtmlTestInformation info, String testName, expectations) {
     final String compiler = configuration['compiler'];
     final String runtime = configuration['runtime'];
     // Html tests work only with the browser controller.
@@ -1475,19 +1422,15 @@
         Uri script = testUri.resolveUri(uri);
         Uri copiedScript = tempUri.resolveUri(uri);
         if (compiler == 'none' || scriptPath.endsWith('.js')) {
-          new File.fromUri(copiedScript).writeAsStringSync(
-              new File.fromUri(script).readAsStringSync());
+          new File.fromUri(copiedScript)
+              .writeAsStringSync(new File.fromUri(script).readAsStringSync());
         } else {
           var destination = copiedScript.toFilePath();
           if (compileToJS) {
             destination = destination.replaceFirst(dartExtension, '.js');
           }
-          commands.add(_compileCommand(
-              script.toFilePath(),
-              destination,
-              compiler,
-              tempDir,
-              info.optionsFromFile));
+          commands.add(_compileCommand(script.toFilePath(), destination,
+              compiler, tempDir, info.optionsFromFile));
         }
       }
     }
@@ -1496,28 +1439,18 @@
 
     var htmlPath = _createUrlPathFromFile(new Path(htmlFile.toFilePath()));
     var fullHtmlPath = _getUriForBrowserTest(htmlPath, null).toString();
-    commands.add(CommandBuilder.instance.getBrowserHtmlTestCommand(
-        runtime,
-        fullHtmlPath,
-        configuration,
-        info.expectedMessages,
-        !isNegative(info)));
+    commands.add(CommandBuilder.instance.getBrowserHtmlTestCommand(runtime,
+        fullHtmlPath, configuration, info.expectedMessages, !isNegative(info)));
     String testDisplayName = '$suiteName/$testName';
-    var testCase = new BrowserTestCase(
-        testDisplayName,
-        commands,
-        configuration,
-        expectations,
-        info,
-        isNegative(info),
-        fullHtmlPath);
+    var testCase = new BrowserTestCase(testDisplayName, commands, configuration,
+        expectations, info, isNegative(info), fullHtmlPath);
     enqueueNewTestCase(testCase);
     return;
   }
 
   /** Helper to create a compilation command for a single input file. */
-  Command _compileCommand(String inputFile, String outputFile,
-      String compiler, String dir, optionsFromFile) {
+  Command _compileCommand(String inputFile, String outputFile, String compiler,
+      String dir, optionsFromFile) {
     assert(compiler == 'dart2js');
     List<String> args;
     if (compilerPath.endsWith('.dart')) {
@@ -1527,8 +1460,7 @@
       args = [];
     }
     args.addAll(TestUtils.standardOptions(configuration));
-    String packageRoot =
-      packageRootArgument(optionsFromFile['packageRoot']);
+    String packageRoot = packageRootArgument(optionsFromFile['packageRoot']);
     if (packageRoot != null) args.add(packageRoot);
     String packages = packagesArgument(optionsFromFile['packages']);
     if (packages != null) args.add(packages);
@@ -1537,22 +1469,31 @@
     List<String> options = optionsFromFile['sharedOptions'];
     if (options != null) args.addAll(options);
     return CommandBuilder.instance.getCompilationCommand(
-        compiler, outputFile, !useSdk,
-        dart2JsBootstrapDependencies, compilerPath, args, environmentOverrides);
+        compiler,
+        outputFile,
+        !useSdk,
+        dart2JsBootstrapDependencies,
+        compilerPath,
+        args,
+        environmentOverrides);
   }
 
   /** Helper to create a Polymer deploy command for a single HTML file. */
-  Command _polymerDeployCommand(String inputFile, String outputDir,
-      optionsFromFile) {
+  Command _polymerDeployCommand(
+      String inputFile, String outputDir, optionsFromFile) {
     List<String> args = [];
     String packageRoot = packageRootArgument(optionsFromFile['packageRoot']);
     if (packageRoot != null) args.add(packageRoot);
     String packages = packagesArgument(optionsFromFile['packages']);
     if (packages != null) args.add(packages);
-    args..add('package:polymer/deploy.dart')
-        ..add('--test')..add(inputFile)
-        ..add('--out')..add(outputDir)
-        ..add('--file-filter')..add('.svn');
+    args
+      ..add('package:polymer/deploy.dart')
+      ..add('--test')
+      ..add(inputFile)
+      ..add('--out')
+      ..add(outputDir)
+      ..add('--file-filter')
+      ..add('.svn');
     if (configuration['csp']) args.add('--csp');
 
     return CommandBuilder.instance.getProcessCommand(
@@ -1568,14 +1509,14 @@
         return 'text/javascript';
       default:
         print('Non-web runtime, so no scriptType for: '
-                    '${configuration["compiler"]}');
+            '${configuration["compiler"]}');
         exit(1);
         return null;
     }
   }
 
   bool get hasRuntime {
-    switch(configuration['runtime']) {
+    switch (configuration['runtime']) {
       case 'none':
         return false;
       default:
@@ -1614,7 +1555,7 @@
 
     if (configuration["compiler"] == "dart2analyzer" &&
         (filePath.filename.contains("dart2js") ||
-        filePath.directoryPath.segments().last.contains('html_common'))) {
+            filePath.directoryPath.segments().last.contains('html_common'))) {
       args.add("--use-dart2js-libraries");
     }
 
@@ -1733,8 +1674,8 @@
     RegExp packagesRegExp = new RegExp(r"// Packages=(.*)");
     RegExp isolateStubsRegExp = new RegExp(r"// IsolateStubs=(.*)");
     // TODO(gram) Clean these up once the old directives are not supported.
-    RegExp domImportRegExp =
-        new RegExp(r"^[#]?import.*dart:(html|web_audio|indexed_db|svg|web_sql)",
+    RegExp domImportRegExp = new RegExp(
+        r"^[#]?import.*dart:(html|web_audio|indexed_db|svg|web_sql)",
         multiLine: true);
 
     var bytes = new File(filePath.toNativePath()).readAsBytesSync();
@@ -1813,34 +1754,43 @@
     List<String> subtestNames = [];
     Iterator matchesIter =
         multiHtmlTestGroupRegExp.allMatches(contents).iterator;
-    while(matchesIter.moveNext() && isMultiHtmlTest) {
+    while (matchesIter.moveNext() && isMultiHtmlTest) {
       String fullMatch = matchesIter.current.group(0);
       subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
     }
 
-    return { "vmOptions": result,
-             "sharedOptions": sharedOptions == null ? [] : sharedOptions,
-             "dartOptions": dartOptions,
-             "packageRoot": packageRoot,
-             "packages": packages,
-             "hasCompileError": false,
-             "hasRuntimeError": false,
-             "hasStaticWarning" : false,
-             "otherScripts": otherScripts,
-             "isMultitest": isMultitest,
-             "isMultiHtmlTest": isMultiHtmlTest,
-             "subtestNames": subtestNames,
-             "isolateStubs": isolateStubs,
-             "containsDomImport": containsDomImport };
+    return {
+      "vmOptions": result,
+      "sharedOptions": sharedOptions == null ? [] : sharedOptions,
+      "dartOptions": dartOptions,
+      "packageRoot": packageRoot,
+      "packages": packages,
+      "hasCompileError": false,
+      "hasRuntimeError": false,
+      "hasStaticWarning": false,
+      "otherScripts": otherScripts,
+      "isMultitest": isMultitest,
+      "isMultiHtmlTest": isMultiHtmlTest,
+      "subtestNames": subtestNames,
+      "isolateStubs": isolateStubs,
+      "containsDomImport": containsDomImport
+    };
   }
 
   List<List<String>> getVmOptions(Map optionsFromFile) {
     var COMPILERS = const ['none', 'precompiler', 'dart2app'];
-    var RUNTIMES = const ['none', 'dart_precompiled', 'dart_product', 'vm',
-                          'drt', 'dartium',
-                          'ContentShellOnAndroid', 'DartiumOnAndroid'];
+    var RUNTIMES = const [
+      'none',
+      'dart_precompiled',
+      'dart_product',
+      'vm',
+      'drt',
+      'dartium',
+      'ContentShellOnAndroid',
+      'DartiumOnAndroid'
+    ];
     var needsVmOptions = COMPILERS.contains(configuration['compiler']) &&
-                         RUNTIMES.contains(configuration['runtime']);
+        RUNTIMES.contains(configuration['runtime']);
     if (!needsVmOptions) return [[]];
     final vmOptions = optionsFromFile['vmOptions'];
     return vmOptions;
@@ -1861,8 +1811,8 @@
    * environment variables, configuration files, etc.
    */
   Map readOptionsFromCo19File(Path filePath) {
-    String contents = decodeUtf8(new File(filePath.toNativePath())
-        .readAsBytesSync());
+    String contents =
+        decodeUtf8(new File(filePath.toNativePath()).readAsBytesSync());
 
     bool hasCompileError = contents.contains("@compile-error");
     bool hasRuntimeError = contents.contains("@runtime-error");
@@ -1876,7 +1826,7 @@
       "packageRoot": null,
       "hasCompileError": hasCompileError,
       "hasRuntimeError": hasRuntimeError,
-      "hasStaticWarning" : hasStaticWarning,
+      "hasStaticWarning": hasStaticWarning,
       "otherScripts": <String>[],
       "isMultitest": isMultitest,
       "isMultiHtmlTest": false,
@@ -1887,54 +1837,46 @@
   }
 }
 
-
 /// Used for testing packages in on off settings, i.e., we pass in the actual
 /// directory that we want to test.
 class PKGTestSuite extends StandardTestSuite {
-
   PKGTestSuite(Map configuration, Path directoryPath)
-      : super(configuration,
-              directoryPath.filename,
-              directoryPath,
-              ["$directoryPath/.status"],
-              isTestFilePredicate: (f) => f.endsWith('_test.dart'),
-              recursive: true);
+      : super(configuration, directoryPath.filename, directoryPath,
+            ["$directoryPath/.status"],
+            isTestFilePredicate: (f) => f.endsWith('_test.dart'),
+            recursive: true);
 
-    void enqueueBrowserTest(List<Command> baseCommands,
-                          Path packageRoot,
-                          TestInformation info,
-                          String testName,
-                          expectations) {
-      String runtime = configuration['runtime'];
-      Path filePath = info.filePath;
-      Path dir = filePath.directoryPath;
-      String nameNoExt = filePath.filenameWithoutExtension;
-      Path customHtmlPath = dir.append('$nameNoExt.html');
-      File customHtml = new File(customHtmlPath.toNativePath());
-      if (!customHtml.existsSync()) {
-        super.enqueueBrowserTest(baseCommands, packageRoot,
-                                 info, testName, expectations);
-      } else {
-        Path relativeHtml = customHtmlPath.relativeTo(TestUtils.dartDir);
-        List<Command> commands = []..addAll(baseCommands);
-        var fullPath = _createUrlPathFromFile(customHtmlPath);
+  void enqueueBrowserTest(List<Command> baseCommands, Path packageRoot,
+      TestInformation info, String testName, expectations) {
+    String runtime = configuration['runtime'];
+    Path filePath = info.filePath;
+    Path dir = filePath.directoryPath;
+    String nameNoExt = filePath.filenameWithoutExtension;
+    Path customHtmlPath = dir.append('$nameNoExt.html');
+    File customHtml = new File(customHtmlPath.toNativePath());
+    if (!customHtml.existsSync()) {
+      super.enqueueBrowserTest(
+          baseCommands, packageRoot, info, testName, expectations);
+    } else {
+      Path relativeHtml = customHtmlPath.relativeTo(TestUtils.dartDir);
+      List<Command> commands = []..addAll(baseCommands);
+      var fullPath = _createUrlPathFromFile(customHtmlPath);
 
-        commands.add(CommandBuilder.instance.getBrowserTestCommand(
-            runtime, fullPath, configuration, !isNegative(info)));
-        String testDisplayName = '$suiteName/$testName';
-        enqueueNewTestCase(new BrowserTestCase(testDisplayName,
-                                               commands,
-                                               configuration,
-                                               expectations,
-                                               info,
-                                               isNegative(info),
-                                               relativeHtml.toNativePath()));
-
-      }
+      commands.add(CommandBuilder.instance.getBrowserTestCommand(
+          runtime, fullPath, configuration, !isNegative(info)));
+      String testDisplayName = '$suiteName/$testName';
+      enqueueNewTestCase(new BrowserTestCase(
+          testDisplayName,
+          commands,
+          configuration,
+          expectations,
+          info,
+          isNegative(info),
+          relativeHtml.toNativePath()));
     }
+  }
 }
 
-
 /// A DartcCompilationTestSuite will run dartc on all of the tests.
 ///
 /// Usually, the result of a dartc run is determined by the output of
@@ -1942,15 +1884,13 @@
 class DartcCompilationTestSuite extends StandardTestSuite {
   List<String> _testDirs;
 
-  DartcCompilationTestSuite(Map configuration,
-                            String suiteName,
-                            String directoryPath,
-                            List<String> this._testDirs,
-                            List<String> expectations)
-      : super(configuration,
-              suiteName,
-              new Path(directoryPath),
-              expectations);
+  DartcCompilationTestSuite(
+      Map configuration,
+      String suiteName,
+      String directoryPath,
+      List<String> this._testDirs,
+      List<String> expectations)
+      : super(configuration, suiteName, new Path(directoryPath), expectations);
 
   List<String> additionalOptions(Path filePath) {
     return ['--fatal-warnings', '--fatal-type-errors'];
@@ -1970,14 +1910,10 @@
   }
 }
 
-
 class AnalyzeLibraryTestSuite extends DartcCompilationTestSuite {
   AnalyzeLibraryTestSuite(Map configuration)
-      : super(configuration,
-              'analyze_library',
-              'sdk',
-              ['lib'],
-              ['tests/lib/analyzer/analyze_library.status']);
+      : super(configuration, 'analyze_library', 'sdk', ['lib'],
+            ['tests/lib/analyzer/analyze_library.status']);
 
   List<String> additionalOptions(Path filePath, {bool showSdkWarnings}) {
     var options = super.additionalOptions(filePath);
@@ -1996,24 +1932,25 @@
   bool get listRecursively => true;
 }
 
-
 class PkgBuildTestSuite extends TestSuite {
   final String statusFilePath;
 
   PkgBuildTestSuite(Map configuration, String suiteName, this.statusFilePath)
       : super(configuration, suiteName) {
-    assert(configuration['use_sdk']);;
+    assert(configuration['use_sdk']);
+    ;
   }
 
   void forEachTest(void onTest(TestCase testCase), _, [void onDone()]) {
     bool fileExists(Path path) => new File(path.toNativePath()).existsSync();
 
-    bool dirExists(Path path)
-        => new Directory(path.toNativePath()).existsSync();
+    bool dirExists(Path path) =>
+        new Directory(path.toNativePath()).existsSync();
 
-    enqueueTestCases(Map<String, String> localPackageDirectories,
-                     Map<String, String> localSampleDirectories,
-                     TestExpectations testExpectations) {
+    enqueueTestCases(
+        Map<String, String> localPackageDirectories,
+        Map<String, String> localSampleDirectories,
+        TestExpectations testExpectations) {
       enqueueTestCase(String packageName, String directory) {
         var absoluteDirectoryPath = new Path(directory);
 
@@ -2022,8 +1959,7 @@
           return;
         }
 
-        var directoryPath =
-            absoluteDirectoryPath.relativeTo(TestUtils.dartDir);
+        var directoryPath = absoluteDirectoryPath.relativeTo(TestUtils.dartDir);
         var testName = "$directoryPath";
         var displayName = '$suiteName/$testName';
         var packageName = directoryPath.filename;
@@ -2055,10 +1991,10 @@
         var commands = new List<Command>();
         commands.add(
             CommandBuilder.instance.getCopyCommand(directory, checkoutDir));
-        commands.add(CommandBuilder.instance.getModifyPubspecCommand(
-            pubspecYamlFile, dependencyOverrides));
-        commands.add(CommandBuilder.instance.getPubCommand(
-            "get", pubPath, checkoutDir, cacheDir));
+        commands.add(CommandBuilder.instance
+            .getModifyPubspecCommand(pubspecYamlFile, dependencyOverrides));
+        commands.add(CommandBuilder.instance
+            .getPubCommand("get", pubPath, checkoutDir, cacheDir));
 
         bool containsWebDirectory = dirExists(directoryPath.append('web'));
         bool containsBuildDartFile =
@@ -2067,23 +2003,29 @@
           var dartBinary = new File(dartVmBinaryFileName).absolute.path;
 
           commands.add(CommandBuilder.instance.getProcessCommand(
-              "custom_build", dartBinary, ['build.dart'],
-              {'PUB_CACHE': cacheDir}, checkoutDir));
+              "custom_build",
+              dartBinary,
+              ['build.dart'],
+              {'PUB_CACHE': cacheDir},
+              checkoutDir));
 
           // We only try to deploy the application if it's a webapp.
           if (containsWebDirectory) {
             commands.add(CommandBuilder.instance.getProcessCommand(
-                 "custom_deploy", dartBinary, ['build.dart', '--deploy'],
-                 {'PUB_CACHE': cacheDir}, checkoutDir));
+                "custom_deploy",
+                dartBinary,
+                ['build.dart', '--deploy'],
+                {'PUB_CACHE': cacheDir},
+                checkoutDir));
           }
-        } else if (containsWebDirectory)  {
-          commands.add(CommandBuilder.instance.getPubCommand(
-             "build", pubPath, checkoutDir, cacheDir));
+        } else if (containsWebDirectory) {
+          commands.add(CommandBuilder.instance
+              .getPubCommand("build", pubPath, checkoutDir, cacheDir));
         }
 
         // Enqueue TestCase
-        var testCase = new TestCase(displayName,
-            commands, configuration, testExpectations.expectations(testName));
+        var testCase = new TestCase(displayName, commands, configuration,
+            testExpectations.expectations(testName));
         enqueueNewTestCase(testCase);
       }
 
@@ -2097,10 +2039,13 @@
 
     doTest = onTest;
     List<String> statusFiles = [
-        TestUtils.dartDir.join(new Path(statusFilePath)).toNativePath()];
+      TestUtils.dartDir.join(new Path(statusFilePath)).toNativePath()
+    ];
     ReadTestExpectations(statusFiles, configuration).then((expectations) {
-      Future.wait([discoverPackagesInRepository(),
-                   discoverSamplesInRepository()]).then((List results) {
+      Future.wait([
+        discoverPackagesInRepository(),
+        discoverSamplesInRepository()
+      ]).then((List results) {
         Map packageDirectories = results[0];
         Map sampleDirectories = results[1];
         enqueueTestCases(packageDirectories, sampleDirectories, expectations);
@@ -2109,7 +2054,6 @@
   }
 }
 
-
 class LastModifiedCache {
   Map<String, DateTime> _cache = <String, DateTime>{};
 
@@ -2135,7 +2079,6 @@
   }
 }
 
-
 class ExistsCache {
   Map<String, bool> _cache = <String, bool>{};
 
@@ -2152,7 +2095,6 @@
   }
 }
 
-
 class TestUtils {
   /**
    * Any script using TestUtils must set dartDirUri to a file:// URI
@@ -2162,13 +2104,13 @@
     dartDirUri = uri;
     dartDir = new Path(uri.toFilePath());
   }
+
   static Random rand = new Random.secure();
   static Uri dartDirUri;
   static Path dartDir;
   static LastModifiedCache lastModifiedCache = new LastModifiedCache();
   static ExistsCache existsCache = new ExistsCache();
-  static Path currentWorkingDirectory =
-      new Path(Directory.current.path);
+  static Path currentWorkingDirectory = new Path(Directory.current.path);
 
   /**
    * Generates a random number.
@@ -2210,7 +2152,8 @@
    * Assumes that the directory for [dest] already exists.
    */
   static Future copyFile(Path source, Path dest) {
-    return new File(source.toNativePath()).openRead()
+    return new File(source.toNativePath())
+        .openRead()
         .pipe(new File(dest.toNativePath()).openWrite());
   }
 
@@ -2240,13 +2183,14 @@
       var native_path = new Path(path).toNativePath();
       // Running this in a shell sucks, but rmdir is not part of the standard
       // path.
-      return Process.run('rmdir', ['/s', '/q', native_path], runInShell: true)
-        .then((ProcessResult result) {
-          if (result.exitCode != 0) {
-            throw new Exception('Can\'t delete path $native_path. '
-                                'This path might be too long');
-          }
-        });
+      return Process
+          .run('rmdir', ['/s', '/q', native_path], runInShell: true)
+          .then((ProcessResult result) {
+        if (result.exitCode != 0) {
+          throw new Exception('Can\'t delete path $native_path. '
+              'This path might be too long');
+        }
+      });
     } else {
       var dir = new Directory(path);
       return dir.delete(recursive: true);
@@ -2259,8 +2203,8 @@
       var minified = configuration['minified'] ? '-minified' : '';
       var csp = configuration['csp'] ? '-csp' : '';
       var sdk = configuration['use_sdk'] ? '-sdk' : '';
-      var packages = configuration['use_public_packages']
-          ? '-public_packages' : '';
+      var packages =
+          configuration['use_public_packages'] ? '-public_packages' : '';
       var dirName = "${configuration['compiler']}"
           "$checked$minified$csp$packages$sdk";
       String generatedPath = "${TestUtils.buildDir(configuration)}"
@@ -2328,8 +2272,7 @@
         args.add("--categories=all");
       }
     }
-    if ((compiler == "dart2js") &&
-        configuration["minified"]) {
+    if ((compiler == "dart2js") && configuration["minified"]) {
       args.add("--minify");
     }
     if (compiler == "dart2js" && configuration["csp"]) {
@@ -2415,7 +2358,7 @@
     var crossDir = new Directory(new Path('$outDir$cross').toNativePath());
     if (normalDir.existsSync() && crossDir.existsSync()) {
       throw "You can't have both $normalDir and $crossDir, we don't know which"
-            " binary to use";
+          " binary to use";
     }
     if (crossDir.existsSync()) {
       return cross;
@@ -2468,7 +2411,6 @@
       "tests_co19_src_WebPlatformTest_html_semantics_embedded-content_"
           "media-elements_": "co19_media_elements",
       "tests_co19_src_WebPlatformTest_html_semantics_": "co19_semantics_",
-
       "tests_co19_src_WebPlatformTest_html-templates_additions-to-"
           "the-steps-to-clone-a-node_": "co19_htmltemplates_clone_",
       "tests_co19_src_WebPlatformTest_html-templates_definitions_"
@@ -2486,7 +2428,6 @@
       "tests_co19_src_WebPlatformTest_html-templates_template-element"
           "_template-": "co19_htmltemplates_element-",
       "tests_co19_src_WebPlatformTest_html-templates_": "co19_htmltemplate_",
-
       "tests_co19_src_WebPlatformTest_shadow-dom_shadow-trees_":
           "co19_shadow-trees_",
       "tests_co19_src_WebPlatformTest_shadow-dom_elements-and-dom-objects_":
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index d000994..fd2245e 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -14,7 +14,7 @@
 const Duration MAX_STDIO_DELAY = const Duration(seconds: 30);
 
 String MAX_STDIO_DELAY_PASSED_MESSAGE =
-"""Not waiting for stdout/stderr from subprocess anymore 
+    """Not waiting for stdout/stderr from subprocess anymore 
 ($MAX_STDIO_DELAY passed). Please note that this could be an indicator 
 that there is a hanging process which we were unable to kill.""";
 
@@ -46,6 +46,7 @@
     // if (trace != null) msg += "\nStackTrace: $trace";
     return msg;
   }
+
   static void info(String msg, [error]) {
     msg = _formatErrorMessage(msg, error);
     _print("$_datetime Info: $msg");
@@ -88,13 +89,12 @@
     if (newLine) buffer.write("\n");
   }
 
-  prettifyJsonInternal(
-      Object obj, {bool indentation: true, bool newLine: true}) {
+  prettifyJsonInternal(Object obj,
+      {bool indentation: true, bool newLine: true}) {
     if (obj is List) {
       addString("[", indentation: indentation);
       currentIndentation += shiftWidth;
       for (var item in obj) {
-
         prettifyJsonInternal(item, indentation: indentation, newLine: false);
         addString(",", indentation: false);
       }
@@ -119,7 +119,6 @@
   return buffer.toString();
 }
 
-
 /**
  * [areByteArraysEqual] compares a range of bytes from [buffer1] with a
  * range of bytes from [buffer2].
@@ -129,9 +128,8 @@
  * [offset2]).
  * Otherwise [false] is returned.
  */
-bool areByteArraysEqual(List<int> buffer1, int offset1,
-                        List<int> buffer2, int offset2,
-                        int count) {
+bool areByteArraysEqual(
+    List<int> buffer1, int offset1, List<int> buffer2, int offset2, int count) {
   if ((offset1 + count) > buffer1.length ||
       (offset2 + count) > buffer2.length) {
     return false;
@@ -151,7 +149,7 @@
  * Returns [true] if [pattern] was found in [data].
  * Otherwise [false] is returned.
  */
-int findBytes(List<int> data, List<int> pattern, [int startPos=0]) {
+int findBytes(List<int> data, List<int> pattern, [int startPos = 0]) {
   // TODO(kustermann): Use one of the fast string-matching algorithms!
   for (int i = startPos; i < (data.length - pattern.length); i++) {
     bool found = true;
@@ -180,47 +178,47 @@
 }
 
 class Locations {
-  static String getBrowserLocation(String browserName,
-                                   Map globalConfiguration) {
+  static String getBrowserLocation(
+      String browserName, Map globalConfiguration) {
     var location = globalConfiguration[browserName];
     if (location != null && location != '') {
       return location;
     }
     var browserLocations = {
-        'firefox': const {
-          'windows': 'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe',
-          'linux': 'firefox',
-          'macos': '/Applications/Firefox.app/Contents/MacOS/firefox'
-        },
-        'chrome': const {
-          'windows':
+      'firefox': const {
+        'windows': 'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe',
+        'linux': 'firefox',
+        'macos': '/Applications/Firefox.app/Contents/MacOS/firefox'
+      },
+      'chrome': const {
+        'windows':
             'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
-          'macos':
-            '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
-          'linux': 'google-chrome'
-        },
-        'dartium': const {
-          'windows': 'client\\tests\\dartium\\chrome.exe',
-          'macos': 'client/tests/dartium/Chromium.app/Contents/MacOS/Chromium',
-          'linux': 'client/tests/dartium/chrome'
-        },
-        'safari': const {
-          'macos': '/Applications/Safari.app/Contents/MacOS/Safari'
-        },
-        'safarimobilesim': const {
-          'macos': '/Applications/Xcode.app/Contents/Developer/Platforms/'
-                   'iPhoneSimulator.platform/Developer/Applications/'
-                   'iPhone Simulator.app/Contents/MacOS/iPhone Simulator'
-        },
-        'ie9': const {
-          'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
-        },
-        'ie10': const {
-          'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
-        },
-        'ie11': const {
-          'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
-        }};
+        'macos': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
+        'linux': 'google-chrome'
+      },
+      'dartium': const {
+        'windows': 'client\\tests\\dartium\\chrome.exe',
+        'macos': 'client/tests/dartium/Chromium.app/Contents/MacOS/Chromium',
+        'linux': 'client/tests/dartium/chrome'
+      },
+      'safari': const {
+        'macos': '/Applications/Safari.app/Contents/MacOS/Safari'
+      },
+      'safarimobilesim': const {
+        'macos': '/Applications/Xcode.app/Contents/Developer/Platforms/'
+            'iPhoneSimulator.platform/Developer/Applications/'
+            'iPhone Simulator.app/Contents/MacOS/iPhone Simulator'
+      },
+      'ie9': const {
+        'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
+      },
+      'ie10': const {
+        'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
+      },
+      'ie11': const {
+        'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
+      }
+    };
     browserLocations['ff'] = browserLocations['firefox'];
 
     assert(browserLocations[browserName] != null);
@@ -246,12 +244,15 @@
   int _value = 0;
 
   void add(Object object) {
-    _value = ((_value * 31) ^ object.hashCode)  & 0x3FFFFFFF;
+    _value = ((_value * 31) ^ object.hashCode) & 0x3FFFFFFF;
   }
 
   void addJson(Object object) {
-    if (object == null || object is num || object is String ||
-                  object is Uri || object is bool) {
+    if (object == null ||
+        object is num ||
+        object is String ||
+        object is Uri ||
+        object is bool) {
       add(object);
     } else if (object is List) {
       object.forEach(addJson);
@@ -304,7 +305,7 @@
   final int _hashCode;
 
   int get hashCode => _hashCode;
-  operator==(other) => other is UniqueObject && _hashCode == other._hashCode;
+  operator ==(other) => other is UniqueObject && _hashCode == other._hashCode;
 
   UniqueObject() : _hashCode = ++_nextId;
 }
diff --git a/tools/testing/dart/vm_test_config.dart b/tools/testing/dart/vm_test_config.dart
index 9fdf36b..9cadd4fc 100644
--- a/tools/testing/dart/vm_test_config.dart
+++ b/tools/testing/dart/vm_test_config.dart
@@ -8,9 +8,7 @@
 
 class VMTestSuite extends CCTestSuite {
   VMTestSuite(Map configuration)
-      : super(configuration,
-              "vm",
-              "run_vm_tests",
-              ["runtime/tests/vm/vm.status"],
-              testPrefix: 'cc/');
+      : super(
+            configuration, "vm", "run_vm_tests", ["runtime/tests/vm/vm.status"],
+            testPrefix: 'cc/');
 }