Add packages to optimize svgs dynamically

These packages will be used to dynamically optimize SVG images
during the build.

R=jacktfranklin@chromium.org

Bug: 1216402
Change-Id: I04e95aa7d79c9d67beaf8a7861182c52b16b7d0f
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2939992
Reviewed-by: Jack Franklin <jacktfranklin@chromium.org>
Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org>
diff --git a/node_modules/css-tree/lib/lexer/generic-urange.js b/node_modules/css-tree/lib/lexer/generic-urange.js
new file mode 100644
index 0000000..2556d70
--- /dev/null
+++ b/node_modules/css-tree/lib/lexer/generic-urange.js
@@ -0,0 +1,159 @@
+var isHexDigit = require('../tokenizer').isHexDigit;
+var cmpChar = require('../tokenizer').cmpChar;
+var TYPE = require('../tokenizer').TYPE;
+
+var IDENT = TYPE.Ident;
+var DELIM = TYPE.Delim;
+var NUMBER = TYPE.Number;
+var DIMENSION = TYPE.Dimension;
+var PLUSSIGN = 0x002B;     // U+002B PLUS SIGN (+)
+var HYPHENMINUS = 0x002D;  // U+002D HYPHEN-MINUS (-)
+var QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
+var U = 0x0075;            // U+0075 LATIN SMALL LETTER U (u)
+
+function isDelim(token, code) {
+    return token !== null && token.type === DELIM && token.value.charCodeAt(0) === code;
+}
+
+function startsWith(token, code) {
+    return token.value.charCodeAt(0) === code;
+}
+
+function hexSequence(token, offset, allowDash) {
+    for (var pos = offset, hexlen = 0; pos < token.value.length; pos++) {
+        var code = token.value.charCodeAt(pos);
+
+        if (code === HYPHENMINUS && allowDash && hexlen !== 0) {
+            if (hexSequence(token, offset + hexlen + 1, false) > 0) {
+                return 6; // dissallow following question marks
+            }
+
+            return 0; // dash at the ending of a hex sequence is not allowed
+        }
+
+        if (!isHexDigit(code)) {
+            return 0; // not a hex digit
+        }
+
+        if (++hexlen > 6) {
+            return 0; // too many hex digits
+        };
+    }
+
+    return hexlen;
+}
+
+function withQuestionMarkSequence(consumed, length, getNextToken) {
+    if (!consumed) {
+        return 0; // nothing consumed
+    }
+
+    while (isDelim(getNextToken(length), QUESTIONMARK)) {
+        if (++consumed > 6) {
+            return 0; // too many question marks
+        }
+
+        length++;
+    }
+
+    return length;
+}
+
+// https://drafts.csswg.org/css-syntax/#urange
+// Informally, the <urange> production has three forms:
+// U+0001
+//      Defines a range consisting of a single code point, in this case the code point "1".
+// U+0001-00ff
+//      Defines a range of codepoints between the first and the second value, in this case
+//      the range between "1" and "ff" (255 in decimal) inclusive.
+// U+00??
+//      Defines a range of codepoints where the "?" characters range over all hex digits,
+//      in this case defining the same as the value U+0000-00ff.
+// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
+//
+// <urange> =
+//   u '+' <ident-token> '?'* |
+//   u <dimension-token> '?'* |
+//   u <number-token> '?'* |
+//   u <number-token> <dimension-token> |
+//   u <number-token> <number-token> |
+//   u '+' '?'+
+module.exports = function urange(token, getNextToken) {
+    var length = 0;
+
+    // should start with `u` or `U`
+    if (token === null || token.type !== IDENT || !cmpChar(token.value, 0, U)) {
+        return 0;
+    }
+
+    token = getNextToken(++length);
+    if (token === null) {
+        return 0;
+    }
+
+    // u '+' <ident-token> '?'*
+    // u '+' '?'+
+    if (isDelim(token, PLUSSIGN)) {
+        token = getNextToken(++length);
+        if (token === null) {
+            return 0;
+        }
+
+        if (token.type === IDENT) {
+            // u '+' <ident-token> '?'*
+            return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken);
+        }
+
+        if (isDelim(token, QUESTIONMARK)) {
+            // u '+' '?'+
+            return withQuestionMarkSequence(1, ++length, getNextToken);
+        }
+
+        // Hex digit or question mark is expected
+        return 0;
+    }
+
+    // u <number-token> '?'*
+    // u <number-token> <dimension-token>
+    // u <number-token> <number-token>
+    if (token.type === NUMBER) {
+        if (!startsWith(token, PLUSSIGN)) {
+            return 0;
+        }
+
+        var consumedHexLength = hexSequence(token, 1, true);
+        if (consumedHexLength === 0) {
+            return 0;
+        }
+
+        token = getNextToken(++length);
+        if (token === null) {
+            // u <number-token> <eof>
+            return length;
+        }
+
+        if (token.type === DIMENSION || token.type === NUMBER) {
+            // u <number-token> <dimension-token>
+            // u <number-token> <number-token>
+            if (!startsWith(token, HYPHENMINUS) || !hexSequence(token, 1, false)) {
+                return 0;
+            }
+
+            return length + 1;
+        }
+
+        // u <number-token> '?'*
+        return withQuestionMarkSequence(consumedHexLength, length, getNextToken);
+    }
+
+    // u <dimension-token> '?'*
+    if (token.type === DIMENSION) {
+        if (!startsWith(token, PLUSSIGN)) {
+            return 0;
+        }
+
+        return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken);
+    }
+
+    return 0;
+};