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-an-plus-b.js b/node_modules/css-tree/lib/lexer/generic-an-plus-b.js
new file mode 100644
index 0000000..7b8a818
--- /dev/null
+++ b/node_modules/css-tree/lib/lexer/generic-an-plus-b.js
@@ -0,0 +1,236 @@
+var isDigit = require('../tokenizer').isDigit;
+var cmpChar = require('../tokenizer').cmpChar;
+var TYPE = require('../tokenizer').TYPE;
+
+var DELIM = TYPE.Delim;
+var WHITESPACE = TYPE.WhiteSpace;
+var COMMENT = TYPE.Comment;
+var IDENT = TYPE.Ident;
+var NUMBER = TYPE.Number;
+var DIMENSION = TYPE.Dimension;
+var PLUSSIGN = 0x002B;    // U+002B PLUS SIGN (+)
+var HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
+var N = 0x006E;           // U+006E LATIN SMALL LETTER N (n)
+var DISALLOW_SIGN = true;
+var ALLOW_SIGN = false;
+
+function isDelim(token, code) {
+    return token !== null && token.type === DELIM && token.value.charCodeAt(0) === code;
+}
+
+function skipSC(token, offset, getNextToken) {
+    while (token !== null && (token.type === WHITESPACE || token.type === COMMENT)) {
+        token = getNextToken(++offset);
+    }
+
+    return offset;
+}
+
+function checkInteger(token, valueOffset, disallowSign, offset) {
+    if (!token) {
+        return 0;
+    }
+
+    var code = token.value.charCodeAt(valueOffset);
+
+    if (code === PLUSSIGN || code === HYPHENMINUS) {
+        if (disallowSign) {
+            // Number sign is not allowed
+            return 0;
+        }
+        valueOffset++;
+    }
+
+    for (; valueOffset < token.value.length; valueOffset++) {
+        if (!isDigit(token.value.charCodeAt(valueOffset))) {
+            // Integer is expected
+            return 0;
+        }
+    }
+
+    return offset + 1;
+}
+
+// ... <signed-integer>
+// ... ['+' | '-'] <signless-integer>
+function consumeB(token, offset_, getNextToken) {
+    var sign = false;
+    var offset = skipSC(token, offset_, getNextToken);
+
+    token = getNextToken(offset);
+
+    if (token === null) {
+        return offset_;
+    }
+
+    if (token.type !== NUMBER) {
+        if (isDelim(token, PLUSSIGN) || isDelim(token, HYPHENMINUS)) {
+            sign = true;
+            offset = skipSC(getNextToken(++offset), offset, getNextToken);
+            token = getNextToken(offset);
+
+            if (token === null && token.type !== NUMBER) {
+                return 0;
+            }
+        } else {
+            return offset_;
+        }
+    }
+
+    if (!sign) {
+        var code = token.value.charCodeAt(0);
+        if (code !== PLUSSIGN && code !== HYPHENMINUS) {
+            // Number sign is expected
+            return 0;
+        }
+    }
+
+    return checkInteger(token, sign ? 0 : 1, sign, offset);
+}
+
+// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
+module.exports = function anPlusB(token, getNextToken) {
+    /* eslint-disable brace-style*/
+    var offset = 0;
+
+    if (!token) {
+        return 0;
+    }
+
+    // <integer>
+    if (token.type === NUMBER) {
+        return checkInteger(token, 0, ALLOW_SIGN, offset); // b
+    }
+
+    // -n
+    // -n <signed-integer>
+    // -n ['+' | '-'] <signless-integer>
+    // -n- <signless-integer>
+    // <dashndashdigit-ident>
+    else if (token.type === IDENT && token.value.charCodeAt(0) === HYPHENMINUS) {
+        // expect 1st char is N
+        if (!cmpChar(token.value, 1, N)) {
+            return 0;
+        }
+
+        switch (token.value.length) {
+            // -n
+            // -n <signed-integer>
+            // -n ['+' | '-'] <signless-integer>
+            case 2:
+                return consumeB(getNextToken(++offset), offset, getNextToken);
+
+            // -n- <signless-integer>
+            case 3:
+                if (token.value.charCodeAt(2) !== HYPHENMINUS) {
+                    return 0;
+                }
+
+                offset = skipSC(getNextToken(++offset), offset, getNextToken);
+                token = getNextToken(offset);
+
+                return checkInteger(token, 0, DISALLOW_SIGN, offset);
+
+            // <dashndashdigit-ident>
+            default:
+                if (token.value.charCodeAt(2) !== HYPHENMINUS) {
+                    return 0;
+                }
+
+                return checkInteger(token, 3, DISALLOW_SIGN, offset);
+        }
+    }
+
+    // '+'? n
+    // '+'? n <signed-integer>
+    // '+'? n ['+' | '-'] <signless-integer>
+    // '+'? n- <signless-integer>
+    // '+'? <ndashdigit-ident>
+    else if (token.type === IDENT || (isDelim(token, PLUSSIGN) && getNextToken(offset + 1).type === IDENT)) {
+        // just ignore a plus
+        if (token.type !== IDENT) {
+            token = getNextToken(++offset);
+        }
+
+        if (token === null || !cmpChar(token.value, 0, N)) {
+            return 0;
+        }
+
+        switch (token.value.length) {
+            // '+'? n
+            // '+'? n <signed-integer>
+            // '+'? n ['+' | '-'] <signless-integer>
+            case 1:
+                return consumeB(getNextToken(++offset), offset, getNextToken);
+
+            // '+'? n- <signless-integer>
+            case 2:
+                if (token.value.charCodeAt(1) !== HYPHENMINUS) {
+                    return 0;
+                }
+
+                offset = skipSC(getNextToken(++offset), offset, getNextToken);
+                token = getNextToken(offset);
+
+                return checkInteger(token, 0, DISALLOW_SIGN, offset);
+
+            // '+'? <ndashdigit-ident>
+            default:
+                if (token.value.charCodeAt(1) !== HYPHENMINUS) {
+                    return 0;
+                }
+
+                return checkInteger(token, 2, DISALLOW_SIGN, offset);
+        }
+    }
+
+    // <ndashdigit-dimension>
+    // <ndash-dimension> <signless-integer>
+    // <n-dimension>
+    // <n-dimension> <signed-integer>
+    // <n-dimension> ['+' | '-'] <signless-integer>
+    else if (token.type === DIMENSION) {
+        var code = token.value.charCodeAt(0);
+        var sign = code === PLUSSIGN || code === HYPHENMINUS ? 1 : 0;
+
+        for (var i = sign; i < token.value.length; i++) {
+            if (!isDigit(token.value.charCodeAt(i))) {
+                break;
+            }
+        }
+
+        if (i === sign) {
+            // Integer is expected
+            return 0;
+        }
+
+        if (!cmpChar(token.value, i, N)) {
+            return 0;
+        }
+
+        // <n-dimension>
+        // <n-dimension> <signed-integer>
+        // <n-dimension> ['+' | '-'] <signless-integer>
+        if (i + 1 === token.value.length) {
+            return consumeB(getNextToken(++offset), offset, getNextToken);
+        } else {
+            if (token.value.charCodeAt(i + 1) !== HYPHENMINUS) {
+                return 0;
+            }
+
+            // <ndash-dimension> <signless-integer>
+            if (i + 2 === token.value.length) {
+                offset = skipSC(getNextToken(++offset), offset, getNextToken);
+                token = getNextToken(offset);
+
+                return checkInteger(token, 0, DISALLOW_SIGN, offset);
+            }
+            // <ndashdigit-dimension>
+            else {
+                return checkInteger(token, i + 2, DISALLOW_SIGN, offset);
+            }
+        }
+    }
+
+    return 0;
+};