[blobstats] Give unique Dart code its own type and color

This lets us see Dart and non-Dart code more easily and allows the
visualization to aggregate the size of all Dart blobs.

Test: manual
Change-Id: If96756906e5b3917a9d6605b60124536146f3bdb
diff --git a/blobstats/blobstats.dart b/blobstats/blobstats.dart
index d38b252..ea2c993 100644
--- a/blobstats/blobstats.dart
+++ b/blobstats/blobstats.dart
@@ -327,21 +327,27 @@
         var blobTree = {};
         blobTree["n"] = blobName;
         blobTree["k"] = "s"; // kind=blob
-        if (blobName.endsWith(".dilp") || blobName.endsWith(".aotsnapshot")) {
-          blobTree["t"] = "dart"; // type=Dart ("blue")
+        var isUnique = blob.count == 1;
+        var isDart =
+            blobName.endsWith(".dilp") || blobName.endsWith(".aotsnapshot");
+        if (isDart) {
+          if (isUnique) {
+            blobTree["t"] = "uniDart";
+          } else {
+            blobTree["t"] = "dart"; // type=Shared Dart ("blue")
+          }
         } else {
-          blobTree["t"] = "?"; // type=Other ("red")
+          if (isUnique) {
+            blobTree["t"] = "unique";
+          } else {
+            blobTree["t"] = "?"; // type=Other ("red")
+          }
         }
         blobTree["c"] = blob.count;
         blobTree["value"] = blob.proportional;
         blobTree["originalSize"] = blob.sizeOnHost;
         blobTree["estimatedCompressedSize"] = blob.estimatedCompressedSize;
         pkgTree["children"].add(blobTree);
-        // Mark blobs with exactly one reference as "unique blobs" ("green")
-        // The visualizer helpfully computes the sum of all unique "blobs" within a package.
-        if (blob.count == 1) {
-          blobTree["t"] = "unique";
-        }
       });
     }
 
diff --git a/blobstats/template/D3BlobTreeMap.js b/blobstats/template/D3BlobTreeMap.js
index a741a4d..f98d8ce 100644
--- a/blobstats/template/D3BlobTreeMap.js
+++ b/blobstats/template/D3BlobTreeMap.js
@@ -70,6 +70,7 @@
   'dart': 'Shared Dart',
   '?': 'Shared Unrecognized',
   'unique': 'Unique',
+  'uniDart': 'Unique Dart',
 };
 D3BlobTreeMap._BLOB_TYPES = [];
 for (var blob_type in D3BlobTreeMap._BLOB_TYPE_DESCRIPTIONS) {
@@ -94,6 +95,7 @@
   'rgb(148,116,204)',  // Shared Dart - Deep Purple 300
   'rgb(255,213,79)',  // Unique - Amber 300
   'rgb(77,208,225)',  // Shared Other - Cyan 300
+  'rgb(161,136,127)', // Unique Dart - Brown 300
 ];
 
 D3BlobTreeMap._initColorMap = function() {
@@ -128,7 +130,7 @@
 }
 
 /**
- * Sets the data displayed by the treemap and laying out the map.
+ * Sets the data displayed by the treemap and lays out the map.
  */
 D3BlobTreeMap.prototype._setData = function(data) {
   this._treeData = data;
diff --git a/blobstats/template/index.html b/blobstats/template/index.html
index 02f12f7..7331446 100644
--- a/blobstats/template/index.html
+++ b/blobstats/template/index.html
@@ -384,6 +384,7 @@
                     <span class='swatch' id='swatch_0'>&nbsp;&nbsp;&nbsp;</span><input checked type='checkbox' id='check_0' value='dart'>Shared Dart
                 <br><span class='swatch' id='swatch_1'>&nbsp;&nbsp;&nbsp;</span><input checked type='checkbox' id='check_1' value='?'>Shared Unrecognized
                 <br><span class='swatch' id='swatch_2'>&nbsp;&nbsp;&nbsp;</span><input checked type='checkbox' id='check_2' value='unique'>Unique
+                <br><span class='swatch' id='swatch_3'>&nbsp;&nbsp;&nbsp;</span><input checked type='checkbox' id='check_3' value='uniDart'>Unique Dart
         </tr>
         <tr><td colspan=3 style='text-align: center; white-space: nowrap; padding-top: 1em;'>
             Select <input type='button' onclick='filterSetAll(true)' value='All'>,