This commit is contained in:
hatuhn
2019-09-13 09:45:04 +07:00
parent f14a34ba19
commit 558fb07261
16790 changed files with 0 additions and 1642370 deletions

80
node_modules/svgo/lib/svgo.js generated vendored
View File

@@ -1,80 +0,0 @@
'use strict';
/**
* SVGO is a Nodejs-based tool for optimizing SVG vector graphics files.
*
* @see https://github.com/svg/svgo
*
* @author Kir Belevich <kir@soulshine.in> (https://github.com/deepsweet)
* @copyright © 2012 Kir Belevich
* @license MIT https://raw.githubusercontent.com/svg/svgo/master/LICENSE
*/
var CONFIG = require('./svgo/config.js'),
SVG2JS = require('./svgo/svg2js.js'),
PLUGINS = require('./svgo/plugins.js'),
JSAPI = require('./svgo/jsAPI.js'),
JS2SVG = require('./svgo/js2svg.js');
var SVGO = module.exports = function(config) {
this.config = CONFIG(config);
};
SVGO.prototype.optimize = function(svgstr, callback) {
if (this.config.error) return callback(this.config);
var _this = this,
config = this.config,
maxPassCount = config.multipass ? 10 : 1,
counter = 0,
prevResultSize = Number.POSITIVE_INFINITY,
optimizeOnceCallback = function(svgjs) {
if (svgjs.error) {
callback(svgjs);
return;
}
if (++counter < maxPassCount && svgjs.data.length < prevResultSize) {
prevResultSize = svgjs.data.length;
_this._optimizeOnce(svgjs.data, optimizeOnceCallback);
} else {
callback(svgjs);
}
};
_this._optimizeOnce(svgstr, optimizeOnceCallback);
};
SVGO.prototype._optimizeOnce = function(svgstr, callback) {
var config = this.config;
SVG2JS(svgstr, function(svgjs) {
if (svgjs.error) {
callback(svgjs);
return;
}
svgjs = PLUGINS(svgjs, config.plugins);
callback(JS2SVG(svgjs, config.js2svg));
});
};
/**
* The factory that creates a content item with the helper methods.
*
* @param {Object} data which passed to jsAPI constructor
* @returns {JSAPI} content item
*/
SVGO.prototype.createContentItem = function(data) {
return new JSAPI(data);
};

581
node_modules/svgo/lib/svgo/coa.js generated vendored
View File

@@ -1,581 +0,0 @@
/* jshint quotmark: false */
'use strict';
require('colors');
var FS = require('fs'),
PATH = require('path'),
SVGO = require('../svgo.js'),
YAML = require('js-yaml'),
PKG = require('../../package.json'),
mkdirp = require('mkdirp'),
encodeSVGDatauri = require('./tools.js').encodeSVGDatauri,
decodeSVGDatauri = require('./tools.js').decodeSVGDatauri,
regSVGFile = /\.svg$/;
/**
* Command-Option-Argument.
*
* @see https://github.com/veged/coa
*/
module.exports = require('coa').Cmd()
.helpful()
.name(PKG.name)
.title(PKG.description)
.opt()
.name('version').title('Version')
.short('v').long('version')
.only()
.flag()
.act(function() {
// output the version to stdout instead of stderr if returned
process.stdout.write(PKG.version + '\n');
// coa will run `.toString` on the returned value and send it to stderr
return '';
})
.end()
.opt()
.name('input').title('Input file, "-" for STDIN')
.short('i').long('input')
.val(function(val) {
return val || this.reject("Option '--input' must have a value.");
})
.end()
.opt()
.name('string').title('Input SVG data string')
.short('s').long('string')
.end()
.opt()
.name('folder').title('Input folder, optimize and rewrite all *.svg files')
.short('f').long('folder')
.val(function(val) {
return val || this.reject("Option '--folder' must have a value.");
})
.end()
.opt()
.name('output').title('Output file or folder (by default the same as the input), "-" for STDOUT')
.short('o').long('output')
.val(function(val) {
return val || this.reject("Option '--output' must have a value.");
})
.end()
.opt()
.name('precision').title('Set number of digits in the fractional part, overrides plugins params')
.short('p').long('precision')
.val(function(val) {
return !isNaN(val) ? val : this.reject("Option '--precision' must be an integer number");
})
.end()
.opt()
.name('config').title('Config file or JSON string to extend or replace default')
.long('config')
.val(function(val) {
return val || this.reject("Option '--config' must have a value.");
})
.end()
.opt()
.name('disable').title('Disable plugin by name')
.long('disable')
.arr()
.val(function(val) {
return val || this.reject("Option '--disable' must have a value.");
})
.end()
.opt()
.name('enable').title('Enable plugin by name')
.long('enable')
.arr()
.val(function(val) {
return val || this.reject("Option '--enable' must have a value.");
})
.end()
.opt()
.name('datauri').title('Output as Data URI string (base64, URI encoded or unencoded)')
.long('datauri')
.val(function(val) {
return val || this.reject("Option '--datauri' must have one of the following values: 'base64', 'enc' or 'unenc'");
})
.end()
.opt()
.name('multipass').title('Enable multipass')
.long('multipass')
.flag()
.end()
.opt()
.name('pretty').title('Make SVG pretty printed')
.long('pretty')
.flag()
.end()
.opt()
.name('indent').title('Indent number when pretty printing SVGs')
.long('indent')
.val(function(val) {
return !isNaN(val) ? val : this.reject("Option '--indent' must be an integer number");
})
.end()
.opt()
.name('quiet').title('Only output error messages, not regular status messages')
.short('q').long('quiet')
.flag()
.end()
.opt()
.name('show-plugins').title('Show available plugins and exit')
.long('show-plugins')
.flag()
.end()
.arg()
.name('input').title('Alias to --input')
.end()
.arg()
.name('output').title('Alias to --output')
.end()
.act(function(opts, args) {
var input = args && args.input ? args.input : opts.input,
output = args && args.output ? args.output : opts.output,
config = {};
// --show-plugins
if (opts['show-plugins']) {
showAvailablePlugins();
process.exit(0);
}
// w/o anything
if (
(!input || input === '-') &&
!opts.string &&
!opts.stdin &&
!opts.folder &&
process.stdin.isTTY
) return this.usage();
// --config
if (opts.config) {
// string
if (opts.config.charAt(0) === '{') {
try {
config = JSON.parse(opts.config);
} catch (e) {
console.error("Error: Couldn't parse config JSON.");
console.error(String(e));
return;
}
// external file
} else {
var configPath = PATH.resolve(opts.config);
try {
// require() adds some weird output on YML files
config = JSON.parse(FS.readFileSync(configPath, 'utf8'));
} catch (err) {
if (err.code === 'ENOENT') {
console.error('Error: couldn\'t find config file \'' + opts.config + '\'.');
return;
} else if (err.code === 'EISDIR') {
console.error('Error: directory \'' + opts.config + '\' is not a config file.');
return;
}
config = YAML.safeLoad(FS.readFileSync(configPath, 'utf8'));
if (!config || Array.isArray(config)) {
console.error('Error: invalid config file \'' + opts.config + '\'.');
return;
}
}
}
}
// --quiet
if (opts.quiet) {
config.quiet = opts.quiet;
}
// --precision
if (opts.precision) {
config.floatPrecision = Math.max(0, parseInt(opts.precision));
}
// --disable
if (opts.disable) {
changePluginsState(opts.disable, false, config);
}
// --enable
if (opts.enable) {
changePluginsState(opts.enable, true, config);
}
// --multipass
if (opts.multipass) {
config.multipass = true;
}
// --pretty
if (opts.pretty) {
config.js2svg = config.js2svg || {};
config.js2svg.pretty = true;
if (opts.indent) {
config.js2svg.indent = parseInt(opts.indent, 10);
}
}
// --output
if (opts.output) {
config.output = opts.output;
}
// --folder
if (opts.folder) {
optimizeFolder(opts.folder, config, output);
return;
}
// --input
if (input) {
// STDIN
if (input === '-') {
var data = '';
process.stdin.pause();
process.stdin
.on('data', function(chunk) {
data += chunk;
})
.once('end', function() {
optimizeFromString(data, config, opts.datauri, input, output);
})
.resume();
// file
} else {
FS.readFile(input, 'utf8', function(err, data) {
if (err) {
if (err.code === 'EISDIR')
optimizeFolder(input, config, output);
else if (err.code === 'ENOENT')
console.error('Error: no such file or directory \'' + input + '\'.');
else
console.error(err);
return;
}
optimizeFromString(data, config, opts.datauri, input, output);
});
}
// --string
} else if (opts.string) {
opts.string = decodeSVGDatauri(opts.string);
optimizeFromString(opts.string, config, opts.datauri, input, output);
}
});
function optimizeFromString(svgstr, config, datauri, input, output) {
var startTime = Date.now(config),
time,
inBytes = Buffer.byteLength(svgstr, 'utf8'),
outBytes,
svgo = new SVGO(config);
svgo.optimize(svgstr, function(result) {
if (result.error) {
console.error(result.error);
return;
}
if (datauri) {
result.data = encodeSVGDatauri(result.data, datauri);
}
outBytes = Buffer.byteLength(result.data, 'utf8');
time = Date.now() - startTime;
// stdout
if (output === '-' || (!input || input === '-') && !output) {
process.stdout.write(result.data + '\n');
// file
} else {
// overwrite input file if there is no output
if (!output && input) {
output = input;
}
if (!config.quiet) {
console.log('\r');
}
saveFileAndPrintInfo(config, result.data, output, inBytes, outBytes, time);
}
});
}
function saveFileAndPrintInfo(config, data, path, inBytes, outBytes, time) {
FS.writeFile(path, data, 'utf8', function() {
if (config.quiet) {
return;
}
// print time info
printTimeInfo(time);
// print optimization profit info
printProfitInfo(inBytes, outBytes);
});
}
function printTimeInfo(time) {
console.log('Done in ' + time + ' ms!');
}
function printProfitInfo(inBytes, outBytes) {
var profitPercents = 100 - outBytes * 100 / inBytes;
console.log(
(Math.round((inBytes / 1024) * 1000) / 1000) + ' KiB' +
(profitPercents < 0 ? ' + ' : ' - ') +
String(Math.abs((Math.round(profitPercents * 10) / 10)) + '%').green + ' = ' +
(Math.round((outBytes / 1024) * 1000) / 1000) + ' KiB\n'
);
}
/**
* Change plugins state by names array.
*
* @param {Array} names plugins names
* @param {Boolean} state active state
* @param {Object} config original config
* @return {Object} changed config
*/
function changePluginsState(names, state, config) {
// extend config
if (config.plugins) {
names.forEach(function(name) {
var matched,
key;
config.plugins.forEach(function(plugin) {
// get plugin name
if (typeof plugin === 'object') {
key = Object.keys(plugin)[0];
} else {
key = plugin;
}
// if there is such a plugin name
if (key === name) {
// don't replace plugin's params with true
if (typeof plugin[key] !== 'object' || !state) {
plugin[key] = state;
}
// mark it as matched
matched = true;
}
});
// if not matched and current config is not full
if (!matched && !config.full) {
var obj = {};
obj[name] = state;
// push new plugin Object
config.plugins.push(obj);
matched = true;
}
});
// just push
} else {
config.plugins = [];
names.forEach(function(name) {
var obj = {};
obj[name] = state;
config.plugins.push(obj);
});
}
return config;
}
function optimizeFolder(dir, config, output) {
var svgo = new SVGO(config);
if (!config.quiet) {
console.log('Processing directory \'' + dir + '\':\n');
}
// absoluted folder path
var path = PATH.resolve(dir);
// list folder content
FS.readdir(path, function(err, files) {
if (err) {
console.error(err);
return;
}
if (!files.length) {
console.log('Directory \'' + dir + '\' is empty.');
return;
}
var i = 0,
found = false;
function optimizeFile(file) {
// absoluted file path
var filepath = PATH.resolve(path, file);
var outfilepath = output ? PATH.resolve(output, file) : filepath;
// check if file name matches *.svg
if (regSVGFile.test(filepath)) {
found = true;
FS.readFile(filepath, 'utf8', function(err, data) {
if (err) {
console.error(err);
return;
}
var startTime = Date.now(),
time,
inBytes = Buffer.byteLength(data, 'utf8'),
outBytes;
svgo.optimize(data, function(result) {
if (result.error) {
console.error(result.error);
return;
}
outBytes = Buffer.byteLength(result.data, 'utf8');
time = Date.now() - startTime;
writeOutput();
function writeOutput() {
FS.writeFile(outfilepath, result.data, 'utf8', report);
}
function report(err) {
if (err) {
if (err.code === 'ENOENT') {
mkdirp(output, writeOutput);
return;
} else if (err.code === 'ENOTDIR') {
console.error('Error: output \'' + output + '\' is not a directory.');
return;
}
console.error(err);
return;
}
if (!config.quiet) {
console.log(file + ':');
// print time info
printTimeInfo(time);
// print optimization profit info
printProfitInfo(inBytes, outBytes);
}
//move on to the next file
if (++i < files.length) {
optimizeFile(files[i]);
}
}
});
});
}
//move on to the next file
else if (++i < files.length) {
optimizeFile(files[i]);
} else if (!found) {
console.log('No SVG files have been found.');
}
}
optimizeFile(files[i]);
});
}
var showAvailablePlugins = function () {
var svgo = new SVGO(),
// Flatten an array of plugins grouped per type and sort alphabetically
list = Array.prototype.concat.apply([], svgo.config.plugins).sort(function(a, b) {
return a.name > b.name ? 1 : -1;
});
console.log('Currently available plugins:');
list.forEach(function (plugin) {
console.log(' [ ' + plugin.name.green + ' ] ' + plugin.description);
});
//console.log(JSON.stringify(svgo, null, 4));
};

212
node_modules/svgo/lib/svgo/config.js generated vendored
View File

@@ -1,212 +0,0 @@
'use strict';
var FS = require('fs');
var yaml = require('js-yaml');
var EXTEND = require('whet.extend');
/**
* Read and/or extend/replace default config file,
* prepare and optimize plugins array.
*
* @param {Object} [config] input config
* @return {Object} output config
*/
module.exports = function(config) {
var defaults;
config = typeof config == 'object' && config || {};
if (config.plugins && !Array.isArray(config.plugins)) {
return { error: 'Error: Invalid plugins list. Provided \'plugins\' in config should be an array.' };
}
if (config.full) {
defaults = config;
if (Array.isArray(defaults.plugins)) {
defaults.plugins = preparePluginsArray(defaults.plugins);
}
} else {
defaults = EXTEND({}, yaml.safeLoad(FS.readFileSync(__dirname + '/../../.svgo.yml', 'utf8')));
defaults.plugins = preparePluginsArray(defaults.plugins);
defaults = extendConfig(defaults, config);
}
if ('floatPrecision' in config && Array.isArray(defaults.plugins)) {
defaults.plugins.forEach(function(plugin) {
if (plugin.params && ('floatPrecision' in plugin.params)) {
// Don't touch default plugin params
plugin.params = EXTEND({}, plugin.params, { floatPrecision: config.floatPrecision });
}
});
}
if (Array.isArray(defaults.plugins)) {
defaults.plugins = optimizePluginsArray(defaults.plugins);
}
return defaults;
};
/**
* Require() all plugins in array.
*
* @param {Array} plugins input plugins array
* @return {Array} input plugins array of arrays
*/
function preparePluginsArray(plugins) {
var plugin,
key;
return plugins.map(function(item) {
// {}
if (typeof item === 'object') {
key = Object.keys(item)[0];
// custom
if (typeof item[key] === 'object' && item[key].fn && typeof item[key].fn === 'function') {
plugin = setupCustomPlugin(key, item[key]);
} else {
plugin = EXTEND({}, require('../../plugins/' + key));
// name: {}
if (typeof item[key] === 'object') {
plugin.params = EXTEND({}, plugin.params || {}, item[key]);
plugin.active = true;
// name: false
} else if (item[key] === false) {
plugin.active = false;
// name: true
} else if (item[key] === true) {
plugin.active = true;
}
plugin.name = key;
}
// name
} else {
plugin = EXTEND({}, require('../../plugins/' + item));
plugin.name = item;
}
return plugin;
});
}
/**
* Extend plugins with the custom config object.
*
* @param {Array} plugins input plugins
* @param {Object} config config
* @return {Array} output plugins
*/
function extendConfig(defaults, config) {
var key;
// plugins
if (config.plugins) {
config.plugins.forEach(function(item) {
// {}
if (typeof item === 'object') {
key = Object.keys(item)[0];
// custom
if (typeof item[key] === 'object' && item[key].fn && typeof item[key].fn === 'function') {
defaults.plugins.push(setupCustomPlugin(key, item[key]));
} else {
defaults.plugins.forEach(function(plugin) {
if (plugin.name === key) {
// name: {}
if (typeof item[key] === 'object') {
plugin.params = EXTEND({}, plugin.params || {}, item[key]);
plugin.active = true;
// name: false
} else if (item[key] === false) {
plugin.active = false;
// name: true
} else if (item[key] === true) {
plugin.active = true;
}
}
});
}
}
});
}
defaults.multipass = config.multipass;
// svg2js
if (config.svg2js) {
defaults.svg2js = config.svg2js;
}
// js2svg
if (config.js2svg) {
defaults.js2svg = config.js2svg;
}
return defaults;
}
/**
* Setup and enable a custom plugin
*
* @param {String} plugin name
* @param {Object} custom plugin
* @return {Array} enabled plugin
*/
function setupCustomPlugin(name, plugin) {
plugin.active = true;
plugin.params = EXTEND({}, plugin.params || {});
plugin.name = name;
return plugin;
}
/**
* Try to group sequential elements of plugins array.
*
* @param {Object} plugins input plugins
* @return {Array} output plugins
*/
function optimizePluginsArray(plugins) {
var prev;
return plugins.reduce(function(plugins, item) {
if (prev && item.type == prev[0].type) {
prev.push(item);
} else {
plugins.push(prev = [item]);
}
return plugins;
}, []);
}

352
node_modules/svgo/lib/svgo/js2svg.js generated vendored
View File

@@ -1,352 +0,0 @@
'use strict';
var EOL = require('os').EOL,
EXTEND = require('whet.extend'),
textElem = require('../../plugins/_collections.js').elemsGroups.textContent.concat('title');
var defaults = {
doctypeStart: '<!DOCTYPE',
doctypeEnd: '>',
procInstStart: '<?',
procInstEnd: '?>',
tagOpenStart: '<',
tagOpenEnd: '>',
tagCloseStart: '</',
tagCloseEnd: '>',
tagShortStart: '<',
tagShortEnd: '/>',
attrStart: '="',
attrEnd: '"',
commentStart: '<!--',
commentEnd: '-->',
cdataStart: '<![CDATA[',
cdataEnd: ']]>',
textStart: '',
textEnd: '',
indent: 4,
regEntities: /[&'"<>]/g,
regValEntities: /[&"<>]/g,
encodeEntity: encodeEntity,
pretty: false,
useShortTags: true
};
var entities = {
'&': '&amp;',
'\'': '&apos;',
'"': '&quot;',
'>': '&gt;',
'<': '&lt;',
};
/**
* Convert SVG-as-JS object to SVG (XML) string.
*
* @param {Object} data input data
* @param {Object} config config
*
* @return {Object} output data
*/
module.exports = function(data, config) {
return new JS2SVG(config).convert(data);
};
function JS2SVG(config) {
if (config) {
this.config = EXTEND(true, {}, defaults, config);
} else {
this.config = defaults;
}
var indent = this.config.indent;
if (typeof indent == 'number' && !isNaN(indent)) {
this.config.indent = '';
for (var i = indent; i-- > 0;) this.config.indent += ' ';
} else if (typeof indent != 'string') {
this.config.indent = ' ';
}
if (this.config.pretty) {
this.config.doctypeEnd += EOL;
this.config.procInstEnd += EOL;
this.config.commentEnd += EOL;
this.config.cdataEnd += EOL;
this.config.tagShortEnd += EOL;
this.config.tagOpenEnd += EOL;
this.config.tagCloseEnd += EOL;
this.config.textEnd += EOL;
}
this.indentLevel = 0;
this.textContext = null;
}
function encodeEntity(char) {
return entities[char];
}
/**
* Start conversion.
*
* @param {Object} data input data
*
* @return {String}
*/
JS2SVG.prototype.convert = function(data) {
var svg = '';
if (data.content) {
this.indentLevel++;
data.content.forEach(function(item) {
if (item.elem) {
svg += this.createElem(item);
} else if (item.text) {
svg += this.createText(item.text);
} else if (item.doctype) {
svg += this.createDoctype(item.doctype);
} else if (item.processinginstruction) {
svg += this.createProcInst(item.processinginstruction);
} else if (item.comment) {
svg += this.createComment(item.comment);
} else if (item.cdata) {
svg += this.createCDATA(item.cdata);
}
}, this);
}
this.indentLevel--;
return {
data: svg,
info: {
width: this.width,
height: this.height
}
};
};
/**
* Create indent string in accordance with the current node level.
*
* @return {String}
*/
JS2SVG.prototype.createIndent = function() {
var indent = '';
if (this.config.pretty && !this.textContext) {
for (var i = 1; i < this.indentLevel; i++) {
indent += this.config.indent;
}
}
return indent;
};
/**
* Create doctype tag.
*
* @param {String} doctype doctype body string
*
* @return {String}
*/
JS2SVG.prototype.createDoctype = function(doctype) {
return this.config.doctypeStart +
doctype +
this.config.doctypeEnd;
};
/**
* Create XML Processing Instruction tag.
*
* @param {Object} instruction instruction object
*
* @return {String}
*/
JS2SVG.prototype.createProcInst = function(instruction) {
return this.config.procInstStart +
instruction.name +
' ' +
instruction.body +
this.config.procInstEnd;
};
/**
* Create comment tag.
*
* @param {String} comment comment body
*
* @return {String}
*/
JS2SVG.prototype.createComment = function(comment) {
return this.config.commentStart +
comment +
this.config.commentEnd;
};
/**
* Create CDATA section.
*
* @param {String} cdata CDATA body
*
* @return {String}
*/
JS2SVG.prototype.createCDATA = function(cdata) {
return this.createIndent() +
this.config.cdataStart +
cdata +
this.config.cdataEnd;
};
/**
* Create element tag.
*
* @param {Object} data element object
*
* @return {String}
*/
JS2SVG.prototype.createElem = function(data) {
// beautiful injection for obtaining SVG information :)
if (
data.isElem('svg') &&
data.hasAttr('width') &&
data.hasAttr('height')
) {
this.width = data.attr('width').value;
this.height = data.attr('height').value;
}
// empty element and short tag
if (data.isEmpty()) {
if (this.config.useShortTags) {
return this.createIndent() +
this.config.tagShortStart +
data.elem +
this.createAttrs(data) +
this.config.tagShortEnd;
} else {
return this.createIndent() +
this.config.tagShortStart +
data.elem +
this.createAttrs(data) +
this.config.tagOpenEnd +
this.config.tagCloseStart +
data.elem +
this.config.tagCloseEnd;
}
// non-empty element
} else {
var tagOpenStart = this.config.tagOpenStart,
tagOpenEnd = this.config.tagOpenEnd,
tagCloseStart = this.config.tagCloseStart,
tagCloseEnd = this.config.tagCloseEnd,
openIndent = this.createIndent(),
textIndent = '',
processedData = '',
dataEnd = '';
if (this.textContext) {
tagOpenStart = defaults.tagOpenStart;
tagOpenEnd = defaults.tagOpenEnd;
tagCloseStart = defaults.tagCloseStart;
tagCloseEnd = defaults.tagCloseEnd;
openIndent = '';
} else if (data.isElem(textElem)) {
if (this.config.pretty) {
textIndent += openIndent + this.config.indent;
}
this.textContext = data;
}
processedData += this.convert(data).data;
if (this.textContext == data) {
this.textContext = null;
if (this.config.pretty) dataEnd = EOL;
}
return openIndent +
tagOpenStart +
data.elem +
this.createAttrs(data) +
tagOpenEnd +
textIndent +
processedData +
dataEnd +
this.createIndent() +
tagCloseStart +
data.elem +
tagCloseEnd;
}
};
/**
* Create element attributes.
*
* @param {Object} elem attributes object
*
* @return {String}
*/
JS2SVG.prototype.createAttrs = function(elem) {
var attrs = '';
elem.eachAttr(function(attr) {
if (attr.value !== undefined) {
attrs += ' ' +
attr.name +
this.config.attrStart +
String(attr.value).replace(this.config.regValEntities, this.config.encodeEntity) +
this.config.attrEnd;
}
else {
attrs += ' ' +
attr.name;
}
}, this);
return attrs;
};
/**
* Create text node.
*
* @param {String} text text
*
* @return {String}
*/
JS2SVG.prototype.createText = function(text) {
return this.createIndent() +
this.config.textStart +
text.replace(this.config.regEntities, this.config.encodeEntity) +
(this.textContext ? '' : this.config.textEnd);
};

298
node_modules/svgo/lib/svgo/jsAPI.js generated vendored
View File

@@ -1,298 +0,0 @@
'use strict';
var EXTEND = require('whet.extend');
var JSAPI = module.exports = function(data, parentNode) {
EXTEND(this, data);
if (parentNode) {
Object.defineProperty(this, 'parentNode', {
writable: true,
value: parentNode
});
}
};
/**
* Perform a deep clone of this node.
*
* @return {Object} element
*/
JSAPI.prototype.clone = function() {
var node = this;
var nodeData = {};
Object.keys(node).forEach(function(key) {
if (key !== 'content') {
nodeData[key] = node[key];
}
});
// Deep-clone node data
// This is still faster than using EXTEND(true…)
nodeData = JSON.parse(JSON.stringify(nodeData));
// parentNode gets set to a proper object by the parent clone,
// but it needs to be true/false now to do the right thing
// in the constructor.
var clonedNode = new JSAPI(nodeData, !!node.parentNode);
if (node.content) {
clonedNode.content = node.content.map(function(childNode) {
var clonedChild = childNode.clone();
clonedChild.parentNode = clonedNode;
return clonedChild;
});
}
return clonedNode;
};
/**
* Determine if item is an element
* (any, with a specific name or in a names array).
*
* @param {String|Array} [param] element name or names arrays
* @return {Boolean}
*/
JSAPI.prototype.isElem = function(param) {
if (!param) return !!this.elem;
if (Array.isArray(param)) return !!this.elem && (param.indexOf(this.elem) > -1);
return !!this.elem && this.elem === param;
};
/**
* Renames an element
*
* @param {String} name new element name
* @return {Object} element
*/
JSAPI.prototype.renameElem = function(name) {
if (name && typeof name === 'string')
this.elem = this.local = name;
return this;
};
/**
* Determine if element is empty.
*
* @return {Boolean}
*/
JSAPI.prototype.isEmpty = function() {
return !this.content || !this.content.length;
};
/**
* Changes content by removing elements and/or adding new elements.
*
* @param {Number} start Index at which to start changing the content.
* @param {Number} n Number of elements to remove.
* @param {Array|Object} [insertion] Elements to add to the content.
* @return {Array} Removed elements.
*/
JSAPI.prototype.spliceContent = function(start, n, insertion) {
if (arguments.length < 2) return [];
if (!Array.isArray(insertion))
insertion = Array.apply(null, arguments).slice(2);
insertion.forEach(function(inner) { inner.parentNode = this }, this);
return this.content.splice.apply(this.content, [start, n].concat(insertion));
};
/**
* Determine if element has an attribute
* (any, or by name or by name + value).
*
* @param {String} [name] attribute name
* @param {String} [val] attribute value (will be toString()'ed)
* @return {Boolean}
*/
JSAPI.prototype.hasAttr = function(name, val) {
if (!this.attrs || !Object.keys(this.attrs).length) return false;
if (!arguments.length) return !!this.attrs;
if (val !== undefined) return !!this.attrs[name] && this.attrs[name].value === val.toString();
return !!this.attrs[name];
};
/**
* Determine if element has an attribute by local name
* (any, or by name or by name + value).
*
* @param {String} [localName] local attribute name
* @param {Number|String|RegExp|Function} [val] attribute value (will be toString()'ed or executed, otherwise ignored)
* @return {Boolean}
*/
JSAPI.prototype.hasAttrLocal = function(localName, val) {
if (!this.attrs || !Object.keys(this.attrs).length) return false;
if (!arguments.length) return !!this.attrs;
var callback;
switch (val != null && val.constructor && val.constructor.name) {
case 'Number': // same as String
case 'String': callback = stringValueTest; break;
case 'RegExp': callback = regexpValueTest; break;
case 'Function': callback = funcValueTest; break;
default: callback = nameTest;
}
return this.someAttr(callback);
function nameTest(attr) {
return attr.local === localName;
}
function stringValueTest(attr) {
return attr.local === localName && val == attr.value;
}
function regexpValueTest(attr) {
return attr.local === localName && val.test(attr.value);
}
function funcValueTest(attr) {
return attr.local === localName && val(attr.value);
}
};
/**
* Get a specific attribute from an element
* (by name or name + value).
*
* @param {String} name attribute name
* @param {String} [val] attribute value (will be toString()'ed)
* @return {Object|Undefined}
*/
JSAPI.prototype.attr = function(name, val) {
if (!this.hasAttr() || !arguments.length) return undefined;
if (val !== undefined) return this.hasAttr(name, val) ? this.attrs[name] : undefined;
return this.attrs[name];
};
/**
* Get computed attribute value from an element
*
* @param {String} name attribute name
* @return {Object|Undefined}
*/
JSAPI.prototype.computedAttr = function(name, val) {
/* jshint eqnull: true */
if (!arguments.length) return;
for (var elem = this; elem && (!elem.hasAttr(name) || !elem.attr(name).value); elem = elem.parentNode);
if (val != null) {
return elem ? elem.hasAttr(name, val) : false;
} else if (elem && elem.hasAttr(name)) {
return elem.attrs[name].value;
}
};
/**
* Remove a specific attribute.
*
* @param {String|Array} name attribute name
* @param {String} [val] attribute value
* @return {Boolean}
*/
JSAPI.prototype.removeAttr = function(name, val, recursive) {
if (!arguments.length) return false;
if (Array.isArray(name)) name.forEach(this.removeAttr, this);
if (!this.hasAttr(name)) return false;
if (!recursive && val && this.attrs[name].value !== val) return false;
delete this.attrs[name];
if (!Object.keys(this.attrs).length) delete this.attrs;
return true;
};
/**
* Add attribute.
*
* @param {Object} [attr={}] attribute object
* @return {Object|Boolean} created attribute or false if no attr was passed in
*/
JSAPI.prototype.addAttr = function(attr) {
attr = attr || {};
if (attr.name === undefined ||
attr.prefix === undefined ||
attr.local === undefined
) return false;
this.attrs = this.attrs || {};
this.attrs[attr.name] = attr;
return this.attrs[attr.name];
};
/**
* Iterates over all attributes.
*
* @param {Function} callback callback
* @param {Object} [context] callback context
* @return {Boolean} false if there are no any attributes
*/
JSAPI.prototype.eachAttr = function(callback, context) {
if (!this.hasAttr()) return false;
for (var name in this.attrs) {
callback.call(context, this.attrs[name]);
}
return true;
};
/**
* Tests whether some attribute passes the test.
*
* @param {Function} callback callback
* @param {Object} [context] callback context
* @return {Boolean} false if there are no any attributes
*/
JSAPI.prototype.someAttr = function(callback, context) {
if (!this.hasAttr()) return false;
for (var name in this.attrs) {
if (callback.call(context, this.attrs[name])) return true;
}
return false;
};

View File

@@ -1,98 +0,0 @@
'use strict';
/**
* Plugins engine.
*
* @module plugins
*
* @param {Object} data input data
* @param {Object} plugins plugins object from config
* @return {Object} output data
*/
module.exports = function(data, plugins) {
plugins.forEach(function(group) {
switch(group[0].type) {
case 'perItem':
data = perItem(data, group);
break;
case 'perItemReverse':
data = perItem(data, group, true);
break;
case 'full':
data = full(data, group);
break;
}
});
return data;
};
/**
* Direct or reverse per-item loop.
*
* @param {Object} data input data
* @param {Array} plugins plugins list to process
* @param {Boolean} [reverse] reverse pass?
* @return {Object} output data
*/
function perItem(data, plugins, reverse) {
function monkeys(items) {
items.content = items.content.filter(function(item) {
// reverse pass
if (reverse && item.content) {
monkeys(item);
}
// main filter
var filter = true;
for (var i = 0; filter && i < plugins.length; i++) {
var plugin = plugins[i];
if (plugin.active && plugin.fn(item, plugin.params) === false) {
filter = false;
}
}
// direct pass
if (!reverse && item.content) {
monkeys(item);
}
return filter;
});
return items;
}
return monkeys(data);
}
/**
* "Full" plugins.
*
* @param {Object} data input data
* @param {Array} plugins plugins list to process
* @return {Object} output data
*/
function full(data, plugins) {
plugins.forEach(function(plugin) {
if (plugin.active) {
data = plugin.fn(data, plugin.params);
}
});
return data;
}

187
node_modules/svgo/lib/svgo/svg2js.js generated vendored
View File

@@ -1,187 +0,0 @@
'use strict';
var SAX = require('sax'),
JSAPI = require('./jsAPI.js'),
entityDeclaration = /<!ENTITY\s+(\S+)\s+(?:'([^\']+)'|"([^\"]+)")\s*>/g;
var config = {
strict: true,
trim: false,
normalize: true,
lowercase: true,
xmlns: true,
position: true
};
/**
* Convert SVG (XML) string to SVG-as-JS object.
*
* @param {String} data input data
* @param {Function} callback
*/
module.exports = function(data, callback) {
var sax = SAX.parser(config.strict, config),
root = new JSAPI({ elem: '#document' }),
current = root,
stack = [root],
textContext = null,
parsingError = false;
function pushToContent(content) {
content = new JSAPI(content, current);
(current.content = current.content || []).push(content);
return content;
}
sax.ondoctype = function(doctype) {
pushToContent({
doctype: doctype
});
var subsetStart = doctype.indexOf('['),
entityMatch;
if (subsetStart >= 0) {
entityDeclaration.lastIndex = subsetStart;
while ((entityMatch = entityDeclaration.exec(data)) != null) {
sax.ENTITIES[entityMatch[1]] = entityMatch[2] || entityMatch[3];
}
}
};
sax.onprocessinginstruction = function(data) {
pushToContent({
processinginstruction: data
});
};
sax.oncomment = function(comment) {
pushToContent({
comment: comment.trim()
});
};
sax.oncdata = function(cdata) {
pushToContent({
cdata: cdata
});
};
sax.onopentag = function(data) {
var elem = {
elem: data.name,
prefix: data.prefix,
local: data.local
};
if (Object.keys(data.attributes).length) {
elem.attrs = {};
for (var name in data.attributes) {
elem.attrs[name] = {
name: name,
value: data.attributes[name].value,
prefix: data.attributes[name].prefix,
local: data.attributes[name].local
};
}
}
elem = pushToContent(elem);
current = elem;
// Save info about <text> tag to prevent trimming of meaningful whitespace
if (data.name == 'text' && !data.prefix) {
textContext = current;
}
stack.push(elem);
};
sax.ontext = function(text) {
if (/\S/.test(text) || textContext) {
if (!textContext)
text = text.trim();
pushToContent({
text: text
});
}
};
sax.onclosetag = function() {
var last = stack.pop();
// Trim text inside <text> tag.
if (last == textContext) {
trim(textContext);
textContext = null;
}
current = stack[stack.length - 1];
};
sax.onerror = function(e) {
e.message = 'Error in parsing SVG: ' + e.message;
if (e.message.indexOf('Unexpected end') < 0) {
throw e;
}
};
sax.onend = function() {
if (!this.error) {
callback(root);
} else {
callback({ error: this.error.message });
}
};
try {
sax.write(data);
} catch (e) {
callback({ error: e.message });
parsingError = true;
}
if (!parsingError) sax.close();
function trim(elem) {
if (!elem.content) return elem;
var start = elem.content[0],
end = elem.content[elem.content.length - 1];
while (start && start.content && !start.text) start = start.content[0];
if (start && start.text) start.text = start.text.replace(/^\s+/, '');
while (end && end.content && !end.text) end = end.content[end.content.length - 1];
if (end && end.text) end.text = end.text.replace(/\s+$/, '');
return elem;
}
};

147
node_modules/svgo/lib/svgo/tools.js generated vendored
View File

@@ -1,147 +0,0 @@
'use strict';
/**
* Encode plain SVG data string into Data URI string.
*
* @param {String} str input string
* @param {String} type Data URI type
* @return {String} output string
*/
exports.encodeSVGDatauri = function(str, type) {
var prefix = 'data:image/svg+xml';
// base64
if (!type || type === 'base64') {
prefix += ';base64,';
str = prefix + new Buffer(str).toString('base64');
// URI encoded
} else if (type === 'enc') {
str = prefix + ',' + encodeURIComponent(str);
// unencoded
} else if (type === 'unenc') {
str = prefix + ',' + str;
}
return str;
};
/**
* Decode SVG Data URI string into plain SVG string.
*
* @param {string} str input string
* @return {String} output string
*/
exports.decodeSVGDatauri = function(str) {
var regexp = /data:image\/svg\+xml(;charset=[^;,]*)?(;base64)?,(.*)/;
var match = regexp.exec(str);
// plain string
if (!match) return str;
var data = match[3];
// base64
if (match[2]) {
str = new Buffer(data, 'base64').toString('utf8');
// URI encoded
} else if (data.charAt(0) === '%') {
str = decodeURIComponent(data);
// unencoded
} else if (data.charAt(0) === '<') {
str = data;
}
return str;
};
exports.intersectArrays = function(a, b) {
return a.filter(function(n) {
return b.indexOf(n) > -1;
});
};
exports.cleanupOutData = function(data, params) {
var str = '',
delimiter,
prev;
data.forEach(function(item, i) {
// space delimiter by default
delimiter = ' ';
// no extra space in front of first number
if (i === 0) {
delimiter = '';
}
// remove floating-point numbers leading zeros
// 0.5 → .5
// -0.5 → -.5
if (params.leadingZero) {
item = removeLeadingZero(item);
}
// no extra space in front of negative number or
// in front of a floating number if a previous number is floating too
if (
params.negativeExtraSpace &&
(item < 0 ||
(String(item).charCodeAt(0) == 46 && prev % 1 !== 0)
)
) {
delimiter = '';
}
// save prev item value
prev = item;
str += delimiter + item;
});
return str;
};
/**
* Remove floating-point numbers leading zero.
*
* @example
* 0.5 → .5
*
* @example
* -0.5 → -.5
*
* @param {Float} num input number
*
* @return {String} output number as string
*/
var removeLeadingZero = exports.removeLeadingZero = function(num) {
var strNum = num.toString();
if (0 < num && num < 1 && strNum.charCodeAt(0) == 48) {
strNum = strNum.slice(1);
} else if (-1 < num && num < 0 && strNum.charCodeAt(1) == 48) {
strNum = strNum.charAt(0) + strNum.slice(2);
}
return strNum;
};