progress on migrating to heex templates and font-icons
This commit is contained in:
parent
d43daafdb7
commit
3eff955672
21793 changed files with 2161968 additions and 16895 deletions
assets_old/node_modules/svgo
.svgo.ymlCHANGELOG.mdLICENSEMakefileREADME.mdREADME.ru.md
bin
lib
node_modules
package.jsonplugins
_collections.js_path.js_transforms.jsaddAttributesToSVGElement.jsaddClassesToSVGElement.jscleanupAttrs.jscleanupEnableBackground.jscleanupIDs.jscleanupListOfValues.jscleanupNumericValues.jscollapseGroups.jsconvertColors.jsconvertEllipseToCircle.jsconvertPathData.jsconvertShapeToPath.jsconvertStyleToAttrs.jsconvertTransform.jsinlineStyles.jsmergePaths.jsminifyStyles.jsmoveElemsAttrsToGroup.jsmoveGroupAttrsToElems.jsprefixIds.jsremoveAttributesBySelector.jsremoveAttrs.jsremoveComments.jsremoveDesc.jsremoveDimensions.jsremoveDoctype.jsremoveEditorsNSData.jsremoveElementsByAttr.jsremoveEmptyAttrs.jsremoveEmptyContainers.jsremoveEmptyText.jsremoveHiddenElems.jsremoveMetadata.jsremoveNonInheritableGroupAttrs.jsremoveOffCanvasPaths.jsremoveRasterImages.jsremoveScriptElement.jsremoveStyleElement.jsremoveTitle.jsremoveUnknownsAndDefaults.jsremoveUnusedNS.jsremoveUselessDefs.jsremoveUselessStrokeAndFill.jsremoveViewBox.jsremoveXMLNS.jsremoveXMLProcInst.jsreusePaths.jssortAttrs.jssortDefsChildren.js
75
assets_old/node_modules/svgo/.svgo.yml
generated
vendored
Normal file
75
assets_old/node_modules/svgo/.svgo.yml
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
# replace default config
|
||||
|
||||
# multipass: true
|
||||
# full: true
|
||||
|
||||
plugins:
|
||||
|
||||
# - name
|
||||
#
|
||||
# or:
|
||||
# - name: false
|
||||
# - name: true
|
||||
#
|
||||
# or:
|
||||
# - name:
|
||||
# param1: 1
|
||||
# param2: 2
|
||||
|
||||
- removeDoctype
|
||||
- removeXMLProcInst
|
||||
- removeComments
|
||||
- removeMetadata
|
||||
- removeXMLNS
|
||||
- removeEditorsNSData
|
||||
- cleanupAttrs
|
||||
- inlineStyles
|
||||
- minifyStyles
|
||||
- convertStyleToAttrs
|
||||
- cleanupIDs
|
||||
- prefixIds
|
||||
- removeRasterImages
|
||||
- removeUselessDefs
|
||||
- cleanupNumericValues
|
||||
- cleanupListOfValues
|
||||
- convertColors
|
||||
- removeUnknownsAndDefaults
|
||||
- removeNonInheritableGroupAttrs
|
||||
- removeUselessStrokeAndFill
|
||||
- removeViewBox
|
||||
- cleanupEnableBackground
|
||||
- removeHiddenElems
|
||||
- removeEmptyText
|
||||
- convertShapeToPath
|
||||
- convertEllipseToCircle
|
||||
- moveElemsAttrsToGroup
|
||||
- moveGroupAttrsToElems
|
||||
- collapseGroups
|
||||
- convertPathData
|
||||
- convertTransform
|
||||
- removeEmptyAttrs
|
||||
- removeEmptyContainers
|
||||
- mergePaths
|
||||
- removeUnusedNS
|
||||
- sortAttrs
|
||||
- sortDefsChildren
|
||||
- removeTitle
|
||||
- removeDesc
|
||||
- removeDimensions
|
||||
- removeAttrs
|
||||
- removeAttributesBySelector
|
||||
- removeElementsByAttr
|
||||
- addClassesToSVGElement
|
||||
- removeStyleElement
|
||||
- removeScriptElement
|
||||
- addAttributesToSVGElement
|
||||
- removeOffCanvasPaths
|
||||
- reusePaths
|
||||
|
||||
# configure the indent (default 4 spaces) used by `--pretty` here:
|
||||
#
|
||||
# @see https://github.com/svg/svgo/blob/master/lib/svgo/js2svg.js#L6 for more config options
|
||||
#
|
||||
# js2svg:
|
||||
# pretty: true
|
||||
# indent: ' '
|
533
assets_old/node_modules/svgo/CHANGELOG.md
generated
vendored
Normal file
533
assets_old/node_modules/svgo/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,533 @@
|
|||
### [ [>](https://github.com/svg/svgo/tree/v1.3.2) ] 1.3.2 / 30.10.2019
|
||||
* Fixed TypeError: Cannot set property 'multipassCount' of undefined
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.3.1) ] 1.3.1 / 29.10.2019
|
||||
* Updated CSSO version to 4.0.2 fixing the issue with empty semicolons ";;" in styles (thanks to @strarsis and @lahmatiy).
|
||||
* `prefixIds` plugin now runs only once with `--multipass` option (by @strarsis).
|
||||
* `cleanupIDs` plugin is prevented from producing a preserved ID, including one which matches a preserved prefix, when minifying (by @thomsj).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.3.0) ] 1.3.0 / 14.07.2019
|
||||
* Custom plugins now can be loaded from external js through `path` plugin param.
|
||||
* New plugin `convertEllipseToCircle` to convert ellipse with equal radius measures to circle (by @tigt).
|
||||
* New plugin `sortDefsChildren` for improved compression (by @davidleston).
|
||||
* SVGO now removes unnecessary spaces after `arcto` path command flags.
|
||||
* `removeDimensions` plugin now adds `viewBox` if it's missing (by @adipascu).
|
||||
* Fixed `removeUnusedNS` not counting attributes in `<svg>` tag itself.
|
||||
* Fixed an issue with incorrect processing multiple images (by @cyberalien).
|
||||
* Fixed an error with incorrect converting multiple segmented curve to an arc.
|
||||
* Fixed an error with matrix decomposition in `convertTransform` due to rounding error leading to illegal value.
|
||||
* Added `force` option for `mergePaths` plugin (by @goyney).
|
||||
* Added options to `prefixIds` plugin for selectively prefixing IDs and/or classes (by @strarsis).
|
||||
* Exported config function (by @1000ch).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.2.2) ] 1.2.2 / 16.04.2019
|
||||
* Update js-yaml for Code Injection warning (by @kaungst).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.2.1) ] 1.2.1 / 04.04.2019
|
||||
Some goodness from pull-requests.
|
||||
* Bump up js-yaml version to fix DoS vulnerability (by @eugestarr).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.2.0) ] 1.2.0 / 24.02.2019
|
||||
Some goodness from pull-requests.
|
||||
* Fixed extra blank lines when processing many files (by @panczarny).
|
||||
* Added `--recursive` option to process folders recursevely with option `-f` (by @dartess).
|
||||
* Added `removeAttributesBySelector` plugin to remove elements matching a css selector (by @bmease).
|
||||
* Added `removeOffCanvasPaths` plugin to remove elements outside of the viewbox (by @JoshyPHP).
|
||||
* `removeAttrs` plugin: added `preserveCurrentColor` color (by @roblevintennis) and 3rd optional filter for a value (by @Herman-Freund).
|
||||
* Added `reusePaths` plugin to replace duplicated elements with link (by @jhowcrof).
|
||||
* Added support of comma-separated plugins list in `--disable` and `--enable` options (by @jmwebservices).
|
||||
* Added option to preserve IDs based on prefix in `cleanupIDs` plugin (by @bkotzz).
|
||||
* Replaced `colors` dependency with `chalk` (by @xPaw).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.1.1) ] 1.1.1 / 17.09.2018
|
||||
* Fixed crash in `SVGO.optimize()` when ‘info’ is absent.
|
||||
* Removed extra space after `cleanupListOfValues` plugin.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.1.0) ] 1.1.0 / 16.09.2018
|
||||
* Fixed `collapseGroups` plugin removing property with a child having `inherit` value.
|
||||
* `version` attribute value is not more being rounded.
|
||||
* Fixed jsAPI `clone` method with respect to the introduced CSS classes.
|
||||
* Fixed scaling strokes with `vector-effect="non-scaling-stroke"` (by @alexjlockwood).
|
||||
* Fixed passing properties from groups in `collapseGroups` plugin if child have a filter (by @stristr).
|
||||
* Fixed arc path commands parsing without separators after flags, effectively producing a JS error.
|
||||
* Fixed `viewBox` separators parsing.
|
||||
* Fixed `removeNonInheritableGroupAttrs` plugin to work as intended.
|
||||
* Fixed removing path segments without length in presence of `stroke-linecap`.
|
||||
* Fixed `removeUnknownsAndDefaults` plugin removing attributes from elements with `id`.
|
||||
* Fixed converting to large arcs from nearly straight lines curves.
|
||||
* Fixed `collapseGroups` plugin affecting `<switch>` and its subgroups.
|
||||
* Fixed `convertTransform` plugin converting to `rotate()` with wrong sign in some case.
|
||||
* Fixed `cleanupListOfValues` plugin not preserving non-numeric values.
|
||||
* Fixed `!important` being passed to attributes in `convertStyleToAttrs` plugin.
|
||||
* Added option `keepImportant` to `convertStyleToAttrs` plugin to preserve styles with `!important`.
|
||||
* `removeHiddenElems` plugin now also removes elements with `visibility="hidden"` attribute (by @mikolaj92).
|
||||
* Added `forceAbsolutePath` option to `convertPathData` plugin to always use absolute coordinates (by @cool).
|
||||
* Added `keepRoleAttr` for `removeUnknownsAndDefaults` plugin to preserve `role-` attributes (by @himedlooff).
|
||||
* Added `xmlns` order option in `sortAttrs` plugin (by @hellatan).
|
||||
* Added an option to `prefixIds` plugin to pass prefix as false or as a function that returns false (by @vzaidman).
|
||||
* `prefixIds` plugin now adds prefix to every class (by @vzaidman).
|
||||
* Updated and improved docs a bit (multiple authors).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.5) ] 1.0.5 / 26.02.2018
|
||||
* Fixed issue with prefixIDs plugin not replacing url() values correctly (by @harrisjose).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.4) ] 1.0.4 / 30.01.2018
|
||||
* Fixed bug with removing groups that are direct child of "<switch>".
|
||||
* Fixed bug with shorthand path points counting (thanks @alexjlockwood for noticing).
|
||||
* Fixed crash on parsing invalid transform, e.g. without close parenthesis.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.3) ] 1.0.3 / 08.11.2017
|
||||
* Fixed `removeViewBox` plugin to check for zero start coordinates.
|
||||
* Removed extra info from STDOUT when it set to output.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.2) ] 1.0.2 / 03.11.2017
|
||||
* Fixed a couple of errors related to `inlineStyles` plugin.
|
||||
* Updated some lost details in documentation to reflect v1.0 changes.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.1) ] 1.0.1 / 31.10.2017
|
||||
* Fixed error “Object.defineProperty called on non-object” in images with `<foreignObject/>`.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.0) ] 1.0.0 / 30.10.2017
|
||||
* SVGO now requires Node 4 or higher.
|
||||
* Changed CLI syntax to treat filenames as input, thus allowing `svgo *.svg` syntax.
|
||||
* `SVGO.optimize()` now returns `Promise`.
|
||||
* Added `datauri` option to JS API.
|
||||
* Added support for SVG 2 `href` attribute.
|
||||
* `cleanupIDs` now don't removes IDs if an image consists only of `defs`.
|
||||
* New plugin `inlineStyles` for converting styles from `<style>` element to attributes if possible (by @strarsis).
|
||||
* `cleanupNumericValues` now rounds values in `viewBox` (by @caub).
|
||||
* New plugin: `removeScriptElement` (disabled by default) to align with `removeStyleElement` (by @pklingem).
|
||||
* `minifyStyles` now removes styles based on usage with controlling options (by @lahmatiy).
|
||||
* New option `except` in `cleanupIDs` to keep IDs (by @Velenir).
|
||||
* New option `force` in `cleanupIDs` to work even if SVG contains `style` or `script` elements (by @Velenir).
|
||||
* Fixed arcs transforming with different signed `scale` parameters (by @JoshyPHP).
|
||||
* Fixed `removeUselessStrokeAndFill` to check for `style` or `script` elements per file (by @caub).
|
||||
* New option `keepAriaAttrs` in `removeUnknownsAndDefaults` (by @davidtheclark).
|
||||
* Corrected parsing in `cleanupIDs` to account animation syntax (by @caub).
|
||||
* `#ff0000` now converts to `red` as well as `#f00` (by @davidleston).
|
||||
* Added “gray” variation to colors list per CSS Color Module Level 4 (by @ydaniv).
|
||||
* Fixed error on empty files.
|
||||
* A separator character in `removeAttrs` now can be changed per `elemSeparator` option (by @mikestreety).
|
||||
* `addAttributesToSVGElement` now can add values to attributes.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.7.2) ] 0.7.2 / 29.01.2017
|
||||
* Extended `currentColor` match conditions (string, rx, bool) (by @AlimovSV)
|
||||
* Fixed removing `<animate>` in `<stop>`.
|
||||
* Fixed removing same transform in inner element in `removeUnknownsAndDefaults`.
|
||||
* Fixed collapsing groups with same non-inheritable attribute.
|
||||
* Corrected removing of leading zero in case of exponential notation.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.7.1) ] 0.7.1 / 27.09.2016
|
||||
* Reverted the requirement of Node.js to version 0.10.
|
||||
* Added `addAttributesToSVGElement` to the default config to allow using it with `--enable` option.
|
||||
* Added korean translation of “How it works” doc (by @primeiros).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.7.0) ] 0.7.0 / 25.08.2016
|
||||
* Required Node.js version has increased to 0.12.
|
||||
* New plugins: `removeElementsByAttr` (by IDs or classes) by @elidupuis,
|
||||
`addAttributesToSVGElement` by @gjjones,
|
||||
`removeXMLNS` (for SVG inlining) by @ricardobeat.
|
||||
* Tests now correctly pass in Windows with CRLF line endings. Pretty print now accounts system line endings.
|
||||
* Fixed bugs with collapsing groups with masks and transforms in `collapseGroups`.
|
||||
* Fixed bugs with erroneous removing IDs in `cleanupIDs`.
|
||||
* Improved attributes sorting in `sortAttrs` by @darktrojan.
|
||||
* `addClassesToSVGElement` no more repeats classes (by @ricardobeat).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.6.6) ] 0.6.6 / 25.04.2016
|
||||
* Corrected CSSO API usage
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.6.5) ] 0.6.5 / 25.04.2016
|
||||
* Extra content inserted by editors are now being removed within `<foreignObject>` as well thus fixing bug “Namespace prefix … is not defined“ after applying SVGO.
|
||||
* Doctype with entities declaration is now also being removed since svgo correctly parses them starting from the version [0.6.2](https://github.com/svg/svgo/tree/v0.6.2).
|
||||
* Corrected `moveGroupAttrsToElems` not to move attributes to `g` content if it's referenced (has an `id`).
|
||||
* `collapseGroups` now don't collapse a group if it has an animated attribute (SMIL).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.6.4) ] 0.6.4 / 05.04.2016
|
||||
* Fixed bug in “[convertStyleToAttrs](https://github.com/svg/svgo/blob/master/plugins/convertStyleToAttrs.js)” plugin with converting styling properties to non-existent attributes (which are normally removed later by `removeUnknownsAndDefaults`).
|
||||
* Added `--indent` option to style pretty-printed SVG. (e.g. `--indent 2`) (by @scurker).
|
||||
* Added `currentColor` param to `convertColors` plugin for converting values like `fill` and `stroke` to `currentColor` (by @scurker).
|
||||
* Bumped CSSO to the current version and used [its new shiny API](https://github.com/css/csso#api) (thanks to @lahmatiy).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.6.3) ] 0.6.3 / 20.03.2016
|
||||
* Smart rounding (introduced in 0.4.5) now applies only when rounding is needed, thus making subsequent passes more stable.
|
||||
* Fixed regression in converting curves to arcs.
|
||||
* `xlink:href` references are now being checked by local name `href`, thus correctly working with another namespace prefix.
|
||||
* Fixed `id` removing with disabled `plugins/convertStyleToAttrs.js`.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.6.2) ] 0.6.2 / 08.03.2016
|
||||
* Better error handling and messaging improvements.
|
||||
* SVG files with XML entities (e.g. from Adobe Illustrator) are now correctly being parsed.
|
||||
* Fixed error on converting curves to arcs.
|
||||
* Corrected rounding in subsequent passes with `--multipass` option.
|
||||
* Data URI option now handles charset (by @holymonson)
|
||||
* Transformations are no longer moved to group if there is a mask (`plugins/moveElemsAttrsToGroup.js`).
|
||||
* Fixed matrix decomposition losing sign in case like `[1, 0, 0, -1, 0, 0]` (`scale(1 -1)`).
|
||||
* Fixed crash on uppercased color name.
|
||||
* Paths with `id` and without `stroke-width` aren't being transformed now since `stroke-width` may be applied later.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.6.1) ] 0.6.1 / 21.11.2015
|
||||
* Added option `--quiet` to suppress output (by @phihag).
|
||||
* Removed `lib-cov` folder from the package, which was erroneously included before.
|
||||
* Fixed errors in “[minifyStyles](https://github.com/svg/svgo/blob/master/plugins/minifyStyles.js)” when there are `<style>` elements with `CDATA` content or without content at all.
|
||||
* Amended transform functions parsing to prevent errors when there are no separators between numbers (which isn't allowed by syntax, but understood by browsers).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.6.0) ] 0.6.0 / 08.11.2015
|
||||
* New optimization: circular curves now being converted to arcs. A notable improvement for circles within paths.
|
||||
* New plugin “[minifyStyles](https://github.com/svg/svgo/blob/master/plugins/minifyStyles.js)” which minifies `<style>` elments content with CSSO by @strarsis (svgo still doesn't understand its content)
|
||||
* New plugin “[removeStyleElement](https://github.com/svg/svgo/blob/master/plugins/removeStyleElement.js)” (disabled by default) by @betsydupuis.
|
||||
* Fixed issues with parsing numbers with exponent fraction (could happen with high precision >= 7).
|
||||
* Fixed rounding error due to incorrect preserving of precision in transformations.
|
||||
* Fixed shorthand curve distortion due to converted previous curve to not a curve.
|
||||
* Fixed interoperability issue with `precision` cli-option and `full` config.
|
||||
* Fixed an error produced by “[removeUnknownsAndDefaults](https://github.com/svg/svgo/blob/master/plugins/removeUnknownsAndDefaults.js)” by @thiakil
|
||||
* Another Inkscape prefix namespace is being removed.
|
||||
* Fixed an issue in [moveElemsAttrsToGroup“](https://github.com/svg/svgo/blob/master/plugins/moveElemsAttrsToGroup“.js)” with transforms moved around `clip-path`.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.5.6) ] 0.5.6 / 13.08.2015
|
||||
* Fixed paths removing.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.5.5) ] 0.5.5 / 05.08.2015
|
||||
* Reverted debugging changes.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.5.4) ] 0.5.4 / 05.08.2015
|
||||
* New parameter `useShortTags` by @bradbarrow. Now svgo can produce correct non-selfclosing tags (useful in HTML in old browsers).
|
||||
* Fixed failing on empty transformation (which could be produced by two opposite).
|
||||
* Fixed removing paths which have numbers with exponent notation.
|
||||
* Fixed a bug with arc transformation.
|
||||
* Some typo fixes.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.5.3) ] 0.5.3 / 21.06.2015
|
||||
* Fixed breaking related to rounding functions in “[convertTransform](https://github.com/svg/svgo/blob/master/plugins/convertTransform.js)”.
|
||||
* Fixed a bug with ID in animations not being worked on by “[cleanupIDs](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js)”.
|
||||
* Fixed a bug with quoted reference in `url()`.
|
||||
* Now, if there are several same IDs in the document, then the first one is used and others are being removed.
|
||||
* New command-line option `--show-plugins` displaying list of plugins.
|
||||
* Two new optional plugins: “[removeDimensions](https://github.com/svg/svgo/blob/master/plugins/removeDimensions.js)” (removes `width` and `height` if there is `viewBox`) and “[removeAttrsPlugin](https://github.com/svg/svgo/blob/master/plugins/removeAttrs.js)” (by @bennyschudel).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.5.2) ] 0.5.2 / 24.05.2015
|
||||
* Introduced new `transformPrecision` option for better image quality (defaults to 5) in “[convertTransform](https://github.com/svg/svgo/blob/master/plugins/convertTransform.js)” and “[convertPathData](https://github.com/svg/svgo/blob/master/plugins/convertPathData.js)” (for the purpose of applying transformations) plugins.
|
||||
* Matrix transformations now can be decomposed into a combination of few simple transforms like `translate`, `rotate`, `scale`.
|
||||
* Arcs (paths `arcto` command) are now correctly being transformed into another arcs without being converting to Bezier curves.
|
||||
* Fixed an issue with “[mergePaths](https://github.com/svg/svgo/blob/master/plugins/mergePaths.js)” failing to detect paths intersection in some cases.
|
||||
* Fixed a bug with “[removeUnknownsAndDefaults](https://github.com/svg/svgo/blob/master/plugins/removeUnknownsAndDefaults.js)” removing some paths, which was introduced in [v0.5.1](https://github.com/svg/svgo/tree/v0.5.1).
|
||||
* Fixed a bug with transformation having `rotate()` with optional parameters.
|
||||
* Patterns with inherited attributes are no longer being removed.
|
||||
* Styles are no longer being removed from `<desc>` (by @dennari).
|
||||
* SVGO no longer breaks during parsing.
|
||||
* Added `clone()` method to JSAPI (by @jakearchibald)
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.5.1) ] 0.5.1 / 30.03.2015
|
||||
* added new command-line option to set precision in floating point numbers.
|
||||
* fixed all known image-disruptive bugs
|
||||
* Notably [mergePaths](https://github.com/svg/svgo/blob/master/plugins/mergePaths.js) plugin now checks for possible intersections to avoid side-effects
|
||||
* new plugin [removeUselessDefs](https://github.com/svg/svgo/blob/master/plugins/removeUselessDefs.js) to remove elements in ``<defs>`` and similar non-rendering elements without an ``id`` and thus cannot be used
|
||||
* fix for ``--multipass`` command line option (by @dfilatov)
|
||||
* improved [cleanupEnableBackground](https://github.com/svg/svgo/blob/master/plugins/cleanupEnableBackground.js) and [convertColors](https://github.com/svg/svgo/blob/master/plugins/convertColors.js) plugins (by @YetiOr)
|
||||
* new plugin for image manipulation [cleanupListOfValues](https://github.com/svg/svgo/blob/master/plugins/cleanupListOfValues.js) (by @kiyopikko)
|
||||
* fixed fail on comments after closing root ``</svg>`` tag
|
||||
* updated parsing to account meaningful spaces in ``<text>``
|
||||
* ``data-*`` attributes are now preserved in [removeUnknownsAndDefaults](https://github.com/svg/svgo/blob/master/plugins/removeUnknownsAndDefaults.js)
|
||||
* prevented plugins from failing in ``<foreignObject>``
|
||||
* [cleanupNumericValues](https://github.com/svg/svgo/blob/master/plugins/cleanupNumericValues.js) plugin now converts other units to pixels (if it's better)
|
||||
* [removeUselessStrokeAndFill](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) plugin is enabled again with correct work in case of inherited attributes
|
||||
* fixed fail on images with incorrect paths like ``<path d="z"/>``
|
||||
* svgo now understands if an input is a folder (remember, you can set output to folder as well)
|
||||
* added support for some properties from SVG 2 like ``vector-effect="non-scaling-stroke"``
|
||||
* removed option to remove an ``id`` on root ``<svg>`` tag in [removeUnknownsAndDefaults](https://github.com/svg/svgo/blob/master/plugins/removeUnknownsAndDefaults.js) since it's already being done in [cleanupIDs](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js)
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.5.0) ] 0.5.0 / 05.11.2014
|
||||
* added ``--multipass`` command line option which repeatedly applies optimizations like collapsing groups (by @dfilatov)
|
||||
* exposed JSAPI as a factory method (by @mistakster)
|
||||
* added removeDesc plugin (by @dwabyick), disabled by default
|
||||
* [removeUselessStrokeAndFill](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) plugin is disabled by default since it's unable to check inherited properties
|
||||
* transformations now apply to paths with arcs in [plugins/convertPathData](https://github.com/svg/svgo/blob/master/plugins/convertPathData.js)
|
||||
* a lot of bug fixes mostly related to transformations
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.4.5) ] 0.4.5 / 02.08.2014
|
||||
* significally improved plugin [plugins/convertPathData](https://github.com/svg/svgo/blob/master/plugins/convertPathData.js):
|
||||
- Now data is being written relative or absolute whichever is shorter. You can turn it off by setting ``utilizeAbsolute`` to ``false``.
|
||||
- Smarter rounding: values like 2.499 now rounds to 2.5. Rounding now takes in account accumulutive error meaning that points will not be misplaced due to rounding more than it neccessary.
|
||||
- Fixed couple bugs.
|
||||
* ``--output`` option now can be a folder along with ``--folder``, thanks to @mako-taco.
|
||||
* [plugins/cleanupIDs](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) now have ``prefix`` option in case you want to combine multiple svg later (by @DanielMazurkiewicz).
|
||||
* Quotes now being escaped in attributes (by @ditesh).
|
||||
* Minor bugfixes.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.4.4) ] 0.4.4 / 14.01.2014
|
||||
* new plugin [plugins/removeTitle](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) (disabled by default, close [#159](https://github.com/svg/svgo/issues/159))
|
||||
* plugins/convertPathData: skip data concatenation for z instruction in collapseRepeated
|
||||
* plugins/removeUnknownsAndDefaults: do not remove overriden attributes with default values (fix [#161](https://github.com/svg/svgo/issues/161) and [#168](https://github.com/svg/svgo/issues/168))
|
||||
* plugins/removeViewBox: disable by default (fix [#139](https://github.com/svg/svgo/issues/139))
|
||||
* update README with [gulp task](https://github.com/ben-eb/gulp-svgmin)
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.4.3) ] 0.4.3 / 02.01.2014
|
||||
* new plugin [plugins/convertShapeToPath](https://github.com/svg/svgo/blob/master/plugins/convertShapeToPath.js) (close [#96](https://github.com/svg/svgo/issues/96))
|
||||
* update sax version to fix [#140](https://github.com/svg/svgo/issues/140)
|
||||
* update deps
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.4.2) ] 0.4.2 / 19.12.2013
|
||||
* add `lcov.info` to npmignore
|
||||
* fix `js-yaml` version to suppress deprecation warning in stdout
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.4.1) ] 0.4.1 / 18.11.2013
|
||||
* node >=0.8.0
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.4.0) ] 0.4.0 / 18.11.2013
|
||||
* merge almost all pull-requests
|
||||
* update dependencies
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.3.7) ] 0.3.7 / 24.06.2013
|
||||
* do not remove `result` attribute from filter primitives (fix [#122](https://github.com/svg/svgo/issues/122))
|
||||
* plugins/cleanupAttrs: replace newline with space when needed (fix [#119](https://github.com/svg/svgo/issues/119))
|
||||
* lib/coa: look for config file in current folder
|
||||
* lib/coa: always traverse all files in the given folder
|
||||
* deprecate svgo-grunt in favor of [grunt-svgmin](https://github.com/sindresorhus/grunt-svgmin)
|
||||
* re-enable node-coveralls
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.3.6) ] 0.3.6 / 06.06.2013
|
||||
* plugins/removeNonInheritableGroupAttrs: more attrs groups to exclude (fix [#116](https://github.com/svg/svgo/issues/116) & [#118](https://github.com/svg/svgo/issues/118))
|
||||
* lib/coa: optimize folder file by file (temp fix [#114](https://github.com/svg/svgo/issues/114))
|
||||
* `.jshintrc`: JSHint 2.0
|
||||
* temporarily disable node-coveralls
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.3.5) ] 0.3.5 / 07.05.2013
|
||||
* plugins/transformsWithOnePath: fix curves bounding box calculation
|
||||
* plugins/transformsWithOnePath: fix possible c+t or q+s bug
|
||||
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.3.4) ] 0.3.4 / 06.05.2013
|
||||
* plugins/convertPathData: fix m->M bug in some cases
|
||||
* plugins/transformsWithOnePath: fix last point calculation for C/S/Q/T
|
||||
* plugins/mergePaths: add space delimiter between z and m
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.3.3) ] 0.3.3 / 05.05.2013
|
||||
* plugins/convertPathData: convert very first m to M, fix applyTransforms with translate() (fix [#112](https://github.com/svg/svgo/issues/112))
|
||||
* plugins/transformsWithOnePath: fix real width/height rounding; fix scale transform origin; reorder transforms
|
||||
* plugins/transformsWithOnePath: ability to set new width or height independently with auto rescaling
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.3.2) ] 0.3.2 / 03.05.2013
|
||||
* new plugin [plugins/sortAttrs](https://github.com/svg/svgo/blob/master/plugins/sortAttrs.js)
|
||||
* plugins/transformsWithOnePath: buggy hcrop (fix [#111](https://github.com/svg/svgo/issues/111))
|
||||
* Impossible to set output presision to 0 (no fractional part) (fix [#110](https://github.com/svg/svgo/issues/110))
|
||||
* Istanbul + coveralls.io
|
||||
* update README with NPM version from badge.fury.io
|
||||
* update README with dependency status from gemnasium.com
|
||||
* npmignore unneeded files
|
||||
* reoptimized project logo
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.3.1) ] 0.3.1 / 15.04.2013
|
||||
* plugins/transformsWithOnePath: resize SVG and automatically rescale inner Path
|
||||
* better errors handling
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.3.0) ] 0.3.0 / 12.04.2013
|
||||
* global refactoring: getting rid of the many dependencies
|
||||
* new plugin [plugins/mergePaths](https://github.com/svg/svgo/blob/master/plugins/mergePaths.js)
|
||||
* new plugin [plugins/transformsWithOnePath](https://github.com/svg/svgo/blob/master/plugins/transformsWithOnePath.js) (renamed and featured `cropAndCenterAlongPath`)
|
||||
* config: replace default config with `full: true`
|
||||
* coa: JSON string as value of `--config`
|
||||
* coa: different types of Data URI strings (close [#105](https://github.com/svg/svgo/issues/105))
|
||||
* plugins/_transforms: allow spaces at the beginning of transform
|
||||
* Travis CI: Nodejs 0.10 & 0.11
|
||||
* `node.extend` → `whet.extend`
|
||||
* update `.gitignore`
|
||||
* update docs
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.2.4) ] 0.2.4 / 05.04.2013
|
||||
* new plugin [plugins/cropAndCenterAlongPath](https://github.com/svg/svgo/blob/master/plugins/cropAndCenterAlongPath.js) for the [Fontello](https://github.com/fontello) project
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.2.3) ] 0.2.3 / 22.02.2013
|
||||
* new plugin [plugins/removeNonInheritableGroupAttrs](https://github.com/svg/svgo/blob/master/plugins/removeNonInheritableGroupAttrs.js) (fix [#101](https://github.com/svg/svgo/issues/101))
|
||||
* new plugin [plugins/removeRasterImages](https://github.com/svg/svgo/blob/master/plugins/removeRasterImages.js) (close [#98](https://github.com/svg/svgo/issues/98))
|
||||
* plugins/convertTransform: bug with trailing spaces in transform value string (fix [#103](https://github.com/svg/svgo/issues/103))
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.2.2) ] 0.2.2 / 09.02.2013
|
||||
* plugins/convertTransforms: wrong translate() shorthand (fix [#94](https://github.com/svg/svgo/issues/94))
|
||||
* [yaml.js](https://github.com/jeremyfa/yaml.js) → [js-yaml](https://github.com/nodeca/js-yaml)
|
||||
* update outdated deps
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.2.1) ] 0.2.1 / 18.01.2013
|
||||
* plugins/moveElemsAttrsToGroup + plugins/moveGroupAttrsToElems: move or just leave transform attr from Group to the inner Path Elems (close [#86](https://github.com/svg/svgo/issues/86))
|
||||
* plugins/removeViewBox: doesn't catch floating-point numbers (fix [#88](https://github.com/svg/svgo/issues/88))
|
||||
* plugins/cleanupEnableBackground: doesn't catch floating-point numbers (fix [#89](https://github.com/svg/svgo/issues/89))
|
||||
* plugins/cleanupNumericValues: wrong floating-point numbers regexp (fix [#92](https://github.com/svg/svgo/issues/92))
|
||||
* SVG file generated by fontcustom.com not properly compressed (fix [#90](https://github.com/svg/svgo/issues/90))
|
||||
* `README.ru.md`: стилизация русского языка, улучшение языковых конструкций, правка ошибок (close [#91](https://github.com/svg/svgo/issues/91))
|
||||
* minor JSHint warning fix
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.2.0) ] 0.2.0 / 23.12.2012
|
||||
* plugins/convertPathData: apply transforms to Path pata (close [#33](https://github.com/svg/svgo/issues/33))
|
||||
* plugins/convertPathData: `-1.816-9.278.682-13.604` parsing error (fix [#85](https://github.com/svg/svgo/issues/85))
|
||||
* plugins/convertTransform: `translate(10, 0)` eq `translate(10)`, but not `translate(10, 10)` eq `translate(10)` (fix [#83](https://github.com/svg/svgo/issues/83))
|
||||
* run plugins/cleanupIDs before plugins/collapseGroups (fix [#84](https://github.com/svg/svgo/issues/84))
|
||||
* update `.gitignore`
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.1.9) ] 0.1.9 / 17.12.2012
|
||||
* plugins/cleanupIDs: renamed from removeUnusedIDs; minify used IDs (fix [#7](https://github.com/svg/svgo/issues/7))
|
||||
* lib/svgo/js2svg: restore HTML entities back (fix [#80](https://github.com/svg/svgo/issues/80) + [#81](https://github.com/svg/svgo/issues/81))
|
||||
* plugins/removeDoctype: do not remove if custom XML entities presents (fix [#77](https://github.com/svg/svgo/issues/77))
|
||||
* lib/svgo/coa: refactoring, colors and fix [#70](https://github.com/svg/svgo/issues/70)
|
||||
* lib/svgo: store elapsed time in result object
|
||||
* usage examples with SVGZ (close [#18](https://github.com/svg/svgo/issues/18))
|
||||
* more optimized logo
|
||||
* update `.gitignore`
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.1.8) ] 0.1.8 / 11.12.2012
|
||||
* new plugin [plugins/removeUselessStrokeAndFill](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) (close [#75](https://github.com/svg/svgo/issues/75))
|
||||
* new plugin [plugins/removeUnusedIDs](https://github.com/svg/svgo/blob/master/plugins/removeUnusedIDs.js) (close [#76](https://github.com/svg/svgo/issues/76))
|
||||
* plugins/convertPathData: wrong M interpretation in some cases (fix [#73](https://github.com/svg/svgo/issues/73))
|
||||
* plugins/cleanupAttrs: use `isElem()` API
|
||||
* `.travis.yml`: check all branches
|
||||
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.1.7) ] 0.1.7 / 08.12.2012
|
||||
* plugins/convertPathData: incorrect interpretation of `z + m` (fix [#69](https://github.com/svg/svgo/issues/69))
|
||||
* plugins/convertTransform: do a more accurate floating numbers rounding in `matrixToTransform()` (fix [#68](https://github.com/svg/svgo/issues/68))
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.1.6) ] 0.1.6 / 07.12.2012
|
||||
* plugins/convertPathData: collapse repeated instructions only after curveSmoothShorthands (fix [#64](https://github.com/svg/svgo/issues/64))
|
||||
* lib/svgo/coa: handle 'there is nothing to optimize' case and display a message about it (fix [#61](https://github.com/svg/svgo/issues/61))
|
||||
* plugins/cleanupSVGElem: delete as useless artefact
|
||||
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.1.5) ] 0.1.5 / 06.12.2012
|
||||
* E-notated numbers in paths not recognised (fix [#63](https://github.com/svg/svgo/issues/63))
|
||||
* update README with `svgo-grunt` and `svgo-osx-folder-action`
|
||||
* fix `mocha-as-promised` plug in node 0.6
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.1.4) ] 0.1.4 / 05.12.2012
|
||||
* plugins/_collections: more defaults
|
||||
* `README.ru.md`
|
||||
* `docs/how-it-works/ru.md`
|
||||
* mocha + mocha-as-promised + chai + chai-as-promised + should + istanbul = <3
|
||||
* update dependencies semvers in `package.json`
|
||||
* `v0.1.x` and `v0.2.x` milestones
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.1.3) ] 0.1.3 / 30.11.2012
|
||||
* new plugin [plugins/cleanupNumericValues](https://github.com/svg/svgo/blob/master/plugins/cleanupNumericValues.js) (close [#8](https://github.com/svg/svgo/issues/8))
|
||||
* plugins/removeDefaultPx functionality now included in plugins/removeUnknownsAndDefaults
|
||||
* plugins/removeUnknownsAndDefaults: refactoring and picking up the complete elems+attrs collection (close [#59](https://github.com/svg/svgo/issues/59))
|
||||
* plugins/convertTransform: error in matrices multiplication (fix [#58](https://github.com/svg/svgo/issues/58))
|
||||
* plugins/convertTransform: mark translate() and scale() as useless only with one param (fix [#57](https://github.com/svg/svgo/issues/57))
|
||||
* plugins/convertPathData: drastic speed improvement with huge Path data
|
||||
* plugins/convertPathData: fix the very first Mm with multiple points (fix [#56](https://github.com/svg/svgo/issues/56))
|
||||
* plugins/moveElemsAttrsToGroup: additional check for transform attr
|
||||
* brand-new project `logo.svg`
|
||||
* `.travis.yml`: build only master branch
|
||||
* global `'use strict'`
|
||||
* `.jshintignore`
|
||||
* README and CHANGELOG: minor corrections
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.1.2) ] 0.1.2 / 24.11.2012
|
||||
* lib/svgo/svg2js: correct 'onerror' failure (fix [#51](https://github.com/svg/svgo/issues/51))
|
||||
* config: disable sax-js position tracking by default (fix [#52](https://github.com/svg/svgo/issues/52))
|
||||
* lib/svgo: rename 'startBytes' to 'inBytes' and 'endBytes' to 'outBytes' (close [#53](https://github.com/svg/svgo/issues/53))
|
||||
* plugins/removeUnknownsAndDefaults: remove SVG id attr (close [#54](https://github.com/svg/svgo/issues/54))
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.1.1) ] 0.1.1 / 23.11.2012
|
||||
* plugins/moveElemsAttrsToGroup: fix inheitable only attrs array (fix [#47](https://github.com/svg/svgo/issues/47))
|
||||
* plugins/removeEmptyContainers: do not remove an empty 'svg' element (fix [#48](https://github.com/svg/svgo/issues/48))
|
||||
* plugins/removeDefaultPx: should also understand a floating-numbers too (fix [#49](https://github.com/svg/svgo/issues/49))
|
||||
* plugins/removeUnknownsAndDefaults: merge multiple groupDefaults attrs (close [#50](https://github.com/svg/svgo/issues/50))
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.1.0) ] 0.1.0 / 22.11.2012
|
||||
* new plugin [plugins/removeUnknownsAndDefaults](https://github.com/svg/svgo/blob/master/plugins/removeUnknownsAndDefaults.js) (close [#6](https://github.com/svg/svgo/issues/6))
|
||||
* plugins/convertPathData: convert straight curves into lines segments (close [#17](https://github.com/svg/svgo/issues/17)); remove an absolute coords conversions
|
||||
* plugins/convertPathData: convert quadratic Bézier curveto into smooth shorthand (close [#31](https://github.com/svg/svgo/issues/31))
|
||||
* plugins/convertPathData: convert curveto into smooth shorthand (close [#30](https://github.com/svg/svgo/issues/30))
|
||||
* lib/svgo: global API refactoring (close [#37](https://github.com/svg/svgo/issues/37))
|
||||
* lib/svgo: fatal and stupid error in stream chunks concatenation (fix [#40](https://github.com/svg/svgo/issues/40))
|
||||
* lib/coa: batch folder optimization (close [#29](https://github.com/svg/svgo/issues/29))
|
||||
* lib/coa: support arguments as aliases to `--input` and `--output` (close [#28](https://github.com/svg/svgo/issues/28))
|
||||
* project logo by [Egor Bolhshakov](http://xizzzy.ru/)
|
||||
* move modules to `./lib/svgo/`
|
||||
* rename and convert `config.json` to `.svgo.yml`
|
||||
* add [./docs/](https://github.com/svg/svgo/tree/master/docs)
|
||||
* plugins/convertPathData: don't remove first `M` even if it's `0,0`
|
||||
* plugins/convertPathData: stronger defense from infinite loop
|
||||
* plugins/moveElemsAttrsToGroup: should affect only inheritable attributes (fix [#46](https://github.com/svg/svgo/issues/46))*
|
||||
* plugins/removeComments: ignore comments which starts with '!' (close [#43](https://github.com/svg/svgo/issues/43))
|
||||
* config: `cleanupAttrs` should be before `convertStyleToAttrs` (fix [#44](https://github.com/svg/svgo/issues/44))*
|
||||
* lib/svgo/jsAPI: add `eachAttr()` optional context param
|
||||
* temporarily remove PhantomJS and `--test` (close [#38](https://github.com/svg/svgo/issues/38))
|
||||
* q@0.8.10 compatibility: 'end is deprecated, use done instead' fix
|
||||
* add [Istanbul](https://github.com/gotwarlost/istanbul) code coverage
|
||||
* update dependencies versions and gitignore
|
||||
* README: add TODO section with versions milestones
|
||||
* update README with License section
|
||||
* update LICENSE with russian translation
|
||||
* `.editorconfig`: 2 spaces for YAML
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.0.9) ] 0.0.9 / 29.10.2012
|
||||
* [plugins how-to](https://github.com/svg/svgo/tree/master/plugins#readme) (close [#27](https://github.com/svg/svgo/issues/27))
|
||||
* allow any plugin of any type to go in any order (close [#14](https://github.com/svg/svgo/issues/14))
|
||||
* allow to do a multiple optimizations with one init (close [#25](https://github.com/svg/svgo/issues/25))
|
||||
* plugins/convertPathData: global refactoring
|
||||
* plugins/convertPathData: do all the tricks with absolute coords too (fix [#22](https://github.com/svg/svgo/issues/22))
|
||||
* plugins/convertPathData: accumulation of rounding errors (fix [#23](https://github.com/svg/svgo/issues/23))
|
||||
* plugins/convertPathData: prevent an infinity loop on invalid path data (fix [#26](https://github.com/svg/svgo/issues/26))
|
||||
* plugins/convertPathData: do not remove very first M from the path data (fix [#24](https://github.com/svg/svgo/issues/24))
|
||||
* plugins/convertPathData: optimize path data in <glyph> and <missing-glyph> (close [#20](https://github.com/svg/svgo/issues/20))
|
||||
* plugins/convertTransform: add patternTransform attribute to the process (close [#15](https://github.com/svg/svgo/issues/15))
|
||||
* plugins/convertTransform: Firefox: removing extra space in front of negative number is alowed only in path data, but not in transform (fix [#12](https://github.com/svg/svgo/issues/12))
|
||||
* plugins/removeXMLProcInst: remove only 'xml' but not 'xml-stylesheet' (fix [#21](https://github.com/svg/svgo/issues/15))
|
||||
* plugins/collapseGroups: merge split-level transforms (fix [#13](https://github.com/svg/svgo/issues/13))
|
||||
* jsdoc corrections
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.0.8) ] 0.0.8 / 20.10.2012
|
||||
* new plugin [convertTransform](plugins/convertTransform.js) (close [#5](https://github.com/svg/svgo/issues/5))
|
||||
* new plugin [removeUnusedNS](plugins/removeUnusedNS.js)
|
||||
* plugins/convertPathData: remove useless segments
|
||||
* plugins/convertPathData: a lot of refactoring
|
||||
* plugins/convertPathData: round numbers before conditions because of exponential notation (fix [#3](https://github.com/svg/svgo/issues/3))
|
||||
* plugins/moveElemsAttrsToGroup: merge split-level transforms instead of replacing (fix [#10](https://github.com/svg/svgo/issues/10))
|
||||
* lib/svg2js: catch and output xml parser errors (fix [#4](https://github.com/svg/svgo/issues/4))
|
||||
* lib/coa: open file for writing only when we are ready (fix [#2](https://github.com/svg/svgo/issues/2))
|
||||
* lib/tools: node.extend module
|
||||
* lib/plugins: refactoring
|
||||
* lib/js2svg: refactoring
|
||||
* lib/jsAPI: simplification and refactoring
|
||||
* absolute urls in README
|
||||
* update .editorconfig
|
||||
* update .travis.yml with nodejs 0.9
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.0.7) ] 0.0.7 / 14.10.2012
|
||||
* new plugin [convertPathData](plugins/convertPathData.js)
|
||||
* --input data now can be a Data URI base64 string
|
||||
* --output data now can be a Data URI base64 string with --datauri flag
|
||||
* Travis CI
|
||||
* JSHint corrections + .jshintrc
|
||||
* [.editorconfig](http://editorconfig.org/)
|
||||
* display time spent on optimization
|
||||
* .svgo → config.json
|
||||
* lib/phantom_wrapper.js → lib/phantom.js
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.0.6) ] 0.0.6 / 04.10.2012
|
||||
* add --test option to make a visual comparison of two files (PhantomJS pre-required)
|
||||
* update README and CHANGELOG with the correct relative urls
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.0.5) ] 0.0.5 / 03.10.2012
|
||||
* every plugin now has [at least one test](plugins)
|
||||
* removeViewBox, cleanupEnableBackground, removeEditorsNSData, convertStyleToAttrs and collapseGroups plugins fixes
|
||||
* new --pretty option for the pretty printed SVG
|
||||
* lib/config refactoring
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.0.4) ] 0.0.4 / 30.09.2012
|
||||
* new plugin [removeViewBox](plugins/removeViewBox.js)
|
||||
* new plugin [cleanupEnableBackground](plugins/cleanupEnableBackground.js)
|
||||
* display useful info after successful optimization
|
||||
* 'npm test' with 'spec' mocha output by default
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.0.3) ] 0.0.3 / 29.09.2012
|
||||
* plugins/collapseGroups bugfix
|
||||
* plugins/moveElemsAttrsToGroup bugfix
|
||||
* svgo now display --help if running w/o arguments
|
||||
* massive jsdoc updates
|
||||
* plugins engine main filter function optimization
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.0.2) ] 0.0.2 / 28.09.2012
|
||||
* add --disable and --enable command line options
|
||||
* add an empty values rejecting to coa.js
|
||||
* update README
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.0.1) ] 0.0.1 / 27.09.2012
|
||||
* initial public version
|
55
assets_old/node_modules/svgo/LICENSE
generated
vendored
Normal file
55
assets_old/node_modules/svgo/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
The MIT License
|
||||
|
||||
Copyright © 2012–2016 Kir Belevich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
Лицензия MIT
|
||||
|
||||
Copyright © 2012–2016 Кир Белевич
|
||||
|
||||
Данная лицензия разрешает лицам, получившим копию данного
|
||||
программного обеспечения и сопутствующей документации
|
||||
(в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно
|
||||
использовать Программное Обеспечение без ограничений, включая
|
||||
неограниченное право на использование, копирование, изменение,
|
||||
добавление, публикацию, распространение, сублицензирование
|
||||
и/или продажу копий Программного Обеспечения, также как и лицам,
|
||||
которым предоставляется данное Программное Обеспечение,
|
||||
при соблюдении следующих условий:
|
||||
|
||||
Указанное выше уведомление об авторском праве и данные условия
|
||||
должны быть включены во все копии или значимые части данного
|
||||
Программного Обеспечения.
|
||||
|
||||
ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ»,
|
||||
БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ,
|
||||
ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ,
|
||||
СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ
|
||||
ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ
|
||||
ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ
|
||||
ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ,
|
||||
ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ С ПРОГРАММНЫМ
|
||||
ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
|
||||
ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
|
21
assets_old/node_modules/svgo/Makefile
generated
vendored
Normal file
21
assets_old/node_modules/svgo/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
test:
|
||||
@npm run test
|
||||
|
||||
lib-cov:
|
||||
@./node_modules/.bin/istanbul instrument --output lib-cov --no-compact --variable global.__coverage__ lib
|
||||
|
||||
coverage: lib-cov
|
||||
@COVERAGE=1 ISTANBUL_REPORTERS=text-summary ./node_modules/.bin/mocha --reporter mocha-istanbul
|
||||
@rm -rf lib-cov
|
||||
|
||||
coveralls: lib-cov
|
||||
@COVERAGE=1 ISTANBUL_REPORTERS=lcovonly ./node_modules/.bin/mocha --reporter mocha-istanbul
|
||||
@cat lcov.info | ./node_modules/.bin/coveralls
|
||||
@rm -rf lib-cov lcov.info
|
||||
|
||||
travis: lint test coveralls
|
||||
|
||||
lint:
|
||||
@npm run lint
|
||||
|
||||
.PHONY: test
|
215
assets_old/node_modules/svgo/README.md
generated
vendored
Normal file
215
assets_old/node_modules/svgo/README.md
generated
vendored
Normal file
|
@ -0,0 +1,215 @@
|
|||
**english** | [русский](https://github.com/svg/svgo/blob/master/README.ru.md)
|
||||
- - -
|
||||
|
||||
<img src="https://svg.github.io/svgo-logo.svg" width="200" height="200" alt="logo"/>
|
||||
|
||||
## SVGO [](https://npmjs.org/package/svgo) [](https://travis-ci.org/svg/svgo) [](https://coveralls.io/r/svg/svgo?branch=master)
|
||||
|
||||
**SVG O**ptimizer is a Nodejs-based tool for optimizing SVG vector graphics files.
|
||||

|
||||
|
||||
## Why?
|
||||
|
||||
SVG files, especially those exported from various editors, usually contain a lot of redundant and useless information. This can include editor metadata, comments, hidden elements, default or non-optimal values and other stuff that can be safely removed or converted without affecting the SVG rendering result.
|
||||
|
||||
## What it can do
|
||||
|
||||
SVGO has a plugin-based architecture, so almost every optimization is a separate plugin.
|
||||
|
||||
Today we have:
|
||||
|
||||
| Plugin | Description | Default |
|
||||
| ------ | ----------- | ------- |
|
||||
| [cleanupAttrs](https://github.com/svg/svgo/blob/master/plugins/cleanupAttrs.js) | cleanup attributes from newlines, trailing, and repeating spaces | `enabled` |
|
||||
| [inlineStyles](https://github.com/svg/svgo/blob/master/plugins/inlineStyles.js) | move and merge styles from `<style>` elements to element `style` attributes | `enabled` |
|
||||
| [removeDoctype](https://github.com/svg/svgo/blob/master/plugins/removeDoctype.js) | remove doctype declaration | `enabled` |
|
||||
| [removeXMLProcInst](https://github.com/svg/svgo/blob/master/plugins/removeXMLProcInst.js) | remove XML processing instructions | `enabled` |
|
||||
| [removeComments](https://github.com/svg/svgo/blob/master/plugins/removeComments.js) | remove comments | `enabled` |
|
||||
| [removeMetadata](https://github.com/svg/svgo/blob/master/plugins/removeMetadata.js) | remove `<metadata>` | `enabled` |
|
||||
| [removeTitle](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) | remove `<title>` | `enabled` |
|
||||
| [removeDesc](https://github.com/svg/svgo/blob/master/plugins/removeDesc.js) | remove `<desc>` | `enabled` |
|
||||
| [removeUselessDefs](https://github.com/svg/svgo/blob/master/plugins/removeUselessDefs.js) | remove elements of `<defs>` without `id` | `enabled` |
|
||||
| [removeXMLNS](https://github.com/svg/svgo/blob/master/plugins/removeXMLNS.js) | removes `xmlns` attribute (for inline svg) | `disabled` |
|
||||
| [removeEditorsNSData](https://github.com/svg/svgo/blob/master/plugins/removeEditorsNSData.js) | remove editors namespaces, elements, and attributes | `enabled` |
|
||||
| [removeEmptyAttrs](https://github.com/svg/svgo/blob/master/plugins/removeEmptyAttrs.js) | remove empty attributes | `enabled` |
|
||||
| [removeHiddenElems](https://github.com/svg/svgo/blob/master/plugins/removeHiddenElems.js) | remove hidden elements | `enabled` |
|
||||
| [removeEmptyText](https://github.com/svg/svgo/blob/master/plugins/removeEmptyText.js) | remove empty Text elements | `enabled` |
|
||||
| [removeEmptyContainers](https://github.com/svg/svgo/blob/master/plugins/removeEmptyContainers.js) | remove empty Container elements | `enabled` |
|
||||
| [removeViewBox](https://github.com/svg/svgo/blob/master/plugins/removeViewBox.js) | remove `viewBox` attribute when possible | `enabled` |
|
||||
| [cleanupEnableBackground](https://github.com/svg/svgo/blob/master/plugins/cleanupEnableBackground.js) | remove or cleanup `enable-background` attribute when possible | `enabled` |
|
||||
| [minifyStyles](https://github.com/svg/svgo/blob/master/plugins/minifyStyles.js) | minify `<style>` elements content with [CSSO](https://github.com/css/csso) | `enabled` |
|
||||
| [convertStyleToAttrs](https://github.com/svg/svgo/blob/master/plugins/convertStyleToAttrs.js) | convert styles into attributes | `enabled` |
|
||||
| [convertColors](https://github.com/svg/svgo/blob/master/plugins/convertColors.js) | convert colors (from `rgb()` to `#rrggbb`, from `#rrggbb` to `#rgb`) | `enabled` |
|
||||
| [convertPathData](https://github.com/svg/svgo/blob/master/plugins/convertPathData.js) | convert Path data to relative or absolute (whichever is shorter), convert one segment to another, trim useless delimiters, smart rounding, and much more | `enabled` |
|
||||
| [convertTransform](https://github.com/svg/svgo/blob/master/plugins/convertTransform.js) | collapse multiple transforms into one, convert matrices to the short aliases, and much more | `enabled` |
|
||||
| [removeUnknownsAndDefaults](https://github.com/svg/svgo/blob/master/plugins/removeUnknownsAndDefaults.js) | remove unknown elements content and attributes, remove attrs with default values | `enabled` |
|
||||
| [removeNonInheritableGroupAttrs](https://github.com/svg/svgo/blob/master/plugins/removeNonInheritableGroupAttrs.js) | remove non-inheritable group's "presentation" attributes | `enabled` |
|
||||
| [removeUselessStrokeAndFill](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) | remove useless `stroke` and `fill` attrs | `enabled` |
|
||||
| [removeUnusedNS](https://github.com/svg/svgo/blob/master/plugins/removeUnusedNS.js) | remove unused namespaces declaration | `enabled` |
|
||||
| [prefixIds](https://github.com/svg/svgo/blob/master/plugins/prefixIds.js) | prefix IDs and classes with the SVG filename or an arbitrary string | `disabled` |
|
||||
| [cleanupIDs](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) | remove unused and minify used IDs | `enabled` |
|
||||
| [cleanupNumericValues](https://github.com/svg/svgo/blob/master/plugins/cleanupNumericValues.js) | round numeric values to the fixed precision, remove default `px` units | `enabled` |
|
||||
| [cleanupListOfValues](https://github.com/svg/svgo/blob/master/plugins/cleanupListOfValues.js) | round numeric values in attributes that take a list of numbers (like `viewBox` or `enable-background`) | `disabled` |
|
||||
| [moveElemsAttrsToGroup](https://github.com/svg/svgo/blob/master/plugins/moveElemsAttrsToGroup.js) | move elements' attributes to their enclosing group | `enabled` |
|
||||
| [moveGroupAttrsToElems](https://github.com/svg/svgo/blob/master/plugins/moveGroupAttrsToElems.js) | move some group attributes to the contained elements | `enabled` |
|
||||
| [collapseGroups](https://github.com/svg/svgo/blob/master/plugins/collapseGroups.js) | collapse useless groups | `enabled` |
|
||||
| [removeRasterImages](https://github.com/svg/svgo/blob/master/plugins/removeRasterImages.js) | remove raster images | `disabled` |
|
||||
| [mergePaths](https://github.com/svg/svgo/blob/master/plugins/mergePaths.js) | merge multiple Paths into one | `enabled` |
|
||||
| [convertShapeToPath](https://github.com/svg/svgo/blob/master/plugins/convertShapeToPath.js) | convert some basic shapes to `<path>` | `enabled` |
|
||||
| [convertEllipseToCircle](https://github.com/svg/svgo/blob/master/plugins/convertEllipseToCircle.js) | convert non-eccentric `<ellipse>` to `<circle>` | `enabled` |
|
||||
| [sortAttrs](https://github.com/svg/svgo/blob/master/plugins/sortAttrs.js) | sort element attributes for epic readability | `disabled` |
|
||||
| [sortDefsChildren](https://github.com/svg/svgo/blob/master/plugins/sortDefsChildren.js) | sort children of `<defs>` in order to improve compression | `enabled` |
|
||||
| [removeDimensions](https://github.com/svg/svgo/blob/master/plugins/removeDimensions.js) | remove `width`/`height` and add `viewBox` if it's missing (opposite to removeViewBox, disable it first) | `disabled` |
|
||||
| [removeAttrs](https://github.com/svg/svgo/blob/master/plugins/removeAttrs.js) | remove attributes by pattern | `disabled` |
|
||||
| [removeAttributesBySelector](https://github.com/svg/svgo/blob/master/plugins/removeAttributesBySelector.js) | removes attributes of elements that match a css selector | `disabled` |
|
||||
| [removeElementsByAttr](https://github.com/svg/svgo/blob/master/plugins/removeElementsByAttr.js) | remove arbitrary elements by ID or className | `disabled` |
|
||||
| [addClassesToSVGElement](https://github.com/svg/svgo/blob/master/plugins/addClassesToSVGElement.js) | add classnames to an outer `<svg>` element | `disabled` |
|
||||
| [addAttributesToSVGElement](https://github.com/svg/svgo/blob/master/plugins/addAttributesToSVGElement.js) | adds attributes to an outer `<svg>` element | `disabled` |
|
||||
| [removeOffCanvasPaths](https://github.com/svg/svgo/blob/master/plugins/removeOffCanvasPaths.js) | removes elements that are drawn outside of the viewbox | `disabled` |
|
||||
| [removeStyleElement](https://github.com/svg/svgo/blob/master/plugins/removeStyleElement.js) | remove `<style>` elements | `disabled` |
|
||||
| [removeScriptElement](https://github.com/svg/svgo/blob/master/plugins/removeScriptElement.js) | remove `<script>` elements | `disabled` |
|
||||
| [reusePaths](https://github.com/svg/svgo/blob/master/plugins/reusePaths.js) | Find duplicated <path> elements and replace them with <use> links | `disabled` |
|
||||
|
||||
Want to know how it works and how to write your own plugin? [Of course you want to](https://github.com/svg/svgo/blob/master/docs/how-it-works/en.md). ([동작방법](https://github.com/svg/svgo/blob/master/docs/how-it-works/ko.md))
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
$ [sudo] npm install -g svgo
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### <abbr title="Command Line Interface">CLI</abbr>
|
||||
|
||||
```
|
||||
Usage:
|
||||
svgo [OPTIONS] [ARGS]
|
||||
|
||||
Options:
|
||||
-h, --help : Help
|
||||
-v, --version : Version
|
||||
-i INPUT, --input=INPUT : Input file, "-" for STDIN
|
||||
-s STRING, --string=STRING : Input SVG data string
|
||||
-f FOLDER, --folder=FOLDER : Input folder, optimize and rewrite all *.svg files
|
||||
-o OUTPUT, --output=OUTPUT : Output file or folder (by default the same as the input), "-" for STDOUT
|
||||
-p PRECISION, --precision=PRECISION : Set number of digits in the fractional part, overrides plugins params
|
||||
--config=CONFIG : Config file or JSON string to extend or replace default
|
||||
--disable=PLUGIN : Disable plugin by name, "--disable=PLUGIN1,PLUGIN2" for multiple plugins
|
||||
--enable=PLUGIN : Enable plugin by name, "--enable=PLUGIN3,PLUGIN4" for multiple plugins
|
||||
--datauri=DATAURI : Output as Data URI string (base64, URI encoded or unencoded)
|
||||
--multipass : Pass over SVGs multiple times to ensure all optimizations are applied
|
||||
--pretty : Make SVG pretty printed
|
||||
--indent=INDENT : Indent number when pretty printing SVGs
|
||||
-r, --recursive : Use with '-f'. Optimizes *.svg files in folders recursively.
|
||||
-q, --quiet : Only output error messages, not regular status messages
|
||||
--show-plugins : Show available plugins and exit
|
||||
|
||||
Arguments:
|
||||
INPUT : Alias to --input
|
||||
```
|
||||
|
||||
* with files:
|
||||
|
||||
```sh
|
||||
$ svgo test.svg
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```sh
|
||||
$ svgo *.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg -o test.min.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg other.svg third.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg other.svg third.svg -o test.min.svg -o other.min.svg -o third.min.svg
|
||||
```
|
||||
|
||||
* with STDIN / STDOUT:
|
||||
|
||||
```sh
|
||||
$ cat test.svg | svgo -i - -o - > test.min.svg
|
||||
```
|
||||
|
||||
* with folder
|
||||
|
||||
```sh
|
||||
$ svgo -f ../path/to/folder/with/svg/files
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```sh
|
||||
$ svgo -f ../path/to/folder/with/svg/files -o ../path/to/folder/with/svg/output
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo *.svg -o ../path/to/folder/with/svg/output
|
||||
```
|
||||
|
||||
* with strings:
|
||||
|
||||
```sh
|
||||
$ svgo -s '<svg version="1.1">test</svg>' -o test.min.svg
|
||||
```
|
||||
|
||||
or even with Data URI base64:
|
||||
|
||||
```sh
|
||||
$ svgo -s 'data:image/svg+xml;base64,...' -o test.min.svg
|
||||
```
|
||||
|
||||
* with SVGZ:
|
||||
|
||||
from `.svgz` to `.svg`:
|
||||
|
||||
```sh
|
||||
$ gunzip -c test.svgz | svgo -i - -o test.min.svg
|
||||
```
|
||||
|
||||
from `.svg` to `.svgz`:
|
||||
|
||||
```sh
|
||||
$ svgo test.svg -o - | gzip -cfq9 > test.svgz
|
||||
```
|
||||
|
||||
### Other Ways to Use SVGO
|
||||
|
||||
* as a web app – [SVGOMG](https://jakearchibald.github.io/svgomg/)
|
||||
* as a Nodejs module – [examples](https://github.com/svg/svgo/tree/master/examples)
|
||||
* as a Grunt task – [grunt-svgmin](https://github.com/sindresorhus/grunt-svgmin)
|
||||
* as a Gulp task – [gulp-svgmin](https://github.com/ben-eb/gulp-svgmin)
|
||||
* as a Mimosa module – [mimosa-minify-svg](https://github.com/dbashford/mimosa-minify-svg)
|
||||
* as an OSX Folder Action – [svgo-osx-folder-action](https://github.com/svg/svgo-osx-folder-action)
|
||||
* as a webpack loader – [image-webpack-loader](https://github.com/tcoopman/image-webpack-loader)
|
||||
* as a Telegram Bot – [svgo_bot](https://github.com/maksugr/svgo_bot)
|
||||
* as a PostCSS plugin – [postcss-svgo](https://github.com/ben-eb/postcss-svgo)
|
||||
* as an Inkscape plugin – [inkscape-svgo](https://github.com/konsumer/inkscape-svgo)
|
||||
* as a Sketch plugin - [svgo-compressor](https://github.com/BohemianCoding/svgo-compressor)
|
||||
* as macOS app - [Image Shrinker](https://image-shrinker.com)
|
||||
* as a Rollup plugin - [rollup-plugin-svgo](https://github.com/porsager/rollup-plugin-svgo)
|
||||
|
||||
## Backers
|
||||
|
||||
| [<img src="https://sheetjs.com/sketch128.png" width="80">](https://sheetjs.com/) | [<img src="https://rawgithub.com/fontello/fontello/master/fontello-image.svg" width="80">](http://fontello.com/) |
|
||||
|:-:|:-:|
|
||||
| [SheetJS LLC](https://sheetjs.com/) | [Fontello](http://fontello.com/) |
|
||||
|
||||
## Donations
|
||||
|
||||
- PayPal: https://www.paypal.me/deepsweet
|
||||
|
||||
## License and Copyright
|
||||
|
||||
This software is released under the terms of the [MIT license](https://github.com/svg/svgo/blob/master/LICENSE).
|
||||
|
||||
Logo by [Yegor Bolshakov](http://xizzzy.ru/).
|
205
assets_old/node_modules/svgo/README.ru.md
generated
vendored
Normal file
205
assets_old/node_modules/svgo/README.ru.md
generated
vendored
Normal file
|
@ -0,0 +1,205 @@
|
|||
[english](https://github.com/svg/svgo/blob/master/README.md) | **русский**
|
||||
- - -
|
||||
|
||||
<img src="https://svg.github.io/svgo-logo.svg" width="200" height="200" alt="logo"/>
|
||||
|
||||
## SVGO [](https://npmjs.org/package/svgo) [](https://travis-ci.org/svg/svgo) [](https://coveralls.io/r/svg/svgo?branch=master)
|
||||
|
||||
**SVG** **O**ptimizer – это инструмент для оптимизации векторной графики в формате SVG, написанный на Node.js.
|
||||

|
||||
|
||||
## Зачем?
|
||||
|
||||
SVG-файлы, особенно экспортированные из редакторов, содержат много избыточной и бесполезной информации, комментариев, скрытых элементов, неоптимальные или стандартные значения и другой мусор, удаление которого безопасно и не влияет на конечный вид изображения.
|
||||
|
||||
## Возможности
|
||||
|
||||
SVGO имеет расширяемую архитектуру, в которой почти каждая оптимизация является отдельным расширением.
|
||||
|
||||
Что у нас есть:
|
||||
|
||||
| Plugin | Description | Default |
|
||||
| ------ | ----------- | ------- |
|
||||
| [cleanupAttrs](https://github.com/svg/svgo/blob/master/plugins/cleanupAttrs.js) | удаление переносов строк и лишних пробелов | `включен` |
|
||||
| [inlineStyles](https://github.com/svg/svgo/blob/master/plugins/inlineStyles.js) | перенос стилей из элементов `<style>` в атрибуты `style` | `включен` |
|
||||
| [removeDoctype](https://github.com/svg/svgo/blob/master/plugins/removeDoctype.js) | удаление doctype | `включен` |
|
||||
| [removeXMLProcInst](https://github.com/svg/svgo/blob/master/plugins/removeXMLProcInst.js) | удаление XML-инструкций | `включен` |
|
||||
| [removeComments](https://github.com/svg/svgo/blob/master/plugins/removeComments.js) | удаление комментариев | `включен` |
|
||||
| [removeMetadata](https://github.com/svg/svgo/blob/master/plugins/removeMetadata.js) | удаление `<metadata>` | `включен` |
|
||||
| [removeTitle](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) | удаление `<title>` | `включен` |
|
||||
| [removeDesc](https://github.com/svg/svgo/blob/master/plugins/removeDesc.js) | удаление `<desc>` | `включен` |
|
||||
| [removeUselessDefs](https://github.com/svg/svgo/blob/master/plugins/removeUselessDefs.js) | удаление элементов в `<defs>` без `id` | `включен` |
|
||||
| [removeXMLNS](https://github.com/svg/svgo/blob/master/plugins/removeXMLNS.js) | удаление атрибута xmlns (для заинлайненных svg) | `выключено` |
|
||||
| [removeEditorsNSData](https://github.com/svg/svgo/blob/master/plugins/removeEditorsNSData.js) | удаление пространств имён различных редакторов, их элементов и атрибутов | `включен` |
|
||||
| [removeEmptyAttrs](https://github.com/svg/svgo/blob/master/plugins/removeEmptyAttrs.js) | удаление пустых атрибутов | `включен` |
|
||||
| [removeHiddenElems](https://github.com/svg/svgo/blob/master/plugins/removeHiddenElems.js) | удаление скрытых элементов | `включен` |
|
||||
| [removeEmptyText](https://github.com/svg/svgo/blob/master/plugins/removeEmptyText.js) | удаление пустых текстовых элементов | `включен` |
|
||||
| [removeEmptyContainers](https://github.com/svg/svgo/blob/master/plugins/removeEmptyContainers.js) | удаление пустых элементов-контейнеров | `включен` |
|
||||
| [removeViewBox](https://github.com/svg/svgo/blob/master/plugins/removeViewBox.js) | удаление атрибута `viewBox`, когда это возможно | `включен` |
|
||||
| [cleanupEnableBackground](https://github.com/svg/svgo/blob/master/plugins/cleanupEnableBackground.js) | удаление или оптимизация атрибута `enable-background`, когда это возможно | `включен` |
|
||||
| [minifyStyles](https://github.com/svg/svgo/blob/master/plugins/minifyStyles.js) | уменьшает содержимое элементов `<style>` с помощью [CSSO](https://github.com/css/csso). | `включен` |
|
||||
| [convertStyleToAttrs](https://github.com/svg/svgo/blob/master/plugins/convertStyleToAttrs.js) | конвертирование стилей в атрибуте `style` в отдельные svg-атрибуты | `включен` |
|
||||
| [convertColors](https://github.com/svg/svgo/blob/master/plugins/convertColors.js) | конвертирование цветовых значений: из `rgb()` в `#rrggbb`, из `#rrggbb` в `#rgb` | `включен` |
|
||||
| [convertPathData](https://github.com/svg/svgo/blob/master/plugins/convertPathData.js) | конвертирование данных Path в относительные или абсолютные координаты, смотря что \|короче; конвертирование одних типов сегментов в другие; удаление ненужных разделителей; умное округление и тому подобное | `включен` |
|
||||
| [convertTransform](https://github.com/svg/svgo/blob/master/plugins/convertTransform.js) | схлопывание нескольких трансформаций в одну, конвертирование матриц в короткие алиасы \|и многое другое | `включен` |
|
||||
| [removeUnknownsAndDefaults](https://github.com/svg/svgo/blob/master/plugins/removeUnknownsAndDefaults.js) | удаление неизвестных элементов, контента и атрибутов | `включен` |
|
||||
| [removeNonInheritableGroupAttrs](https://github.com/svg/svgo/blob/master/plugins/removeNonInheritableGroupAttrs.js) | удаление ненаследуемых "презентационных" атрибутов групп | `включен` |
|
||||
| [removeUselessStrokeAndFill](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) | удаление неиспользуемых атрибутов stroke-* и fill-* | `включен` |
|
||||
| [removeUnusedNS](https://github.com/svg/svgo/blob/master/plugins/removeUnusedNS.js) | удаление деклараций неиспользуемых пространств имён | `включен` |
|
||||
| [prefixIds](https://github.com/svg/svgo/blob/master/plugins/prefixIds.js) | добавляет префикс в ID или классы в виде имени файла или произвольной строки | `выключено` |
|
||||
| [cleanupIDs](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) | удаление неиспользуемых и сокращение используемых ID | `включен` |
|
||||
| [cleanupNumericValues](https://github.com/svg/svgo/blob/master/plugins/cleanupNumericValues.js) | округление дробных чисел до заданной точности, удаление `px` как единицы \|измерения по-умолчанию | `включен` |
|
||||
| [cleanupListOfValues](https://github.com/svg/svgo/blob/master/plugins/cleanupListOfValues.js) | округление числовых значений в атрибутах со списком чисел, таких как `viewBox` \|или `enableBackground` | `выключено` |
|
||||
| [moveElemsAttrsToGroup](https://github.com/svg/svgo/blob/master/plugins/moveElemsAttrsToGroup.js) | перемещение совпадающих атрибутов у всех элементов внутри группы `<g>` | `включен` |
|
||||
| [moveGroupAttrsToElems](https://github.com/svg/svgo/blob/master/plugins/moveGroupAttrsToElems.js) | перемещение некоторых атрибутов группы на элементы внутри | `включен` |
|
||||
| [collapseGroups](https://github.com/svg/svgo/blob/master/plugins/collapseGroups.js) | схлопывание бесполезных групп `<g>` | `включен` |
|
||||
| [removeRasterImages](https://github.com/svg/svgo/blob/master/plugins/removeRasterImages.js) | удаление растровых изображений | `выключено` |
|
||||
| [mergePaths](https://github.com/svg/svgo/blob/master/plugins/mergePaths.js) | склеивание нескольких Path в одну кривую | `включен` |
|
||||
| [convertShapeToPath](https://github.com/svg/svgo/blob/master/plugins/convertShapeToPath.js) | конвертирование простых форм в Path | `включен` |
|
||||
| [convertEllipseToCircle](https://github.com/svg/svgo/blob/master/plugins/convertEllipseToCircle.js) | конвертирование вырожденного эллипса `<ellipse>` в круг `<circle>` | `включен` |
|
||||
| [sortAttrs](https://github.com/svg/svgo/blob/master/plugins/sortAttrs.js) | сортировка атрибутов элементов для удобочитаемости | `выключено` |
|
||||
| [sortDefsChildren](https://github.com/svg/svgo/blob/master/plugins/sortDefsChildren.js) | сортировка детей `<defs>` для лучшей компрессии | `включен` |
|
||||
| [removeDimensions](https://github.com/svg/svgo/blob/master/plugins/removeDimensions.js) | удаляет атрибуты width/height при наличии viewBox (противоречит removeViewBox — плагин должен быть выключен) | `выключено` |
|
||||
| [removeAttrs](https://github.com/svg/svgo/blob/master/plugins/removeAttrs.js) | удаляет атрибуты по указанному паттерну | `выключено` |
|
||||
| [removeAttributesBySelector](https://github.com/svg/svgo/blob/master/plugins/removeAttributesBySelector.js) | удаляет атрибуты по CSS-селектору | `выключено` |
|
||||
| [removeElementsByAttr](https://github.com/svg/svgo/blob/master/plugins/removeElementsByAttr.js) | удаляет элементы по указанным ID или классам | `выключено` |
|
||||
| [addClassesToSVGElement](https://github.com/svg/svgo/blob/master/plugins/addClassesToSVGElement.js) | добавляет имена классов корневому элементу `<svg>` | `выключено` |
|
||||
| [addAttributesToSVGElement](https://github.com/svg/svgo/blob/master/plugins/addAttributesToSVGElement.js) | добавляет атрибуты корневому элементу `<svg>` | `выключено` |
|
||||
| [removeOffCanvasPaths](https://github.com/svg/svgo/blob/master/plugins/removeOffCanvasPaths.js) | удаляет элементы вне отрисовываемой области | `выключено` |
|
||||
| [removeStyleElement](https://github.com/svg/svgo/blob/master/plugins/removeStyleElement.js) | удаляет элементы `<style>` | `выключено` |
|
||||
| [removeScriptElement](https://github.com/svg/svgo/blob/master/plugins/removeScriptElement.js) | удаляет элементы `<script>` | `выключено` |
|
||||
| [reusePaths](https://github.com/svg/svgo/blob/master/plugins/reusePaths.js) | Заменяет дублирующиеся элементы <path> ссылками <use> | `выключено` |
|
||||
|
||||
Хотите узнать принципы работы и как написать свой плагин? [Конечно же, да!](https://github.com/svg/svgo/blob/master/docs/how-it-works/ru.md)
|
||||
|
||||
|
||||
## Как использовать
|
||||
|
||||
```sh
|
||||
$ [sudo] npm install -g svgo
|
||||
```
|
||||
|
||||
## Выполнение:
|
||||
|
||||
### Командная строка
|
||||
|
||||
```
|
||||
Запуск:
|
||||
svgo [OPTIONS] [ARGS]
|
||||
|
||||
Параметры:
|
||||
-h, --help : Помощь
|
||||
-v, --version : Версия программы
|
||||
-i INPUT, --input=INPUT : Входной файл, "-" для STDIN
|
||||
-s STRING, --string=STRING : Входная строка SVG
|
||||
-f FOLDER, --folder=FOLDER : Входная папка, оптимизирует и перезаписывает все файлы *.svg
|
||||
-o OUTPUT, --output=OUTPUT : Выходной файл или папка (совпадает с входным по умолчанию), "-" для STDOUT
|
||||
-p PRECISION, --precision=PRECISION : Число цифр после запятой, переопределяет параметры плагинов
|
||||
--config=CONFIG : Файл конфигурации (или строка JSON) для расширения и замены настроек
|
||||
--disable=PLUGIN : Выключение плагина по имени, "--disable=PLUGIN1,PLUGIN2" для отключения нескольких плагинов
|
||||
--enable=PLUGIN : Включение плагина по имени, "--enable=PLUGIN3,PLUGIN4" для отключения нескольких плагинов
|
||||
--datauri=DATAURI : Результат в виде строки Data URI (base64, URI encoded или unencoded)
|
||||
--multipass : Оптимизация в несколько проходов для применения всех возможных оптимизаций
|
||||
--pretty : Удобочитаемое форматирование SVG
|
||||
--indent=INDENT : Размер отступа для удобочитаемого форматирования
|
||||
-r, --recursive : Совместно с '-f'. Рекурсивно обрабатывать *.svg файлы в папках.
|
||||
-q, --quiet : Подавляет вывод информации, выводятся только сообщения об ошибках
|
||||
--show-plugins : Доступные плагины
|
||||
|
||||
Аргументы:
|
||||
INPUT : Аналогично --input
|
||||
```
|
||||
|
||||
* с файлами:
|
||||
|
||||
```sh
|
||||
$ svgo test.svg
|
||||
```
|
||||
|
||||
или:
|
||||
|
||||
```sh
|
||||
$ svgo *.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg -o test.min.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg other.svg third.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg other.svg third.svg -o test.min.svg -o other.min.svg -o third.min.svg
|
||||
```
|
||||
|
||||
* со STDIN / STDOUT:
|
||||
|
||||
```sh
|
||||
$ cat test.svg | svgo -i - -o - > test.min.svg
|
||||
```
|
||||
|
||||
* с папками
|
||||
|
||||
```sh
|
||||
$ svgo -f ../path/to/folder/with/svg/files
|
||||
```
|
||||
|
||||
или:
|
||||
|
||||
```sh
|
||||
$ svgo -f ../path/to/folder/with/svg/files -o ../path/to/folder/with/svg/output
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo *.svg -o ../path/to/folder/with/svg/output
|
||||
```
|
||||
|
||||
* со строками:
|
||||
|
||||
```sh
|
||||
$ svgo -s '<svg version="1.1">test</svg>' -o test.min.svg
|
||||
```
|
||||
|
||||
или даже с Data URI base64:
|
||||
|
||||
```sh
|
||||
$ svgo -s 'data:image/svg+xml;base64,…' -o test.min.svg
|
||||
```
|
||||
|
||||
* с SVGZ:
|
||||
|
||||
из `.svgz` в `.svg`:
|
||||
|
||||
```sh
|
||||
$ gunzip -c test.svgz | svgo -i - -o test.min.svg
|
||||
```
|
||||
|
||||
из `.svg` в `.svgz`:
|
||||
|
||||
```sh
|
||||
$ svgo test.svg -o - | gzip -cfq9 > test.svgz
|
||||
```
|
||||
|
||||
### Другие способы использования SVGO
|
||||
|
||||
* в виде веб-приложения - [SVGOMG](https://jakearchibald.github.io/svgomg/)
|
||||
* как модуль Node.js – [examples](https://github.com/svg/svgo/tree/master/examples)
|
||||
* как таск для Grunt – [grunt-svgmin](https://github.com/sindresorhus/grunt-svgmin)
|
||||
* как таск для Gulp – [gulp-svgmin](https://github.com/ben-eb/gulp-svgmin)
|
||||
* как таск для Mimosa – [mimosa-minify-svg](https://github.com/dbashford/mimosa-minify-svg)
|
||||
* как действие папки в OSX – [svgo-osx-folder-action](https://github.com/svg/svgo-osx-folder-action)
|
||||
* через загрузчик webpack – [image-webpack-loader](https://github.com/tcoopman/image-webpack-loader)
|
||||
* с помощью бота в Telegram – [svgo_bot](https://github.com/maksugr/svgo_bot)
|
||||
* как плагин PostCSS - [postcss-svgo](https://github.com/ben-eb/postcss-svgo)
|
||||
* как плагин для Inkscape – [inkscape-svgo](https://github.com/konsumer/inkscape-svgo)
|
||||
* как плагин для Sketch - [svgo-compressor](https://github.com/BohemianCoding/svgo-compressor)
|
||||
* в виде приложения macOS - [Image Shrinker](https://image-shrinker.com)
|
||||
* как плагин для Rollup - [rollup-plugin-svgo](https://github.com/porsager/rollup-plugin-svgo)
|
||||
|
||||
## Лицензия и копирайты
|
||||
|
||||
Данное программное обеспечение выпускается под [лицензией MIT](https://github.com/svg/svgo/blob/master/LICENSE).
|
||||
|
||||
Логотип – [Егор Большаков](http://xizzzy.ru/).
|
3
assets_old/node_modules/svgo/bin/svgo
generated
vendored
Executable file
3
assets_old/node_modules/svgo/bin/svgo
generated
vendored
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
require('../lib/svgo/coa').run();
|
222
assets_old/node_modules/svgo/lib/css-tools.js
generated
vendored
Normal file
222
assets_old/node_modules/svgo/lib/css-tools.js
generated
vendored
Normal file
|
@ -0,0 +1,222 @@
|
|||
'use strict';
|
||||
|
||||
var csstree = require('css-tree'),
|
||||
List = csstree.List,
|
||||
stable = require('stable'),
|
||||
specificity = require('csso/lib/restructure/prepare/specificity');
|
||||
|
||||
|
||||
/**
|
||||
* Flatten a CSS AST to a selectors list.
|
||||
*
|
||||
* @param {Object} cssAst css-tree AST to flatten
|
||||
* @return {Array} selectors
|
||||
*/
|
||||
function flattenToSelectors(cssAst) {
|
||||
var selectors = [];
|
||||
|
||||
csstree.walk(cssAst, {visit: 'Rule', enter: function(node) {
|
||||
if (node.type !== 'Rule') {
|
||||
return;
|
||||
}
|
||||
|
||||
var atrule = this.atrule;
|
||||
var rule = node;
|
||||
|
||||
node.prelude.children.each(function(selectorNode, selectorItem) {
|
||||
var selector = {
|
||||
item: selectorItem,
|
||||
atrule: atrule,
|
||||
rule: rule,
|
||||
pseudos: []
|
||||
};
|
||||
|
||||
selectorNode.children.each(function(selectorChildNode, selectorChildItem, selectorChildList) {
|
||||
if (selectorChildNode.type === 'PseudoClassSelector' ||
|
||||
selectorChildNode.type === 'PseudoElementSelector') {
|
||||
selector.pseudos.push({
|
||||
item: selectorChildItem,
|
||||
list: selectorChildList
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
selectors.push(selector);
|
||||
});
|
||||
}});
|
||||
|
||||
return selectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter selectors by Media Query.
|
||||
*
|
||||
* @param {Array} selectors to filter
|
||||
* @param {Array} useMqs Array with strings of media queries that should pass (<name> <expression>)
|
||||
* @return {Array} Filtered selectors that match the passed media queries
|
||||
*/
|
||||
function filterByMqs(selectors, useMqs) {
|
||||
return selectors.filter(function(selector) {
|
||||
if (selector.atrule === null) {
|
||||
return ~useMqs.indexOf('');
|
||||
}
|
||||
|
||||
var mqName = selector.atrule.name;
|
||||
var mqStr = mqName;
|
||||
if (selector.atrule.expression &&
|
||||
selector.atrule.expression.children.first().type === 'MediaQueryList') {
|
||||
var mqExpr = csstree.generate(selector.atrule.expression);
|
||||
mqStr = [mqName, mqExpr].join(' ');
|
||||
}
|
||||
|
||||
return ~useMqs.indexOf(mqStr);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter selectors by the pseudo-elements and/or -classes they contain.
|
||||
*
|
||||
* @param {Array} selectors to filter
|
||||
* @param {Array} usePseudos Array with strings of single or sequence of pseudo-elements and/or -classes that should pass
|
||||
* @return {Array} Filtered selectors that match the passed pseudo-elements and/or -classes
|
||||
*/
|
||||
function filterByPseudos(selectors, usePseudos) {
|
||||
return selectors.filter(function(selector) {
|
||||
var pseudoSelectorsStr = csstree.generate({
|
||||
type: 'Selector',
|
||||
children: new List().fromArray(selector.pseudos.map(function(pseudo) {
|
||||
return pseudo.item.data;
|
||||
}))
|
||||
});
|
||||
return ~usePseudos.indexOf(pseudoSelectorsStr);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove pseudo-elements and/or -classes from the selectors for proper matching.
|
||||
*
|
||||
* @param {Array} selectors to clean
|
||||
* @return {Array} Selectors without pseudo-elements and/or -classes
|
||||
*/
|
||||
function cleanPseudos(selectors) {
|
||||
selectors.forEach(function(selector) {
|
||||
selector.pseudos.forEach(function(pseudo) {
|
||||
pseudo.list.remove(pseudo.item);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares two selector specificities.
|
||||
* extracted from https://github.com/keeganstreet/specificity/blob/master/specificity.js#L211
|
||||
*
|
||||
* @param {Array} aSpecificity Specificity of selector A
|
||||
* @param {Array} bSpecificity Specificity of selector B
|
||||
* @return {Number} Score of selector specificity A compared to selector specificity B
|
||||
*/
|
||||
function compareSpecificity(aSpecificity, bSpecificity) {
|
||||
for (var i = 0; i < 4; i += 1) {
|
||||
if (aSpecificity[i] < bSpecificity[i]) {
|
||||
return -1;
|
||||
} else if (aSpecificity[i] > bSpecificity[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare two simple selectors.
|
||||
*
|
||||
* @param {Object} aSimpleSelectorNode Simple selector A
|
||||
* @param {Object} bSimpleSelectorNode Simple selector B
|
||||
* @return {Number} Score of selector A compared to selector B
|
||||
*/
|
||||
function compareSimpleSelectorNode(aSimpleSelectorNode, bSimpleSelectorNode) {
|
||||
var aSpecificity = specificity(aSimpleSelectorNode),
|
||||
bSpecificity = specificity(bSimpleSelectorNode);
|
||||
return compareSpecificity(aSpecificity, bSpecificity);
|
||||
}
|
||||
|
||||
function _bySelectorSpecificity(selectorA, selectorB) {
|
||||
return compareSimpleSelectorNode(selectorA.item.data, selectorB.item.data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sort selectors stably by their specificity.
|
||||
*
|
||||
* @param {Array} selectors to be sorted
|
||||
* @return {Array} Stable sorted selectors
|
||||
*/
|
||||
function sortSelectors(selectors) {
|
||||
return stable(selectors, _bySelectorSpecificity);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a css-tree AST style declaration to CSSStyleDeclaration property.
|
||||
*
|
||||
* @param {Object} declaration css-tree style declaration
|
||||
* @return {Object} CSSStyleDeclaration property
|
||||
*/
|
||||
function csstreeToStyleDeclaration(declaration) {
|
||||
var propertyName = declaration.property,
|
||||
propertyValue = csstree.generate(declaration.value),
|
||||
propertyPriority = (declaration.important ? 'important' : '');
|
||||
return {
|
||||
name: propertyName,
|
||||
value: propertyValue,
|
||||
priority: propertyPriority
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the CSS string of a style element
|
||||
*
|
||||
* @param {Object} element style element
|
||||
* @return {String|Array} CSS string or empty array if no styles are set
|
||||
*/
|
||||
function getCssStr(elem) {
|
||||
return elem.content[0].text || elem.content[0].cdata || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the CSS string of a style element
|
||||
*
|
||||
* @param {Object} element style element
|
||||
* @param {String} CSS string to be set
|
||||
* @return {Object} reference to field with CSS
|
||||
*/
|
||||
function setCssStr(elem, css) {
|
||||
// in case of cdata field
|
||||
if(elem.content[0].cdata) {
|
||||
elem.content[0].cdata = css;
|
||||
return elem.content[0].cdata;
|
||||
}
|
||||
|
||||
// in case of text field + if nothing was set yet
|
||||
elem.content[0].text = css;
|
||||
return elem.content[0].text;
|
||||
}
|
||||
|
||||
|
||||
module.exports.flattenToSelectors = flattenToSelectors;
|
||||
|
||||
module.exports.filterByMqs = filterByMqs;
|
||||
module.exports.filterByPseudos = filterByPseudos;
|
||||
module.exports.cleanPseudos = cleanPseudos;
|
||||
|
||||
module.exports.compareSpecificity = compareSpecificity;
|
||||
module.exports.compareSimpleSelectorNode = compareSimpleSelectorNode;
|
||||
|
||||
module.exports.sortSelectors = sortSelectors;
|
||||
|
||||
module.exports.csstreeToStyleDeclaration = csstreeToStyleDeclaration;
|
||||
|
||||
module.exports.getCssStr = getCssStr;
|
||||
module.exports.setCssStr = setCssStr;
|
90
assets_old/node_modules/svgo/lib/svgo.js
generated
vendored
Executable file
90
assets_old/node_modules/svgo/lib/svgo.js
generated
vendored
Executable file
|
@ -0,0 +1,90 @@
|
|||
'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'),
|
||||
encodeSVGDatauri = require('./svgo/tools.js').encodeSVGDatauri,
|
||||
JS2SVG = require('./svgo/js2svg.js');
|
||||
|
||||
var SVGO = function(config) {
|
||||
this.config = CONFIG(config);
|
||||
};
|
||||
|
||||
SVGO.prototype.optimize = function(svgstr, info) {
|
||||
info = info || {};
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.config.error) {
|
||||
reject(this.config.error);
|
||||
return;
|
||||
}
|
||||
|
||||
var config = this.config,
|
||||
maxPassCount = config.multipass ? 10 : 1,
|
||||
counter = 0,
|
||||
prevResultSize = Number.POSITIVE_INFINITY,
|
||||
optimizeOnceCallback = (svgjs) => {
|
||||
if (svgjs.error) {
|
||||
reject(svgjs.error);
|
||||
return;
|
||||
}
|
||||
|
||||
info.multipassCount = counter;
|
||||
if (++counter < maxPassCount && svgjs.data.length < prevResultSize) {
|
||||
prevResultSize = svgjs.data.length;
|
||||
this._optimizeOnce(svgjs.data, info, optimizeOnceCallback);
|
||||
} else {
|
||||
if (config.datauri) {
|
||||
svgjs.data = encodeSVGDatauri(svgjs.data, config.datauri);
|
||||
}
|
||||
if (info && info.path) {
|
||||
svgjs.path = info.path;
|
||||
}
|
||||
resolve(svgjs);
|
||||
}
|
||||
};
|
||||
|
||||
this._optimizeOnce(svgstr, info, optimizeOnceCallback);
|
||||
});
|
||||
};
|
||||
|
||||
SVGO.prototype._optimizeOnce = function(svgstr, info, callback) {
|
||||
var config = this.config;
|
||||
|
||||
SVG2JS(svgstr, function(svgjs) {
|
||||
if (svgjs.error) {
|
||||
callback(svgjs);
|
||||
return;
|
||||
}
|
||||
|
||||
svgjs = PLUGINS(svgjs, info, 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);
|
||||
};
|
||||
|
||||
SVGO.Config = CONFIG;
|
||||
|
||||
module.exports = SVGO;
|
||||
// Offer ES module interop compatibility.
|
||||
module.exports.default = SVGO;
|
579
assets_old/node_modules/svgo/lib/svgo/coa.js
generated
vendored
Normal file
579
assets_old/node_modules/svgo/lib/svgo/coa.js
generated
vendored
Normal file
|
@ -0,0 +1,579 @@
|
|||
/* jshint quotmark: false */
|
||||
'use strict';
|
||||
|
||||
var FS = require('fs'),
|
||||
PATH = require('path'),
|
||||
chalk = require('chalk'),
|
||||
mkdirp = require('mkdirp'),
|
||||
promisify = require('util.promisify'),
|
||||
readdir = promisify(FS.readdir),
|
||||
readFile = promisify(FS.readFile),
|
||||
writeFile = promisify(FS.writeFile),
|
||||
SVGO = require('../svgo.js'),
|
||||
YAML = require('js-yaml'),
|
||||
PKG = require('../../package.json'),
|
||||
encodeSVGDatauri = require('./tools.js').encodeSVGDatauri,
|
||||
decodeSVGDatauri = require('./tools.js').decodeSVGDatauri,
|
||||
checkIsDir = require('./tools.js').checkIsDir,
|
||||
regSVGFile = /\.svg$/,
|
||||
noop = () => {},
|
||||
svgo;
|
||||
|
||||
/**
|
||||
* 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')
|
||||
.arr()
|
||||
.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')
|
||||
.arr()
|
||||
.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, "--disable={PLUGIN1,PLUGIN2}" for multiple plugins (*nix)')
|
||||
.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, "--enable={PLUGIN3,PLUGIN4}" for multiple plugins (*nix)')
|
||||
.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('Pass over SVGs multiple times to ensure all optimizations are applied')
|
||||
.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('recursive').title('Use with \'-f\'. Optimizes *.svg files in folders recursively.')
|
||||
.short('r').long('recursive')
|
||||
.flag()
|
||||
.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')
|
||||
.arr()
|
||||
.end()
|
||||
.act(function(opts, args) {
|
||||
var input = opts.input || args.input,
|
||||
output = opts.output,
|
||||
config = {};
|
||||
|
||||
// --show-plugins
|
||||
if (opts['show-plugins']) {
|
||||
showAvailablePlugins();
|
||||
return;
|
||||
}
|
||||
|
||||
// w/o anything
|
||||
if (
|
||||
(!input || input[0] === '-') &&
|
||||
!opts.string &&
|
||||
!opts.stdin &&
|
||||
!opts.folder &&
|
||||
process.stdin.isTTY === true
|
||||
) return this.usage();
|
||||
|
||||
if (typeof process == 'object' && process.versions && process.versions.node && PKG && PKG.engines.node) {
|
||||
var nodeVersion = String(PKG.engines.node).match(/\d*(\.\d+)*/)[0];
|
||||
if (parseFloat(process.versions.node) < parseFloat(nodeVersion)) {
|
||||
return printErrorAndExit(`Error: ${PKG.name} requires Node.js version ${nodeVersion} or higher.`);
|
||||
}
|
||||
}
|
||||
|
||||
// --config
|
||||
if (opts.config) {
|
||||
// string
|
||||
if (opts.config.charAt(0) === '{') {
|
||||
try {
|
||||
config = JSON.parse(opts.config);
|
||||
} catch (e) {
|
||||
return printErrorAndExit(`Error: Couldn't parse config JSON.\n${String(e)}`);
|
||||
}
|
||||
// external file
|
||||
} else {
|
||||
var configPath = PATH.resolve(opts.config),
|
||||
configData;
|
||||
try {
|
||||
// require() adds some weird output on YML files
|
||||
configData = FS.readFileSync(configPath, 'utf8');
|
||||
config = JSON.parse(configData);
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
return printErrorAndExit(`Error: couldn't find config file '${opts.config}'.`);
|
||||
} else if (err.code === 'EISDIR') {
|
||||
return printErrorAndExit(`Error: directory '${opts.config}' is not a config file.`);
|
||||
}
|
||||
config = YAML.safeLoad(configData);
|
||||
config.__DIR = PATH.dirname(configPath); // will use it to resolve custom plugins defined via path
|
||||
|
||||
if (!config || Array.isArray(config)) {
|
||||
return printErrorAndExit(`Error: invalid config file '${opts.config}'.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --quiet
|
||||
if (opts.quiet) {
|
||||
config.quiet = opts.quiet;
|
||||
}
|
||||
|
||||
// --recursive
|
||||
if (opts.recursive) {
|
||||
config.recursive = opts.recursive;
|
||||
}
|
||||
|
||||
// --precision
|
||||
if (opts.precision) {
|
||||
var precision = Math.min(Math.max(0, parseInt(opts.precision)), 20);
|
||||
if (!isNaN(precision)) {
|
||||
config.floatPrecision = 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;
|
||||
var indent;
|
||||
if (opts.indent && !isNaN(indent = parseInt(opts.indent))) {
|
||||
config.js2svg.indent = indent;
|
||||
}
|
||||
}
|
||||
|
||||
svgo = new SVGO(config);
|
||||
|
||||
// --output
|
||||
if (output) {
|
||||
if (input && input[0] != '-') {
|
||||
if (output.length == 1 && checkIsDir(output[0])) {
|
||||
var dir = output[0];
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
output[i] = checkIsDir(input[i]) ? input[i] : PATH.resolve(dir, PATH.basename(input[i]));
|
||||
}
|
||||
} else if (output.length < input.length) {
|
||||
output = output.concat(input.slice(output.length));
|
||||
}
|
||||
}
|
||||
} else if (input) {
|
||||
output = input;
|
||||
} else if (opts.string) {
|
||||
output = '-';
|
||||
}
|
||||
|
||||
if (opts.datauri) {
|
||||
config.datauri = opts.datauri;
|
||||
}
|
||||
|
||||
// --folder
|
||||
if (opts.folder) {
|
||||
var ouputFolder = output && output[0] || opts.folder;
|
||||
return optimizeFolder(config, opts.folder, ouputFolder).then(noop, printErrorAndExit);
|
||||
}
|
||||
|
||||
// --input
|
||||
if (input) {
|
||||
// STDIN
|
||||
if (input[0] === '-') {
|
||||
return new Promise((resolve, reject) => {
|
||||
var data = '',
|
||||
file = output[0];
|
||||
|
||||
process.stdin
|
||||
.on('data', chunk => data += chunk)
|
||||
.once('end', () => processSVGData(config, {input: 'string'}, data, file).then(resolve, reject));
|
||||
});
|
||||
// file
|
||||
} else {
|
||||
return Promise.all(input.map((file, n) => optimizeFile(config, file, output[n])))
|
||||
.then(noop, printErrorAndExit);
|
||||
}
|
||||
|
||||
// --string
|
||||
} else if (opts.string) {
|
||||
var data = decodeSVGDatauri(opts.string);
|
||||
|
||||
return processSVGData(config, {input: 'string'}, data, output[0]);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
names.forEach(flattenPluginsCbk);
|
||||
|
||||
// extend config
|
||||
if (config.plugins) {
|
||||
for (var name of names) {
|
||||
var matched = false,
|
||||
key;
|
||||
|
||||
for (var plugin of config.plugins) {
|
||||
// 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) {
|
||||
// push new plugin Object
|
||||
config.plugins.push({ [name]: state });
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
// just push
|
||||
} else {
|
||||
config.plugins = names.map(name => ({ [name]: state }));
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten an array of plugins by invoking this callback on each element
|
||||
* whose value may be a comma separated list of plugins.
|
||||
*
|
||||
* @param {String} name Plugin name
|
||||
* @param {Number} index Plugin index
|
||||
* @param {Array} names Plugins being traversed
|
||||
*/
|
||||
function flattenPluginsCbk(name, index, names)
|
||||
{
|
||||
var split = name.split(',');
|
||||
|
||||
if(split.length > 1) {
|
||||
names[index] = split.shift();
|
||||
names.push.apply(names, split);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimize SVG files in a directory.
|
||||
* @param {Object} config options
|
||||
* @param {string} dir input directory
|
||||
* @param {string} output output directory
|
||||
* @return {Promise}
|
||||
*/
|
||||
function optimizeFolder(config, dir, output) {
|
||||
if (!config.quiet) {
|
||||
console.log(`Processing directory '${dir}':\n`);
|
||||
}
|
||||
return readdir(dir).then(files => processDirectory(config, dir, files, output));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process given files, take only SVG.
|
||||
* @param {Object} config options
|
||||
* @param {string} dir input directory
|
||||
* @param {Array} files list of file names in the directory
|
||||
* @param {string} output output directory
|
||||
* @return {Promise}
|
||||
*/
|
||||
function processDirectory(config, dir, files, output) {
|
||||
// take only *.svg files, recursively if necessary
|
||||
var svgFilesDescriptions = getFilesDescriptions(config, dir, files, output);
|
||||
|
||||
return svgFilesDescriptions.length ?
|
||||
Promise.all(svgFilesDescriptions.map(fileDescription => optimizeFile(config, fileDescription.inputPath, fileDescription.outputPath))) :
|
||||
Promise.reject(new Error(`No SVG files have been found in '${dir}' directory.`));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get svg files descriptions
|
||||
* @param {Object} config options
|
||||
* @param {string} dir input directory
|
||||
* @param {Array} files list of file names in the directory
|
||||
* @param {string} output output directory
|
||||
* @return {Array}
|
||||
*/
|
||||
function getFilesDescriptions(config, dir, files, output) {
|
||||
const filesInThisFolder = files
|
||||
.filter(name => regSVGFile.test(name))
|
||||
.map(name => ({
|
||||
inputPath: PATH.resolve(dir, name),
|
||||
outputPath: PATH.resolve(output, name),
|
||||
}));
|
||||
|
||||
return config.recursive ?
|
||||
[].concat(
|
||||
filesInThisFolder,
|
||||
files
|
||||
.filter(name => checkIsDir(PATH.resolve(dir, name)))
|
||||
.map(subFolderName => {
|
||||
const subFolderPath = PATH.resolve(dir, subFolderName);
|
||||
const subFolderFiles = FS.readdirSync(subFolderPath);
|
||||
const subFolderOutput = PATH.resolve(output, subFolderName);
|
||||
return getFilesDescriptions(config, subFolderPath, subFolderFiles, subFolderOutput);
|
||||
})
|
||||
.reduce((a, b) => [].concat(a, b), [])
|
||||
) :
|
||||
filesInThisFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read SVG file and pass to processing.
|
||||
* @param {Object} config options
|
||||
* @param {string} file
|
||||
* @param {string} output
|
||||
* @return {Promise}
|
||||
*/
|
||||
function optimizeFile(config, file, output) {
|
||||
return readFile(file, 'utf8').then(
|
||||
data => processSVGData(config, {input: 'file', path: file}, data, output, file),
|
||||
error => checkOptimizeFileError(config, file, output, error)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimize SVG data.
|
||||
* @param {Object} config options
|
||||
* @param {string} data SVG content to optimize
|
||||
* @param {string} output where to write optimized file
|
||||
* @param {string} [input] input file name (being used if output is a directory)
|
||||
* @return {Promise}
|
||||
*/
|
||||
function processSVGData(config, info, data, output, input) {
|
||||
var startTime = Date.now(),
|
||||
prevFileSize = Buffer.byteLength(data, 'utf8');
|
||||
|
||||
return svgo.optimize(data, info).then(function(result) {
|
||||
if (config.datauri) {
|
||||
result.data = encodeSVGDatauri(result.data, config.datauri);
|
||||
}
|
||||
var resultFileSize = Buffer.byteLength(result.data, 'utf8'),
|
||||
processingTime = Date.now() - startTime;
|
||||
|
||||
return writeOutput(input, output, result.data).then(function() {
|
||||
if (!config.quiet && output != '-') {
|
||||
if (input) {
|
||||
console.log(`\n${PATH.basename(input)}:`);
|
||||
}
|
||||
printTimeInfo(processingTime);
|
||||
printProfitInfo(prevFileSize, resultFileSize);
|
||||
}
|
||||
},
|
||||
error => Promise.reject(new Error(error.code === 'ENOTDIR' ? `Error: output '${output}' is not a directory.` : error)));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Write result of an optimization.
|
||||
* @param {string} input
|
||||
* @param {string} output output file name. '-' for stdout
|
||||
* @param {string} data data to write
|
||||
* @return {Promise}
|
||||
*/
|
||||
function writeOutput(input, output, data) {
|
||||
if (output == '-') {
|
||||
console.log(data);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
mkdirp.sync(PATH.dirname(output));
|
||||
|
||||
return writeFile(output, data, 'utf8').catch(error => checkWriteFileError(input, output, data, error));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write a time taken by optimization.
|
||||
* @param {number} time time in milliseconds.
|
||||
*/
|
||||
function printTimeInfo(time) {
|
||||
console.log(`Done in ${time} ms!`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write optimizing information in human readable format.
|
||||
* @param {number} inBytes size before optimization.
|
||||
* @param {number} outBytes size after optimization.
|
||||
*/
|
||||
function printProfitInfo(inBytes, outBytes) {
|
||||
var profitPercents = 100 - outBytes * 100 / inBytes;
|
||||
|
||||
console.log(
|
||||
(Math.round((inBytes / 1024) * 1000) / 1000) + ' KiB' +
|
||||
(profitPercents < 0 ? ' + ' : ' - ') +
|
||||
chalk.green(Math.abs((Math.round(profitPercents * 10) / 10)) + '%') + ' = ' +
|
||||
(Math.round((outBytes / 1024) * 1000) / 1000) + ' KiB'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for errors, if it's a dir optimize the dir.
|
||||
* @param {Object} config
|
||||
* @param {string} input
|
||||
* @param {string} output
|
||||
* @param {Error} error
|
||||
* @return {Promise}
|
||||
*/
|
||||
function checkOptimizeFileError(config, input, output, error) {
|
||||
if (error.code == 'EISDIR') {
|
||||
return optimizeFolder(config, input, output);
|
||||
} else if (error.code == 'ENOENT') {
|
||||
return Promise.reject(new Error(`Error: no such file or directory '${error.path}'.`));
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for saving file error. If the output is a dir, then write file there.
|
||||
* @param {string} input
|
||||
* @param {string} output
|
||||
* @param {string} data
|
||||
* @param {Error} error
|
||||
* @return {Promise}
|
||||
*/
|
||||
function checkWriteFileError(input, output, data, error) {
|
||||
if (error.code == 'EISDIR' && input) {
|
||||
return writeFile(PATH.resolve(output, PATH.basename(input)), data, 'utf8');
|
||||
} else {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show list of available plugins with short description.
|
||||
*/
|
||||
function showAvailablePlugins() {
|
||||
console.log('Currently available plugins:');
|
||||
|
||||
// Flatten an array of plugins grouped per type, sort and write output
|
||||
var list = [].concat.apply([], new SVGO().config.plugins)
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map(plugin => ` [ ${chalk.green(plugin.name)} ] ${plugin.description}`)
|
||||
.join('\n');
|
||||
console.log(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an error and exit.
|
||||
* @param {Error} error
|
||||
* @return {Promise} a promise for running tests
|
||||
*/
|
||||
function printErrorAndExit(error) {
|
||||
console.error(chalk.red(error));
|
||||
process.exit(1);
|
||||
return Promise.reject(error); // for tests
|
||||
}
|
250
assets_old/node_modules/svgo/lib/svgo/config.js
generated
vendored
Normal file
250
assets_old/node_modules/svgo/lib/svgo/config.js
generated
vendored
Normal file
|
@ -0,0 +1,250 @@
|
|||
'use strict';
|
||||
|
||||
var FS = require('fs');
|
||||
var PATH = require('path');
|
||||
var yaml = require('js-yaml');
|
||||
|
||||
/**
|
||||
* 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(config, defaults.plugins);
|
||||
}
|
||||
} else {
|
||||
defaults = Object.assign({}, yaml.safeLoad(FS.readFileSync(__dirname + '/../../.svgo.yml', 'utf8')));
|
||||
defaults.plugins = preparePluginsArray(config, 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 = Object.assign({}, plugin.params, { floatPrecision: config.floatPrecision });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ('datauri' in config) {
|
||||
defaults.datauri = config.datauri;
|
||||
}
|
||||
|
||||
if (Array.isArray(defaults.plugins)) {
|
||||
defaults.plugins = optimizePluginsArray(defaults.plugins);
|
||||
}
|
||||
|
||||
return defaults;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Require() all plugins in array.
|
||||
*
|
||||
* @param {Object} config
|
||||
* @param {Array} plugins input plugins array
|
||||
* @return {Array} input plugins array of arrays
|
||||
*/
|
||||
function preparePluginsArray(config, 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 = setPluginActiveState(
|
||||
loadPlugin(config, key, item[key].path),
|
||||
item,
|
||||
key
|
||||
);
|
||||
plugin.name = key;
|
||||
}
|
||||
|
||||
// name
|
||||
} else {
|
||||
|
||||
plugin = loadPlugin(config, item);
|
||||
plugin.name = item;
|
||||
if (typeof plugin.params === 'object') {
|
||||
plugin.params = Object.assign({}, plugin.params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
if (item[key] == null) {
|
||||
console.error(`Error: '${key}' plugin is misconfigured! Have you padded its content in YML properly?\n`);
|
||||
}
|
||||
|
||||
// custom
|
||||
if (typeof item[key] === 'object' && item[key].fn && typeof item[key].fn === 'function') {
|
||||
defaults.plugins.push(setupCustomPlugin(key, item[key]));
|
||||
|
||||
// plugin defined via path
|
||||
} else if (typeof item[key] === 'object' && item[key].path) {
|
||||
defaults.plugins.push(setPluginActiveState(loadPlugin(config, undefined, item[key].path), item, key));
|
||||
|
||||
} else {
|
||||
defaults.plugins.forEach(function(plugin) {
|
||||
|
||||
if (plugin.name === key) {
|
||||
plugin = setPluginActiveState(plugin, item, key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
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 = Object.assign({}, 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;
|
||||
}, []);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets plugin to active or inactive state.
|
||||
*
|
||||
* @param {Object} plugin
|
||||
* @param {Object} item
|
||||
* @param {Object} key
|
||||
* @return {Object} plugin
|
||||
*/
|
||||
function setPluginActiveState(plugin, item, key) {
|
||||
// name: {}
|
||||
if (typeof item[key] === 'object') {
|
||||
plugin.params = Object.assign({}, 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;
|
||||
}
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads default plugin using name or custom plugin defined via path in config.
|
||||
*
|
||||
* @param {Object} config
|
||||
* @param {Object} name
|
||||
* @param {Object} path
|
||||
* @return {Object} plugin
|
||||
*/
|
||||
function loadPlugin(config, name, path) {
|
||||
var plugin;
|
||||
|
||||
if (!path) {
|
||||
plugin = require('../../plugins/' + name);
|
||||
} else {
|
||||
plugin = require(PATH.resolve(config.__DIR, path));
|
||||
}
|
||||
|
||||
return Object.assign({}, plugin);
|
||||
}
|
138
assets_old/node_modules/svgo/lib/svgo/css-class-list.js
generated
vendored
Normal file
138
assets_old/node_modules/svgo/lib/svgo/css-class-list.js
generated
vendored
Normal file
|
@ -0,0 +1,138 @@
|
|||
'use strict';
|
||||
|
||||
var values = require('object.values');
|
||||
if (!Object.values) {
|
||||
values.shim();
|
||||
}
|
||||
|
||||
|
||||
var CSSClassList = function(node) {
|
||||
this.parentNode = node;
|
||||
this.classNames = new Set();
|
||||
this.classAttr = null;
|
||||
//this.classValue = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs a deep clone of this object.
|
||||
*
|
||||
* @param parentNode the parentNode to assign to the cloned result
|
||||
*/
|
||||
CSSClassList.prototype.clone = function(parentNode) {
|
||||
var node = this;
|
||||
var nodeData = {};
|
||||
|
||||
Object.keys(node).forEach(function(key) {
|
||||
if (key !== 'parentNode') {
|
||||
nodeData[key] = node[key];
|
||||
}
|
||||
});
|
||||
|
||||
// Deep-clone node data.
|
||||
nodeData = JSON.parse(JSON.stringify(nodeData));
|
||||
|
||||
var clone = new CSSClassList(parentNode);
|
||||
Object.assign(clone, nodeData);
|
||||
return clone;
|
||||
};
|
||||
|
||||
CSSClassList.prototype.hasClass = function() {
|
||||
this.classAttr = { // empty class attr
|
||||
'name': 'class',
|
||||
'value': null
|
||||
};
|
||||
|
||||
this.addClassHandler();
|
||||
};
|
||||
|
||||
|
||||
// attr.class
|
||||
|
||||
CSSClassList.prototype.addClassHandler = function() {
|
||||
|
||||
Object.defineProperty(this.parentNode.attrs, 'class', {
|
||||
get: this.getClassAttr.bind(this),
|
||||
set: this.setClassAttr.bind(this),
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
this.addClassValueHandler();
|
||||
};
|
||||
|
||||
// attr.class.value
|
||||
|
||||
CSSClassList.prototype.addClassValueHandler = function() {
|
||||
|
||||
Object.defineProperty(this.classAttr, 'value', {
|
||||
get: this.getClassValue.bind(this),
|
||||
set: this.setClassValue.bind(this),
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
};
|
||||
|
||||
CSSClassList.prototype.getClassAttr = function() {
|
||||
return this.classAttr;
|
||||
};
|
||||
|
||||
CSSClassList.prototype.setClassAttr = function(newClassAttr) {
|
||||
this.setClassValue(newClassAttr.value); // must before applying value handler!
|
||||
|
||||
this.classAttr = newClassAttr;
|
||||
this.addClassValueHandler();
|
||||
};
|
||||
|
||||
CSSClassList.prototype.getClassValue = function() {
|
||||
var arrClassNames = Array.from(this.classNames);
|
||||
return arrClassNames.join(' ');
|
||||
};
|
||||
|
||||
CSSClassList.prototype.setClassValue = function(newValue) {
|
||||
if(typeof newValue === 'undefined') {
|
||||
this.classNames.clear();
|
||||
return;
|
||||
}
|
||||
var arrClassNames = newValue.split(' ');
|
||||
this.classNames = new Set(arrClassNames);
|
||||
};
|
||||
|
||||
|
||||
CSSClassList.prototype.add = function(/* variadic */) {
|
||||
this.hasClass();
|
||||
Object.values(arguments).forEach(this._addSingle.bind(this));
|
||||
};
|
||||
|
||||
CSSClassList.prototype._addSingle = function(className) {
|
||||
this.classNames.add(className);
|
||||
};
|
||||
|
||||
|
||||
CSSClassList.prototype.remove = function(/* variadic */) {
|
||||
this.hasClass();
|
||||
Object.values(arguments).forEach(this._removeSingle.bind(this));
|
||||
};
|
||||
|
||||
CSSClassList.prototype._removeSingle = function(className) {
|
||||
this.classNames.delete(className);
|
||||
};
|
||||
|
||||
|
||||
CSSClassList.prototype.item = function(index) {
|
||||
var arrClassNames = Array.from(this.classNames);
|
||||
return arrClassNames[index];
|
||||
};
|
||||
|
||||
CSSClassList.prototype.toggle = function(className, force) {
|
||||
if(this.contains(className) || force === false) {
|
||||
this.classNames.delete(className);
|
||||
}
|
||||
this.classNames.add(className);
|
||||
};
|
||||
|
||||
CSSClassList.prototype.contains = function(className) {
|
||||
return this.classNames.has(className);
|
||||
};
|
||||
|
||||
|
||||
module.exports = CSSClassList;
|
53
assets_old/node_modules/svgo/lib/svgo/css-select-adapter.js
generated
vendored
Normal file
53
assets_old/node_modules/svgo/lib/svgo/css-select-adapter.js
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
'use strict';
|
||||
|
||||
var baseCssAdapter = require('css-select-base-adapter');
|
||||
|
||||
/**
|
||||
* DOMUtils API for SVGO AST (used by css-select)
|
||||
*/
|
||||
var svgoCssSelectAdapterMin = {
|
||||
|
||||
// is the node a tag?
|
||||
// isTag: ( node:Node ) => isTag:Boolean
|
||||
isTag: function(node) {
|
||||
return node.isElem();
|
||||
},
|
||||
|
||||
// get the parent of the node
|
||||
// getParent: ( node:Node ) => parentNode:Node
|
||||
// returns null when no parent exists
|
||||
getParent: function(node) {
|
||||
return node.parentNode || null;
|
||||
},
|
||||
|
||||
// get the node's children
|
||||
// getChildren: ( node:Node ) => children:[Node]
|
||||
getChildren: function(node) {
|
||||
return node.content || [];
|
||||
},
|
||||
|
||||
// get the name of the tag
|
||||
// getName: ( elem:ElementNode ) => tagName:String
|
||||
getName: function(elemAst) {
|
||||
return elemAst.elem;
|
||||
},
|
||||
|
||||
// get the text content of the node, and its children if it has any
|
||||
// getText: ( node:Node ) => text:String
|
||||
// returns empty string when there is no text
|
||||
getText: function(node) {
|
||||
return node.content[0].text || node.content[0].cdata || '';
|
||||
},
|
||||
|
||||
// get the attribute value
|
||||
// getAttributeValue: ( elem:ElementNode, name:String ) => value:String
|
||||
// returns null when attribute doesn't exist
|
||||
getAttributeValue: function(elem, name) {
|
||||
return elem.hasAttr(name) ? elem.attr(name).value : null;
|
||||
}
|
||||
};
|
||||
|
||||
// use base adapter for default implementation
|
||||
var svgoCssSelectAdapter = baseCssAdapter(svgoCssSelectAdapterMin);
|
||||
|
||||
module.exports = svgoCssSelectAdapter;
|
285
assets_old/node_modules/svgo/lib/svgo/css-style-declaration.js
generated
vendored
Normal file
285
assets_old/node_modules/svgo/lib/svgo/css-style-declaration.js
generated
vendored
Normal file
|
@ -0,0 +1,285 @@
|
|||
'use strict';
|
||||
|
||||
var csstree = require('css-tree'),
|
||||
csstools = require('../css-tools');
|
||||
|
||||
|
||||
var CSSStyleDeclaration = function(node) {
|
||||
this.parentNode = node;
|
||||
|
||||
this.properties = new Map();
|
||||
this.hasSynced = false;
|
||||
|
||||
this.styleAttr = null;
|
||||
this.styleValue = null;
|
||||
|
||||
this.parseError = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs a deep clone of this object.
|
||||
*
|
||||
* @param parentNode the parentNode to assign to the cloned result
|
||||
*/
|
||||
CSSStyleDeclaration.prototype.clone = function(parentNode) {
|
||||
var node = this;
|
||||
var nodeData = {};
|
||||
|
||||
Object.keys(node).forEach(function(key) {
|
||||
if (key !== 'parentNode') {
|
||||
nodeData[key] = node[key];
|
||||
}
|
||||
});
|
||||
|
||||
// Deep-clone node data.
|
||||
nodeData = JSON.parse(JSON.stringify(nodeData));
|
||||
|
||||
var clone = new CSSStyleDeclaration(parentNode);
|
||||
Object.assign(clone, nodeData);
|
||||
return clone;
|
||||
};
|
||||
|
||||
CSSStyleDeclaration.prototype.hasStyle = function() {
|
||||
this.addStyleHandler();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// attr.style
|
||||
|
||||
CSSStyleDeclaration.prototype.addStyleHandler = function() {
|
||||
|
||||
this.styleAttr = { // empty style attr
|
||||
'name': 'style',
|
||||
'value': null
|
||||
};
|
||||
|
||||
Object.defineProperty(this.parentNode.attrs, 'style', {
|
||||
get: this.getStyleAttr.bind(this),
|
||||
set: this.setStyleAttr.bind(this),
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
this.addStyleValueHandler();
|
||||
};
|
||||
|
||||
// attr.style.value
|
||||
|
||||
CSSStyleDeclaration.prototype.addStyleValueHandler = function() {
|
||||
|
||||
Object.defineProperty(this.styleAttr, 'value', {
|
||||
get: this.getStyleValue.bind(this),
|
||||
set: this.setStyleValue.bind(this),
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
};
|
||||
|
||||
CSSStyleDeclaration.prototype.getStyleAttr = function() {
|
||||
return this.styleAttr;
|
||||
};
|
||||
|
||||
CSSStyleDeclaration.prototype.setStyleAttr = function(newStyleAttr) {
|
||||
this.setStyleValue(newStyleAttr.value); // must before applying value handler!
|
||||
|
||||
this.styleAttr = newStyleAttr;
|
||||
this.addStyleValueHandler();
|
||||
this.hasSynced = false; // raw css changed
|
||||
};
|
||||
|
||||
CSSStyleDeclaration.prototype.getStyleValue = function() {
|
||||
return this.getCssText();
|
||||
};
|
||||
|
||||
CSSStyleDeclaration.prototype.setStyleValue = function(newValue) {
|
||||
this.properties.clear(); // reset all existing properties
|
||||
this.styleValue = newValue;
|
||||
this.hasSynced = false; // raw css changed
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
CSSStyleDeclaration.prototype._loadCssText = function() {
|
||||
if (this.hasSynced) {
|
||||
return;
|
||||
}
|
||||
this.hasSynced = true; // must be set here to prevent loop in setProperty(...)
|
||||
|
||||
if (!this.styleValue || this.styleValue.length === 0) {
|
||||
return;
|
||||
}
|
||||
var inlineCssStr = this.styleValue;
|
||||
|
||||
var declarations = {};
|
||||
try {
|
||||
declarations = csstree.parse(inlineCssStr, {
|
||||
context: 'declarationList',
|
||||
parseValue: false
|
||||
});
|
||||
} catch (parseError) {
|
||||
this.parseError = parseError;
|
||||
return;
|
||||
}
|
||||
this.parseError = false;
|
||||
|
||||
var self = this;
|
||||
declarations.children.each(function(declaration) {
|
||||
try {
|
||||
var styleDeclaration = csstools.csstreeToStyleDeclaration(declaration);
|
||||
self.setProperty(styleDeclaration.name, styleDeclaration.value, styleDeclaration.priority);
|
||||
} catch(styleError) {
|
||||
if(styleError.message !== 'Unknown node type: undefined') {
|
||||
self.parseError = styleError;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// only reads from properties
|
||||
|
||||
/**
|
||||
* Get the textual representation of the declaration block (equivalent to .cssText attribute).
|
||||
*
|
||||
* @return {String} Textual representation of the declaration block (empty string for no properties)
|
||||
*/
|
||||
CSSStyleDeclaration.prototype.getCssText = function() {
|
||||
var properties = this.getProperties();
|
||||
|
||||
if (this.parseError) {
|
||||
// in case of a parse error, pass through original styles
|
||||
return this.styleValue;
|
||||
}
|
||||
|
||||
var cssText = [];
|
||||
properties.forEach(function(property, propertyName) {
|
||||
var strImportant = property.priority === 'important' ? '!important' : '';
|
||||
cssText.push(propertyName.trim() + ':' + property.value.trim() + strImportant);
|
||||
});
|
||||
return cssText.join(';');
|
||||
};
|
||||
|
||||
CSSStyleDeclaration.prototype._handleParseError = function() {
|
||||
if (this.parseError) {
|
||||
console.warn('Warning: Parse error when parsing inline styles, style properties of this element cannot be used. The raw styles can still be get/set using .attr(\'style\').value. Error details: ' + this.parseError);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
CSSStyleDeclaration.prototype._getProperty = function(propertyName) {
|
||||
if(typeof propertyName === 'undefined') {
|
||||
throw Error('1 argument required, but only 0 present.');
|
||||
}
|
||||
|
||||
var properties = this.getProperties();
|
||||
this._handleParseError();
|
||||
|
||||
var property = properties.get(propertyName.trim());
|
||||
return property;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the optional priority, "important".
|
||||
*
|
||||
* @param {String} propertyName representing the property name to be checked.
|
||||
* @return {String} priority that represents the priority (e.g. "important") if one exists. If none exists, returns the empty string.
|
||||
*/
|
||||
CSSStyleDeclaration.prototype.getPropertyPriority = function(propertyName) {
|
||||
var property = this._getProperty(propertyName);
|
||||
return property ? property.priority : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the property value given a property name.
|
||||
*
|
||||
* @param {String} propertyName representing the property name to be checked.
|
||||
* @return {String} value containing the value of the property. If not set, returns the empty string.
|
||||
*/
|
||||
CSSStyleDeclaration.prototype.getPropertyValue = function(propertyName) {
|
||||
var property = this._getProperty(propertyName);
|
||||
return property ? property.value : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a property name.
|
||||
*
|
||||
* @param {Number} index of the node to be fetched. The index is zero-based.
|
||||
* @return {String} propertyName that is the name of the CSS property at the specified index.
|
||||
*/
|
||||
CSSStyleDeclaration.prototype.item = function(index) {
|
||||
if(typeof index === 'undefined') {
|
||||
throw Error('1 argument required, but only 0 present.');
|
||||
}
|
||||
|
||||
var properties = this.getProperties();
|
||||
this._handleParseError();
|
||||
|
||||
return Array.from(properties.keys())[index];
|
||||
};
|
||||
|
||||
/**
|
||||
* Return all properties of the node.
|
||||
*
|
||||
* @return {Map} properties that is a Map with propertyName as key and property (propertyValue + propertyPriority) as value.
|
||||
*/
|
||||
CSSStyleDeclaration.prototype.getProperties = function() {
|
||||
this._loadCssText();
|
||||
return this.properties;
|
||||
};
|
||||
|
||||
|
||||
// writes to properties
|
||||
|
||||
/**
|
||||
* Remove a property from the CSS declaration block.
|
||||
*
|
||||
* @param {String} propertyName representing the property name to be removed.
|
||||
* @return {String} oldValue equal to the value of the CSS property before it was removed.
|
||||
*/
|
||||
CSSStyleDeclaration.prototype.removeProperty = function(propertyName) {
|
||||
if(typeof propertyName === 'undefined') {
|
||||
throw Error('1 argument required, but only 0 present.');
|
||||
}
|
||||
|
||||
this.hasStyle();
|
||||
|
||||
var properties = this.getProperties();
|
||||
this._handleParseError();
|
||||
|
||||
var oldValue = this.getPropertyValue(propertyName);
|
||||
properties.delete(propertyName.trim());
|
||||
return oldValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Modify an existing CSS property or creates a new CSS property in the declaration block.
|
||||
*
|
||||
* @param {String} propertyName representing the CSS property name to be modified.
|
||||
* @param {String} [value] containing the new property value. If not specified, treated as the empty string. value must not contain "!important" -- that should be set using the priority parameter.
|
||||
* @param {String} [priority] allowing the "important" CSS priority to be set. If not specified, treated as the empty string.
|
||||
* @return {undefined}
|
||||
*/
|
||||
CSSStyleDeclaration.prototype.setProperty = function(propertyName, value, priority) {
|
||||
if(typeof propertyName === 'undefined') {
|
||||
throw Error('propertyName argument required, but only not present.');
|
||||
}
|
||||
|
||||
this.hasStyle();
|
||||
|
||||
var properties = this.getProperties();
|
||||
this._handleParseError();
|
||||
|
||||
var property = {
|
||||
value: value.trim(),
|
||||
priority: priority.trim()
|
||||
};
|
||||
properties.set(propertyName.trim(), property);
|
||||
|
||||
return property;
|
||||
};
|
||||
|
||||
|
||||
module.exports = CSSStyleDeclaration;
|
348
assets_old/node_modules/svgo/lib/svgo/js2svg.js
generated
vendored
Normal file
348
assets_old/node_modules/svgo/lib/svgo/js2svg.js
generated
vendored
Normal file
|
@ -0,0 +1,348 @@
|
|||
'use strict';
|
||||
|
||||
var EOL = require('os').EOL,
|
||||
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 = {
|
||||
'&': '&',
|
||||
'\'': ''',
|
||||
'"': '"',
|
||||
'>': '>',
|
||||
'<': '<',
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 = Object.assign({}, defaults, config);
|
||||
} else {
|
||||
this.config = Object.assign({}, defaults);
|
||||
}
|
||||
|
||||
var indent = this.config.indent;
|
||||
if (typeof indent == 'number' && !isNaN(indent)) {
|
||||
this.config.indent = (indent < 0) ? '\t' : ' '.repeat(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) {
|
||||
indent = this.config.indent.repeat(this.indentLevel - 1);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
};
|
372
assets_old/node_modules/svgo/lib/svgo/jsAPI.js
generated
vendored
Normal file
372
assets_old/node_modules/svgo/lib/svgo/jsAPI.js
generated
vendored
Normal file
|
@ -0,0 +1,372 @@
|
|||
'use strict';
|
||||
|
||||
var cssSelect = require('css-select');
|
||||
|
||||
var svgoCssSelectAdapter = require('./css-select-adapter');
|
||||
var cssSelectOpts = {
|
||||
xmlMode: true,
|
||||
adapter: svgoCssSelectAdapter
|
||||
};
|
||||
|
||||
var JSAPI = module.exports = function(data, parentNode) {
|
||||
Object.assign(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 !== 'class' && key !== 'style' && key !== 'content') {
|
||||
nodeData[key] = node[key];
|
||||
}
|
||||
});
|
||||
|
||||
// Deep-clone node data.
|
||||
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.class) {
|
||||
clonedNode.class = node.class.clone(clonedNode);
|
||||
}
|
||||
if (node.style) {
|
||||
clonedNode.style = node.style.clone(clonedNode);
|
||||
}
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the closest ancestor of the current element.
|
||||
* @param elemName
|
||||
*
|
||||
* @return {?Object}
|
||||
*/
|
||||
JSAPI.prototype.closestElem = function(elemName) {
|
||||
var elem = this;
|
||||
|
||||
while ((elem = elem.parentNode) && !elem.isElem(elemName));
|
||||
|
||||
return elem;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if(attr.name === 'class') { // newly added class attribute
|
||||
this.class.hasClass();
|
||||
}
|
||||
|
||||
if(attr.name === 'style') { // newly added style attribute
|
||||
this.style.hasStyle();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Evaluate a string of CSS selectors against the element and returns matched elements.
|
||||
*
|
||||
* @param {String} selectors CSS selector(s) string
|
||||
* @return {Array} null if no elements matched
|
||||
*/
|
||||
JSAPI.prototype.querySelectorAll = function(selectors) {
|
||||
|
||||
var matchedEls = cssSelect(selectors, this, cssSelectOpts);
|
||||
|
||||
return matchedEls.length > 0 ? matchedEls : null;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Evaluate a string of CSS selectors against the element and returns only the first matched element.
|
||||
*
|
||||
* @param {String} selectors CSS selector(s) string
|
||||
* @return {Array} null if no element matched
|
||||
*/
|
||||
JSAPI.prototype.querySelector = function(selectors) {
|
||||
|
||||
return cssSelect.selectOne(selectors, this, cssSelectOpts);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Test if a selector matches a given element.
|
||||
*
|
||||
* @param {String} selector CSS selector string
|
||||
* @return {Boolean} true if element would be selected by selector string, false if it does not
|
||||
*/
|
||||
JSAPI.prototype.matches = function(selector) {
|
||||
|
||||
return cssSelect.is(this, selector, cssSelectOpts);
|
||||
|
||||
};
|
101
assets_old/node_modules/svgo/lib/svgo/plugins.js
generated
vendored
Normal file
101
assets_old/node_modules/svgo/lib/svgo/plugins.js
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* Plugins engine.
|
||||
*
|
||||
* @module plugins
|
||||
*
|
||||
* @param {Object} data input data
|
||||
* @param {Object} info extra information
|
||||
* @param {Object} plugins plugins object from config
|
||||
* @return {Object} output data
|
||||
*/
|
||||
module.exports = function(data, info, plugins) {
|
||||
|
||||
plugins.forEach(function(group) {
|
||||
|
||||
switch(group[0].type) {
|
||||
case 'perItem':
|
||||
data = perItem(data, info, group);
|
||||
break;
|
||||
case 'perItemReverse':
|
||||
data = perItem(data, info, group, true);
|
||||
break;
|
||||
case 'full':
|
||||
data = full(data, info, group);
|
||||
break;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Direct or reverse per-item loop.
|
||||
*
|
||||
* @param {Object} data input data
|
||||
* @param {Object} info extra information
|
||||
* @param {Array} plugins plugins list to process
|
||||
* @param {Boolean} [reverse] reverse pass?
|
||||
* @return {Object} output data
|
||||
*/
|
||||
function perItem(data, info, 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, info) === 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 {Object} info extra information
|
||||
* @param {Array} plugins plugins list to process
|
||||
* @return {Object} output data
|
||||
*/
|
||||
function full(data, info, plugins) {
|
||||
|
||||
plugins.forEach(function(plugin) {
|
||||
if (plugin.active) {
|
||||
data = plugin.fn(data, plugin.params, info);
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
|
||||
}
|
200
assets_old/node_modules/svgo/lib/svgo/svg2js.js
generated
vendored
Normal file
200
assets_old/node_modules/svgo/lib/svgo/svg2js.js
generated
vendored
Normal file
|
@ -0,0 +1,200 @@
|
|||
'use strict';
|
||||
|
||||
var SAX = require('sax'),
|
||||
JSAPI = require('./jsAPI.js'),
|
||||
CSSClassList = require('./css-class-list'),
|
||||
CSSStyleDeclaration = require('./css-style-declaration'),
|
||||
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', content: [] }),
|
||||
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,
|
||||
attrs: {}
|
||||
};
|
||||
|
||||
elem.class = new CSSClassList(elem);
|
||||
elem.style = new CSSStyleDeclaration(elem);
|
||||
|
||||
if (Object.keys(data.attributes).length) {
|
||||
for (var name in data.attributes) {
|
||||
|
||||
if (name === 'class') { // has class attribute
|
||||
elem.class.hasClass();
|
||||
}
|
||||
|
||||
if (name === 'style') { // has style attribute
|
||||
elem.style.hasStyle();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
};
|
155
assets_old/node_modules/svgo/lib/svgo/tools.js
generated
vendored
Normal file
155
assets_old/node_modules/svgo/lib/svgo/tools.js
generated
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
'use strict';
|
||||
|
||||
var FS = require('fs');
|
||||
|
||||
/**
|
||||
* 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';
|
||||
if (!type || type === 'base64') {
|
||||
// base64
|
||||
prefix += ';base64,';
|
||||
if (Buffer.from) {
|
||||
str = prefix + Buffer.from(str).toString('base64');
|
||||
} else {
|
||||
str = prefix + new Buffer(str).toString('base64');
|
||||
}
|
||||
} else if (type === 'enc') {
|
||||
// URI encoded
|
||||
str = prefix + ',' + encodeURIComponent(str);
|
||||
} else if (type === 'unenc') {
|
||||
// unencoded
|
||||
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];
|
||||
|
||||
if (match[2]) {
|
||||
// base64
|
||||
str = new Buffer(data, 'base64').toString('utf8');
|
||||
} else if (data.charAt(0) === '%') {
|
||||
// URI encoded
|
||||
str = decodeURIComponent(data);
|
||||
} else if (data.charAt(0) === '<') {
|
||||
// unencoded
|
||||
str = data;
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
exports.intersectArrays = function(a, b) {
|
||||
return a.filter(function(n) {
|
||||
return b.indexOf(n) > -1;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a row of numbers to an optimized string view.
|
||||
*
|
||||
* @example
|
||||
* [0, -1, .5, .5] → "0-1 .5.5"
|
||||
*
|
||||
* @param {number[]} data
|
||||
* @param {Object} params
|
||||
* @param {string?} command path data instruction
|
||||
* @return {string}
|
||||
*/
|
||||
exports.cleanupOutData = function(data, params, command) {
|
||||
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 = '';
|
||||
|
||||
// no extra space after 'arcto' command flags
|
||||
if (params.noSpaceAfterFlags && (command == 'A' || command == 'a')) {
|
||||
var pos = i % 7;
|
||||
if (pos == 4 || pos == 5) 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 &&
|
||||
delimiter != '' &&
|
||||
(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;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Synchronously check if path is a directory. Tolerant to errors like ENOENT.
|
||||
* @param {string} path
|
||||
*/
|
||||
exports.checkIsDir = function(path) {
|
||||
try {
|
||||
return FS.lstatSync(path).isDirectory();
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
};
|
1
assets_old/node_modules/svgo/node_modules/.bin/mkdirp
generated
vendored
Symbolic link
1
assets_old/node_modules/svgo/node_modules/.bin/mkdirp
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../mkdirp/bin/cmd.js
|
21
assets_old/node_modules/svgo/node_modules/mkdirp/LICENSE
generated
vendored
Normal file
21
assets_old/node_modules/svgo/node_modules/mkdirp/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
Copyright 2010 James Halliday (mail@substack.net)
|
||||
|
||||
This project is free software released under the MIT/X11 license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
33
assets_old/node_modules/svgo/node_modules/mkdirp/bin/cmd.js
generated
vendored
Executable file
33
assets_old/node_modules/svgo/node_modules/mkdirp/bin/cmd.js
generated
vendored
Executable file
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var mkdirp = require('../');
|
||||
var minimist = require('minimist');
|
||||
var fs = require('fs');
|
||||
|
||||
var argv = minimist(process.argv.slice(2), {
|
||||
alias: { m: 'mode', h: 'help' },
|
||||
string: [ 'mode' ]
|
||||
});
|
||||
if (argv.help) {
|
||||
fs.createReadStream(__dirname + '/usage.txt').pipe(process.stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
var paths = argv._.slice();
|
||||
var mode = argv.mode ? parseInt(argv.mode, 8) : undefined;
|
||||
|
||||
(function next () {
|
||||
if (paths.length === 0) return;
|
||||
var p = paths.shift();
|
||||
|
||||
if (mode === undefined) mkdirp(p, cb)
|
||||
else mkdirp(p, mode, cb)
|
||||
|
||||
function cb (err) {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
else next();
|
||||
}
|
||||
})();
|
12
assets_old/node_modules/svgo/node_modules/mkdirp/bin/usage.txt
generated
vendored
Normal file
12
assets_old/node_modules/svgo/node_modules/mkdirp/bin/usage.txt
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
usage: mkdirp [DIR1,DIR2..] {OPTIONS}
|
||||
|
||||
Create each supplied directory including any necessary parent directories that
|
||||
don't yet exist.
|
||||
|
||||
If the directory already exists, do nothing.
|
||||
|
||||
OPTIONS are:
|
||||
|
||||
-m, --mode If a directory needs to be created, set the mode as an octal
|
||||
permission string.
|
||||
|
99
assets_old/node_modules/svgo/node_modules/mkdirp/index.js
generated
vendored
Normal file
99
assets_old/node_modules/svgo/node_modules/mkdirp/index.js
generated
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var _0777 = parseInt('0777', 8);
|
||||
|
||||
module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
|
||||
|
||||
function mkdirP (p, opts, f, made) {
|
||||
if (typeof opts === 'function') {
|
||||
f = opts;
|
||||
opts = {};
|
||||
}
|
||||
else if (!opts || typeof opts !== 'object') {
|
||||
opts = { mode: opts };
|
||||
}
|
||||
|
||||
var mode = opts.mode;
|
||||
var xfs = opts.fs || fs;
|
||||
|
||||
if (mode === undefined) {
|
||||
mode = _0777
|
||||
}
|
||||
if (!made) made = null;
|
||||
|
||||
var cb = f || function () {};
|
||||
p = path.resolve(p);
|
||||
|
||||
xfs.mkdir(p, mode, function (er) {
|
||||
if (!er) {
|
||||
made = made || p;
|
||||
return cb(null, made);
|
||||
}
|
||||
switch (er.code) {
|
||||
case 'ENOENT':
|
||||
if (path.dirname(p) === p) return cb(er);
|
||||
mkdirP(path.dirname(p), opts, function (er, made) {
|
||||
if (er) cb(er, made);
|
||||
else mkdirP(p, opts, cb, made);
|
||||
});
|
||||
break;
|
||||
|
||||
// In the case of any other error, just see if there's a dir
|
||||
// there already. If so, then hooray! If not, then something
|
||||
// is borked.
|
||||
default:
|
||||
xfs.stat(p, function (er2, stat) {
|
||||
// if the stat fails, then that's super weird.
|
||||
// let the original error be the failure reason.
|
||||
if (er2 || !stat.isDirectory()) cb(er, made)
|
||||
else cb(null, made);
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mkdirP.sync = function sync (p, opts, made) {
|
||||
if (!opts || typeof opts !== 'object') {
|
||||
opts = { mode: opts };
|
||||
}
|
||||
|
||||
var mode = opts.mode;
|
||||
var xfs = opts.fs || fs;
|
||||
|
||||
if (mode === undefined) {
|
||||
mode = _0777
|
||||
}
|
||||
if (!made) made = null;
|
||||
|
||||
p = path.resolve(p);
|
||||
|
||||
try {
|
||||
xfs.mkdirSync(p, mode);
|
||||
made = made || p;
|
||||
}
|
||||
catch (err0) {
|
||||
switch (err0.code) {
|
||||
case 'ENOENT' :
|
||||
made = sync(path.dirname(p), opts, made);
|
||||
sync(p, opts, made);
|
||||
break;
|
||||
|
||||
// In the case of any other error, just see if there's a dir
|
||||
// there already. If so, then hooray! If not, then something
|
||||
// is borked.
|
||||
default:
|
||||
var stat;
|
||||
try {
|
||||
stat = xfs.statSync(p);
|
||||
}
|
||||
catch (err1) {
|
||||
throw err0;
|
||||
}
|
||||
if (!stat.isDirectory()) throw err0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return made;
|
||||
};
|
34
assets_old/node_modules/svgo/node_modules/mkdirp/package.json
generated
vendored
Normal file
34
assets_old/node_modules/svgo/node_modules/mkdirp/package.json
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "mkdirp",
|
||||
"description": "Recursively mkdir, like `mkdir -p`",
|
||||
"version": "0.5.5",
|
||||
"publishConfig": {
|
||||
"tag": "legacy"
|
||||
},
|
||||
"author": "James Halliday <mail@substack.net> (http://substack.net)",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"mkdir",
|
||||
"directory"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/substack/node-mkdirp.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap test/*.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mock-fs": "^3.7.0",
|
||||
"tap": "^5.4.2"
|
||||
},
|
||||
"bin": "bin/cmd.js",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"bin",
|
||||
"index.js"
|
||||
]
|
||||
}
|
100
assets_old/node_modules/svgo/node_modules/mkdirp/readme.markdown
generated
vendored
Normal file
100
assets_old/node_modules/svgo/node_modules/mkdirp/readme.markdown
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
# mkdirp
|
||||
|
||||
Like `mkdir -p`, but in node.js!
|
||||
|
||||
[](http://travis-ci.org/substack/node-mkdirp)
|
||||
|
||||
# example
|
||||
|
||||
## pow.js
|
||||
|
||||
```js
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
mkdirp('/tmp/foo/bar/baz', function (err) {
|
||||
if (err) console.error(err)
|
||||
else console.log('pow!')
|
||||
});
|
||||
```
|
||||
|
||||
Output
|
||||
|
||||
```
|
||||
pow!
|
||||
```
|
||||
|
||||
And now /tmp/foo/bar/baz exists, huzzah!
|
||||
|
||||
# methods
|
||||
|
||||
```js
|
||||
var mkdirp = require('mkdirp');
|
||||
```
|
||||
|
||||
## mkdirp(dir, opts, cb)
|
||||
|
||||
Create a new directory and any necessary subdirectories at `dir` with octal
|
||||
permission string `opts.mode`. If `opts` is a non-object, it will be treated as
|
||||
the `opts.mode`.
|
||||
|
||||
If `opts.mode` isn't specified, it defaults to `0777`.
|
||||
|
||||
`cb(err, made)` fires with the error or the first directory `made`
|
||||
that had to be created, if any.
|
||||
|
||||
You can optionally pass in an alternate `fs` implementation by passing in
|
||||
`opts.fs`. Your implementation should have `opts.fs.mkdir(path, mode, cb)` and
|
||||
`opts.fs.stat(path, cb)`.
|
||||
|
||||
## mkdirp.sync(dir, opts)
|
||||
|
||||
Synchronously create a new directory and any necessary subdirectories at `dir`
|
||||
with octal permission string `opts.mode`. If `opts` is a non-object, it will be
|
||||
treated as the `opts.mode`.
|
||||
|
||||
If `opts.mode` isn't specified, it defaults to `0777`.
|
||||
|
||||
Returns the first directory that had to be created, if any.
|
||||
|
||||
You can optionally pass in an alternate `fs` implementation by passing in
|
||||
`opts.fs`. Your implementation should have `opts.fs.mkdirSync(path, mode)` and
|
||||
`opts.fs.statSync(path)`.
|
||||
|
||||
# usage
|
||||
|
||||
This package also ships with a `mkdirp` command.
|
||||
|
||||
```
|
||||
usage: mkdirp [DIR1,DIR2..] {OPTIONS}
|
||||
|
||||
Create each supplied directory including any necessary parent directories that
|
||||
don't yet exist.
|
||||
|
||||
If the directory already exists, do nothing.
|
||||
|
||||
OPTIONS are:
|
||||
|
||||
-m, --mode If a directory needs to be created, set the mode as an octal
|
||||
permission string.
|
||||
|
||||
```
|
||||
|
||||
# install
|
||||
|
||||
With [npm](http://npmjs.org) do:
|
||||
|
||||
```
|
||||
npm install mkdirp
|
||||
```
|
||||
|
||||
to get the library, or
|
||||
|
||||
```
|
||||
npm install -g mkdirp
|
||||
```
|
||||
|
||||
to get the command.
|
||||
|
||||
# license
|
||||
|
||||
MIT
|
79
assets_old/node_modules/svgo/package.json
generated
vendored
Normal file
79
assets_old/node_modules/svgo/package.json
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"name": "svgo",
|
||||
"version": "1.3.2",
|
||||
"description": "Nodejs-based tool for optimizing SVG vector graphics files",
|
||||
"keywords": [
|
||||
"svgo",
|
||||
"svg",
|
||||
"optimize",
|
||||
"minify"
|
||||
],
|
||||
"homepage": "https://github.com/svg/svgo",
|
||||
"bugs": {
|
||||
"url": "https://github.com/svg/svgo/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Kir Belevich",
|
||||
"email": "kir@belevi.ch",
|
||||
"url": "https://github.com/deepsweet"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Sergey Belov",
|
||||
"email": "peimei@ya.ru",
|
||||
"url": "http://github.com/arikon"
|
||||
},
|
||||
{
|
||||
"name": "Lev Solntsev",
|
||||
"email": "lev.sun@ya.ru",
|
||||
"url": "http://github.com/GreLI"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/svg/svgo.git"
|
||||
},
|
||||
"main": "./lib/svgo.js",
|
||||
"bin": {
|
||||
"svgo": "./bin/svgo"
|
||||
},
|
||||
"directories": {
|
||||
"bin": "./bin",
|
||||
"lib": "./lib",
|
||||
"example": "./examples"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "set NODE_ENV=test && mocha",
|
||||
"lint": "jshint --show-non-errors .",
|
||||
"jshint": "npm run lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^2.4.1",
|
||||
"coa": "^2.0.2",
|
||||
"css-select": "^2.0.0",
|
||||
"css-select-base-adapter": "^0.1.1",
|
||||
"css-tree": "1.0.0-alpha.37",
|
||||
"csso": "^4.0.2",
|
||||
"js-yaml": "^3.13.1",
|
||||
"mkdirp": "~0.5.1",
|
||||
"object.values": "^1.1.0",
|
||||
"sax": "~1.2.4",
|
||||
"stable": "^0.1.8",
|
||||
"unquote": "~1.1.1",
|
||||
"util.promisify": "~1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coveralls": "^3.0.7",
|
||||
"fs-extra": "~8.1.0",
|
||||
"istanbul": "~0.4.5",
|
||||
"jshint": "~2.10.2",
|
||||
"mocha": "~6.2.2",
|
||||
"mocha-istanbul": "~0.3.0",
|
||||
"mock-stdin": "~0.3.1",
|
||||
"should": "~13.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
2558
assets_old/node_modules/svgo/plugins/_collections.js
generated
vendored
Normal file
2558
assets_old/node_modules/svgo/plugins/_collections.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
988
assets_old/node_modules/svgo/plugins/_path.js
generated
vendored
Normal file
988
assets_old/node_modules/svgo/plugins/_path.js
generated
vendored
Normal file
|
@ -0,0 +1,988 @@
|
|||
/* global a2c */
|
||||
'use strict';
|
||||
|
||||
var rNumber = String.raw`[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?\s*`,
|
||||
rCommaWsp = String.raw`(?:\s,?\s*|,\s*)`,
|
||||
rNumberCommaWsp = `(${rNumber})` + rCommaWsp,
|
||||
rFlagCommaWsp = `([01])${rCommaWsp}?`,
|
||||
rCoordinatePair = String.raw`(${rNumber})${rCommaWsp}?(${rNumber})`,
|
||||
rArcSeq = (rNumberCommaWsp + '?').repeat(2) + rNumberCommaWsp + rFlagCommaWsp.repeat(2) + rCoordinatePair;
|
||||
|
||||
var regPathInstructions = /([MmLlHhVvCcSsQqTtAaZz])\s*/,
|
||||
regCoordinateSequence = new RegExp(rNumber, 'g'),
|
||||
regArcArgumentSequence = new RegExp(rArcSeq, 'g'),
|
||||
regNumericValues = /[-+]?(\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/,
|
||||
transform2js = require('./_transforms').transform2js,
|
||||
transformsMultiply = require('./_transforms').transformsMultiply,
|
||||
transformArc = require('./_transforms').transformArc,
|
||||
collections = require('./_collections.js'),
|
||||
referencesProps = collections.referencesProps,
|
||||
defaultStrokeWidth = collections.attrsGroupsDefaults.presentation['stroke-width'],
|
||||
cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
|
||||
removeLeadingZero = require('../lib/svgo/tools').removeLeadingZero,
|
||||
prevCtrlPoint;
|
||||
|
||||
/**
|
||||
* Convert path string to JS representation.
|
||||
*
|
||||
* @param {String} pathString input string
|
||||
* @param {Object} params plugin params
|
||||
* @return {Array} output array
|
||||
*/
|
||||
exports.path2js = function(path) {
|
||||
if (path.pathJS) return path.pathJS;
|
||||
|
||||
var paramsLength = { // Number of parameters of every path command
|
||||
H: 1, V: 1, M: 2, L: 2, T: 2, Q: 4, S: 4, C: 6, A: 7,
|
||||
h: 1, v: 1, m: 2, l: 2, t: 2, q: 4, s: 4, c: 6, a: 7
|
||||
},
|
||||
pathData = [], // JS representation of the path data
|
||||
instruction, // current instruction context
|
||||
startMoveto = false;
|
||||
|
||||
// splitting path string into array like ['M', '10 50', 'L', '20 30']
|
||||
path.attr('d').value.split(regPathInstructions).forEach(function(data) {
|
||||
if (!data) return;
|
||||
if (!startMoveto) {
|
||||
if (data == 'M' || data == 'm') {
|
||||
startMoveto = true;
|
||||
} else return;
|
||||
}
|
||||
|
||||
// instruction item
|
||||
if (regPathInstructions.test(data)) {
|
||||
instruction = data;
|
||||
|
||||
// z - instruction w/o data
|
||||
if (instruction == 'Z' || instruction == 'z') {
|
||||
pathData.push({
|
||||
instruction: 'z'
|
||||
});
|
||||
}
|
||||
// data item
|
||||
} else {
|
||||
/* jshint boss: true */
|
||||
if (instruction == 'A' || instruction == 'a') {
|
||||
var newData = [];
|
||||
for (var args; (args = regArcArgumentSequence.exec(data));) {
|
||||
for (var i = 1; i < args.length; i++) {
|
||||
newData.push(args[i]);
|
||||
}
|
||||
}
|
||||
data = newData;
|
||||
} else {
|
||||
data = data.match(regCoordinateSequence);
|
||||
}
|
||||
if (!data) return;
|
||||
|
||||
data = data.map(Number);
|
||||
// Subsequent moveto pairs of coordinates are threated as implicit lineto commands
|
||||
// http://www.w3.org/TR/SVG/paths.html#PathDataMovetoCommands
|
||||
if (instruction == 'M' || instruction == 'm') {
|
||||
pathData.push({
|
||||
instruction: pathData.length == 0 ? 'M' : instruction,
|
||||
data: data.splice(0, 2)
|
||||
});
|
||||
instruction = instruction == 'M' ? 'L' : 'l';
|
||||
}
|
||||
|
||||
for (var pair = paramsLength[instruction]; data.length;) {
|
||||
pathData.push({
|
||||
instruction: instruction,
|
||||
data: data.splice(0, pair)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// First moveto is actually absolute. Subsequent coordinates were separated above.
|
||||
if (pathData.length && pathData[0].instruction == 'm') {
|
||||
pathData[0].instruction = 'M';
|
||||
}
|
||||
path.pathJS = pathData;
|
||||
|
||||
return pathData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert relative Path data to absolute.
|
||||
*
|
||||
* @param {Array} data input data
|
||||
* @return {Array} output data
|
||||
*/
|
||||
var relative2absolute = exports.relative2absolute = function(data) {
|
||||
var currentPoint = [0, 0],
|
||||
subpathPoint = [0, 0],
|
||||
i;
|
||||
|
||||
return data.map(function(item) {
|
||||
|
||||
var instruction = item.instruction,
|
||||
itemData = item.data && item.data.slice();
|
||||
|
||||
if (instruction == 'M') {
|
||||
|
||||
set(currentPoint, itemData);
|
||||
set(subpathPoint, itemData);
|
||||
|
||||
} else if ('mlcsqt'.indexOf(instruction) > -1) {
|
||||
|
||||
for (i = 0; i < itemData.length; i++) {
|
||||
itemData[i] += currentPoint[i % 2];
|
||||
}
|
||||
set(currentPoint, itemData);
|
||||
|
||||
if (instruction == 'm') {
|
||||
set(subpathPoint, itemData);
|
||||
}
|
||||
|
||||
} else if (instruction == 'a') {
|
||||
|
||||
itemData[5] += currentPoint[0];
|
||||
itemData[6] += currentPoint[1];
|
||||
set(currentPoint, itemData);
|
||||
|
||||
} else if (instruction == 'h') {
|
||||
|
||||
itemData[0] += currentPoint[0];
|
||||
currentPoint[0] = itemData[0];
|
||||
|
||||
} else if (instruction == 'v') {
|
||||
|
||||
itemData[0] += currentPoint[1];
|
||||
currentPoint[1] = itemData[0];
|
||||
|
||||
} else if ('MZLCSQTA'.indexOf(instruction) > -1) {
|
||||
|
||||
set(currentPoint, itemData);
|
||||
|
||||
} else if (instruction == 'H') {
|
||||
|
||||
currentPoint[0] = itemData[0];
|
||||
|
||||
} else if (instruction == 'V') {
|
||||
|
||||
currentPoint[1] = itemData[0];
|
||||
|
||||
} else if (instruction == 'z') {
|
||||
|
||||
set(currentPoint, subpathPoint);
|
||||
|
||||
}
|
||||
|
||||
return instruction == 'z' ?
|
||||
{ instruction: 'z' } :
|
||||
{
|
||||
instruction: instruction.toUpperCase(),
|
||||
data: itemData
|
||||
};
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply transformation(s) to the Path data.
|
||||
*
|
||||
* @param {Object} elem current element
|
||||
* @param {Array} path input path data
|
||||
* @param {Object} params whether to apply transforms to stroked lines and transform precision (used for stroke width)
|
||||
* @return {Array} output path data
|
||||
*/
|
||||
exports.applyTransforms = function(elem, path, params) {
|
||||
// if there are no 'stroke' attr and references to other objects such as
|
||||
// gradiends or clip-path which are also subjects to transform.
|
||||
if (!elem.hasAttr('transform') || !elem.attr('transform').value ||
|
||||
elem.someAttr(function(attr) {
|
||||
return ~referencesProps.indexOf(attr.name) && ~attr.value.indexOf('url(');
|
||||
}))
|
||||
return path;
|
||||
|
||||
var matrix = transformsMultiply(transform2js(elem.attr('transform').value)),
|
||||
stroke = elem.computedAttr('stroke'),
|
||||
id = elem.computedAttr('id'),
|
||||
transformPrecision = params.transformPrecision,
|
||||
newPoint, scale;
|
||||
|
||||
if (stroke && stroke != 'none') {
|
||||
if (!params.applyTransformsStroked ||
|
||||
(matrix.data[0] != matrix.data[3] || matrix.data[1] != -matrix.data[2]) &&
|
||||
(matrix.data[0] != -matrix.data[3] || matrix.data[1] != matrix.data[2]))
|
||||
return path;
|
||||
|
||||
// "stroke-width" should be inside the part with ID, otherwise it can be overrided in <use>
|
||||
if (id) {
|
||||
var idElem = elem,
|
||||
hasStrokeWidth = false;
|
||||
|
||||
do {
|
||||
if (idElem.hasAttr('stroke-width')) hasStrokeWidth = true;
|
||||
} while (!idElem.hasAttr('id', id) && !hasStrokeWidth && (idElem = idElem.parentNode));
|
||||
|
||||
if (!hasStrokeWidth) return path;
|
||||
}
|
||||
|
||||
scale = +Math.sqrt(matrix.data[0] * matrix.data[0] + matrix.data[1] * matrix.data[1]).toFixed(transformPrecision);
|
||||
|
||||
if (scale !== 1) {
|
||||
var strokeWidth = elem.computedAttr('stroke-width') || defaultStrokeWidth;
|
||||
|
||||
if (!elem.hasAttr('vector-effect') || elem.attr('vector-effect').value !== 'non-scaling-stroke') {
|
||||
if (elem.hasAttr('stroke-width')) {
|
||||
elem.attrs['stroke-width'].value = elem.attrs['stroke-width'].value.trim()
|
||||
.replace(regNumericValues, function(num) {
|
||||
return removeLeadingZero(num * scale);
|
||||
});
|
||||
} else {
|
||||
elem.addAttr({
|
||||
name: 'stroke-width',
|
||||
prefix: '',
|
||||
local: 'stroke-width',
|
||||
value: strokeWidth.replace(regNumericValues, function(num) {
|
||||
return removeLeadingZero(num * scale);
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (id) { // Stroke and stroke-width can be redefined with <use>
|
||||
return path;
|
||||
}
|
||||
|
||||
path.forEach(function(pathItem) {
|
||||
|
||||
if (pathItem.data) {
|
||||
|
||||
// h -> l
|
||||
if (pathItem.instruction === 'h') {
|
||||
|
||||
pathItem.instruction = 'l';
|
||||
pathItem.data[1] = 0;
|
||||
|
||||
// v -> l
|
||||
} else if (pathItem.instruction === 'v') {
|
||||
|
||||
pathItem.instruction = 'l';
|
||||
pathItem.data[1] = pathItem.data[0];
|
||||
pathItem.data[0] = 0;
|
||||
|
||||
}
|
||||
|
||||
// if there is a translate() transform
|
||||
if (pathItem.instruction === 'M' &&
|
||||
(matrix.data[4] !== 0 ||
|
||||
matrix.data[5] !== 0)
|
||||
) {
|
||||
|
||||
// then apply it only to the first absoluted M
|
||||
newPoint = transformPoint(matrix.data, pathItem.data[0], pathItem.data[1]);
|
||||
set(pathItem.data, newPoint);
|
||||
set(pathItem.coords, newPoint);
|
||||
|
||||
// clear translate() data from transform matrix
|
||||
matrix.data[4] = 0;
|
||||
matrix.data[5] = 0;
|
||||
|
||||
} else {
|
||||
|
||||
if (pathItem.instruction == 'a') {
|
||||
|
||||
transformArc(pathItem.data, matrix.data);
|
||||
|
||||
// reduce number of digits in rotation angle
|
||||
if (Math.abs(pathItem.data[2]) > 80) {
|
||||
var a = pathItem.data[0],
|
||||
rotation = pathItem.data[2];
|
||||
pathItem.data[0] = pathItem.data[1];
|
||||
pathItem.data[1] = a;
|
||||
pathItem.data[2] = rotation + (rotation > 0 ? -90 : 90);
|
||||
}
|
||||
|
||||
newPoint = transformPoint(matrix.data, pathItem.data[5], pathItem.data[6]);
|
||||
pathItem.data[5] = newPoint[0];
|
||||
pathItem.data[6] = newPoint[1];
|
||||
|
||||
} else {
|
||||
|
||||
for (var i = 0; i < pathItem.data.length; i += 2) {
|
||||
newPoint = transformPoint(matrix.data, pathItem.data[i], pathItem.data[i + 1]);
|
||||
pathItem.data[i] = newPoint[0];
|
||||
pathItem.data[i + 1] = newPoint[1];
|
||||
}
|
||||
}
|
||||
|
||||
pathItem.coords[0] = pathItem.base[0] + pathItem.data[pathItem.data.length - 2];
|
||||
pathItem.coords[1] = pathItem.base[1] + pathItem.data[pathItem.data.length - 1];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// remove transform attr
|
||||
elem.removeAttr('transform');
|
||||
|
||||
return path;
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply transform 3x3 matrix to x-y point.
|
||||
*
|
||||
* @param {Array} matrix transform 3x3 matrix
|
||||
* @param {Array} point x-y point
|
||||
* @return {Array} point with new coordinates
|
||||
*/
|
||||
function transformPoint(matrix, x, y) {
|
||||
|
||||
return [
|
||||
matrix[0] * x + matrix[2] * y + matrix[4],
|
||||
matrix[1] * x + matrix[3] * y + matrix[5]
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute Cubic Bézie bounding box.
|
||||
*
|
||||
* @see http://processingjs.nihongoresources.com/bezierinfo/
|
||||
*
|
||||
* @param {Float} xa
|
||||
* @param {Float} ya
|
||||
* @param {Float} xb
|
||||
* @param {Float} yb
|
||||
* @param {Float} xc
|
||||
* @param {Float} yc
|
||||
* @param {Float} xd
|
||||
* @param {Float} yd
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
exports.computeCubicBoundingBox = function(xa, ya, xb, yb, xc, yc, xd, yd) {
|
||||
|
||||
var minx = Number.POSITIVE_INFINITY,
|
||||
miny = Number.POSITIVE_INFINITY,
|
||||
maxx = Number.NEGATIVE_INFINITY,
|
||||
maxy = Number.NEGATIVE_INFINITY,
|
||||
ts,
|
||||
t,
|
||||
x,
|
||||
y,
|
||||
i;
|
||||
|
||||
// X
|
||||
if (xa < minx) { minx = xa; }
|
||||
if (xa > maxx) { maxx = xa; }
|
||||
if (xd < minx) { minx= xd; }
|
||||
if (xd > maxx) { maxx = xd; }
|
||||
|
||||
ts = computeCubicFirstDerivativeRoots(xa, xb, xc, xd);
|
||||
|
||||
for (i = 0; i < ts.length; i++) {
|
||||
|
||||
t = ts[i];
|
||||
|
||||
if (t >= 0 && t <= 1) {
|
||||
x = computeCubicBaseValue(t, xa, xb, xc, xd);
|
||||
// y = computeCubicBaseValue(t, ya, yb, yc, yd);
|
||||
|
||||
if (x < minx) { minx = x; }
|
||||
if (x > maxx) { maxx = x; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Y
|
||||
if (ya < miny) { miny = ya; }
|
||||
if (ya > maxy) { maxy = ya; }
|
||||
if (yd < miny) { miny = yd; }
|
||||
if (yd > maxy) { maxy = yd; }
|
||||
|
||||
ts = computeCubicFirstDerivativeRoots(ya, yb, yc, yd);
|
||||
|
||||
for (i = 0; i < ts.length; i++) {
|
||||
|
||||
t = ts[i];
|
||||
|
||||
if (t >= 0 && t <= 1) {
|
||||
// x = computeCubicBaseValue(t, xa, xb, xc, xd);
|
||||
y = computeCubicBaseValue(t, ya, yb, yc, yd);
|
||||
|
||||
if (y < miny) { miny = y; }
|
||||
if (y > maxy) { maxy = y; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
minx: minx,
|
||||
miny: miny,
|
||||
maxx: maxx,
|
||||
maxy: maxy
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
// compute the value for the cubic bezier function at time=t
|
||||
function computeCubicBaseValue(t, a, b, c, d) {
|
||||
|
||||
var mt = 1 - t;
|
||||
|
||||
return mt * mt * mt * a + 3 * mt * mt * t * b + 3 * mt * t * t * c + t * t * t * d;
|
||||
|
||||
}
|
||||
|
||||
// compute the value for the first derivative of the cubic bezier function at time=t
|
||||
function computeCubicFirstDerivativeRoots(a, b, c, d) {
|
||||
|
||||
var result = [-1, -1],
|
||||
tl = -a + 2 * b - c,
|
||||
tr = -Math.sqrt(-a * (c - d) + b * b - b * (c + d) + c * c),
|
||||
dn = -a + 3 * b - 3 * c + d;
|
||||
|
||||
if (dn !== 0) {
|
||||
result[0] = (tl + tr) / dn;
|
||||
result[1] = (tl - tr) / dn;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute Quadratic Bézier bounding box.
|
||||
*
|
||||
* @see http://processingjs.nihongoresources.com/bezierinfo/
|
||||
*
|
||||
* @param {Float} xa
|
||||
* @param {Float} ya
|
||||
* @param {Float} xb
|
||||
* @param {Float} yb
|
||||
* @param {Float} xc
|
||||
* @param {Float} yc
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
exports.computeQuadraticBoundingBox = function(xa, ya, xb, yb, xc, yc) {
|
||||
|
||||
var minx = Number.POSITIVE_INFINITY,
|
||||
miny = Number.POSITIVE_INFINITY,
|
||||
maxx = Number.NEGATIVE_INFINITY,
|
||||
maxy = Number.NEGATIVE_INFINITY,
|
||||
t,
|
||||
x,
|
||||
y;
|
||||
|
||||
// X
|
||||
if (xa < minx) { minx = xa; }
|
||||
if (xa > maxx) { maxx = xa; }
|
||||
if (xc < minx) { minx = xc; }
|
||||
if (xc > maxx) { maxx = xc; }
|
||||
|
||||
t = computeQuadraticFirstDerivativeRoot(xa, xb, xc);
|
||||
|
||||
if (t >= 0 && t <= 1) {
|
||||
x = computeQuadraticBaseValue(t, xa, xb, xc);
|
||||
// y = computeQuadraticBaseValue(t, ya, yb, yc);
|
||||
|
||||
if (x < minx) { minx = x; }
|
||||
if (x > maxx) { maxx = x; }
|
||||
}
|
||||
|
||||
// Y
|
||||
if (ya < miny) { miny = ya; }
|
||||
if (ya > maxy) { maxy = ya; }
|
||||
if (yc < miny) { miny = yc; }
|
||||
if (yc > maxy) { maxy = yc; }
|
||||
|
||||
t = computeQuadraticFirstDerivativeRoot(ya, yb, yc);
|
||||
|
||||
if (t >= 0 && t <=1 ) {
|
||||
// x = computeQuadraticBaseValue(t, xa, xb, xc);
|
||||
y = computeQuadraticBaseValue(t, ya, yb, yc);
|
||||
|
||||
if (y < miny) { miny = y; }
|
||||
if (y > maxy) { maxy = y ; }
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
minx: minx,
|
||||
miny: miny,
|
||||
maxx: maxx,
|
||||
maxy: maxy
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
// compute the value for the quadratic bezier function at time=t
|
||||
function computeQuadraticBaseValue(t, a, b, c) {
|
||||
|
||||
var mt = 1 - t;
|
||||
|
||||
return mt * mt * a + 2 * mt * t * b + t * t * c;
|
||||
|
||||
}
|
||||
|
||||
// compute the value for the first derivative of the quadratic bezier function at time=t
|
||||
function computeQuadraticFirstDerivativeRoot(a, b, c) {
|
||||
|
||||
var t = -1,
|
||||
denominator = a - 2 * b + c;
|
||||
|
||||
if (denominator !== 0) {
|
||||
t = (a - b) / denominator;
|
||||
}
|
||||
|
||||
return t;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert path array to string.
|
||||
*
|
||||
* @param {Array} path input path data
|
||||
* @param {Object} params plugin params
|
||||
* @return {String} output path string
|
||||
*/
|
||||
exports.js2path = function(path, data, params) {
|
||||
|
||||
path.pathJS = data;
|
||||
|
||||
if (params.collapseRepeated) {
|
||||
data = collapseRepeated(data);
|
||||
}
|
||||
|
||||
path.attr('d').value = data.reduce(function(pathString, item) {
|
||||
var strData = '';
|
||||
if (item.data) {
|
||||
strData = cleanupOutData(item.data, params, item.instruction);
|
||||
}
|
||||
return pathString += item.instruction + strData;
|
||||
}, '');
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Collapse repeated instructions data
|
||||
*
|
||||
* @param {Array} path input path data
|
||||
* @return {Array} output path data
|
||||
*/
|
||||
function collapseRepeated(data) {
|
||||
|
||||
var prev,
|
||||
prevIndex;
|
||||
|
||||
// copy an array and modifieds item to keep original data untouched
|
||||
data = data.reduce(function(newPath, item) {
|
||||
if (
|
||||
prev && item.data &&
|
||||
item.instruction == prev.instruction
|
||||
) {
|
||||
// concat previous data with current
|
||||
if (item.instruction != 'M') {
|
||||
prev = newPath[prevIndex] = {
|
||||
instruction: prev.instruction,
|
||||
data: prev.data.concat(item.data),
|
||||
coords: item.coords,
|
||||
base: prev.base
|
||||
};
|
||||
} else {
|
||||
prev.data = item.data;
|
||||
prev.coords = item.coords;
|
||||
}
|
||||
} else {
|
||||
newPath.push(item);
|
||||
prev = item;
|
||||
prevIndex = newPath.length - 1;
|
||||
}
|
||||
|
||||
return newPath;
|
||||
}, []);
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
function set(dest, source) {
|
||||
dest[0] = source[source.length - 2];
|
||||
dest[1] = source[source.length - 1];
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if two paths have an intersection by checking convex hulls
|
||||
* collision using Gilbert-Johnson-Keerthi distance algorithm
|
||||
* http://entropyinteractive.com/2011/04/gjk-algorithm/
|
||||
*
|
||||
* @param {Array} path1 JS path representation
|
||||
* @param {Array} path2 JS path representation
|
||||
* @return {Boolean}
|
||||
*/
|
||||
exports.intersects = function(path1, path2) {
|
||||
if (path1.length < 3 || path2.length < 3) return false; // nothing to fill
|
||||
|
||||
// Collect points of every subpath.
|
||||
var points1 = relative2absolute(path1).reduce(gatherPoints, []),
|
||||
points2 = relative2absolute(path2).reduce(gatherPoints, []);
|
||||
|
||||
// Axis-aligned bounding box check.
|
||||
if (points1.maxX <= points2.minX || points2.maxX <= points1.minX ||
|
||||
points1.maxY <= points2.minY || points2.maxY <= points1.minY ||
|
||||
points1.every(function (set1) {
|
||||
return points2.every(function (set2) {
|
||||
return set1[set1.maxX][0] <= set2[set2.minX][0] ||
|
||||
set2[set2.maxX][0] <= set1[set1.minX][0] ||
|
||||
set1[set1.maxY][1] <= set2[set2.minY][1] ||
|
||||
set2[set2.maxY][1] <= set1[set1.minY][1];
|
||||
});
|
||||
})
|
||||
) return false;
|
||||
|
||||
// Get a convex hull from points of each subpath. Has the most complexity O(n·log n).
|
||||
var hullNest1 = points1.map(convexHull),
|
||||
hullNest2 = points2.map(convexHull);
|
||||
|
||||
// Check intersection of every subpath of the first path with every subpath of the second.
|
||||
return hullNest1.some(function(hull1) {
|
||||
if (hull1.length < 3) return false;
|
||||
|
||||
return hullNest2.some(function(hull2) {
|
||||
if (hull2.length < 3) return false;
|
||||
|
||||
var simplex = [getSupport(hull1, hull2, [1, 0])], // create the initial simplex
|
||||
direction = minus(simplex[0]); // set the direction to point towards the origin
|
||||
|
||||
var iterations = 1e4; // infinite loop protection, 10 000 iterations is more than enough
|
||||
while (true) {
|
||||
if (iterations-- == 0) {
|
||||
console.error('Error: infinite loop while processing mergePaths plugin.');
|
||||
return true; // true is the safe value that means “do nothing with paths”
|
||||
}
|
||||
// add a new point
|
||||
simplex.push(getSupport(hull1, hull2, direction));
|
||||
// see if the new point was on the correct side of the origin
|
||||
if (dot(direction, simplex[simplex.length - 1]) <= 0) return false;
|
||||
// process the simplex
|
||||
if (processSimplex(simplex, direction)) return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function getSupport(a, b, direction) {
|
||||
return sub(supportPoint(a, direction), supportPoint(b, minus(direction)));
|
||||
}
|
||||
|
||||
// Computes farthest polygon point in particular direction.
|
||||
// Thanks to knowledge of min/max x and y coordinates we can choose a quadrant to search in.
|
||||
// Since we're working on convex hull, the dot product is increasing until we find the farthest point.
|
||||
function supportPoint(polygon, direction) {
|
||||
var index = direction[1] >= 0 ?
|
||||
direction[0] < 0 ? polygon.maxY : polygon.maxX :
|
||||
direction[0] < 0 ? polygon.minX : polygon.minY,
|
||||
max = -Infinity,
|
||||
value;
|
||||
while ((value = dot(polygon[index], direction)) > max) {
|
||||
max = value;
|
||||
index = ++index % polygon.length;
|
||||
}
|
||||
return polygon[(index || polygon.length) - 1];
|
||||
}
|
||||
};
|
||||
|
||||
function processSimplex(simplex, direction) {
|
||||
/* jshint -W004 */
|
||||
|
||||
// we only need to handle to 1-simplex and 2-simplex
|
||||
if (simplex.length == 2) { // 1-simplex
|
||||
var a = simplex[1],
|
||||
b = simplex[0],
|
||||
AO = minus(simplex[1]),
|
||||
AB = sub(b, a);
|
||||
// AO is in the same direction as AB
|
||||
if (dot(AO, AB) > 0) {
|
||||
// get the vector perpendicular to AB facing O
|
||||
set(direction, orth(AB, a));
|
||||
} else {
|
||||
set(direction, AO);
|
||||
// only A remains in the simplex
|
||||
simplex.shift();
|
||||
}
|
||||
} else { // 2-simplex
|
||||
var a = simplex[2], // [a, b, c] = simplex
|
||||
b = simplex[1],
|
||||
c = simplex[0],
|
||||
AB = sub(b, a),
|
||||
AC = sub(c, a),
|
||||
AO = minus(a),
|
||||
ACB = orth(AB, AC), // the vector perpendicular to AB facing away from C
|
||||
ABC = orth(AC, AB); // the vector perpendicular to AC facing away from B
|
||||
|
||||
if (dot(ACB, AO) > 0) {
|
||||
if (dot(AB, AO) > 0) { // region 4
|
||||
set(direction, ACB);
|
||||
simplex.shift(); // simplex = [b, a]
|
||||
} else { // region 5
|
||||
set(direction, AO);
|
||||
simplex.splice(0, 2); // simplex = [a]
|
||||
}
|
||||
} else if (dot(ABC, AO) > 0) {
|
||||
if (dot(AC, AO) > 0) { // region 6
|
||||
set(direction, ABC);
|
||||
simplex.splice(1, 1); // simplex = [c, a]
|
||||
} else { // region 5 (again)
|
||||
set(direction, AO);
|
||||
simplex.splice(0, 2); // simplex = [a]
|
||||
}
|
||||
} else // region 7
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function minus(v) {
|
||||
return [-v[0], -v[1]];
|
||||
}
|
||||
|
||||
function sub(v1, v2) {
|
||||
return [v1[0] - v2[0], v1[1] - v2[1]];
|
||||
}
|
||||
|
||||
function dot(v1, v2) {
|
||||
return v1[0] * v2[0] + v1[1] * v2[1];
|
||||
}
|
||||
|
||||
function orth(v, from) {
|
||||
var o = [-v[1], v[0]];
|
||||
return dot(o, minus(from)) < 0 ? minus(o) : o;
|
||||
}
|
||||
|
||||
function gatherPoints(points, item, index, path) {
|
||||
|
||||
var subPath = points.length && points[points.length - 1],
|
||||
prev = index && path[index - 1],
|
||||
basePoint = subPath.length && subPath[subPath.length - 1],
|
||||
data = item.data,
|
||||
ctrlPoint = basePoint;
|
||||
|
||||
switch (item.instruction) {
|
||||
case 'M':
|
||||
points.push(subPath = []);
|
||||
break;
|
||||
case 'H':
|
||||
addPoint(subPath, [data[0], basePoint[1]]);
|
||||
break;
|
||||
case 'V':
|
||||
addPoint(subPath, [basePoint[0], data[0]]);
|
||||
break;
|
||||
case 'Q':
|
||||
addPoint(subPath, data.slice(0, 2));
|
||||
prevCtrlPoint = [data[2] - data[0], data[3] - data[1]]; // Save control point for shorthand
|
||||
break;
|
||||
case 'T':
|
||||
if (prev.instruction == 'Q' || prev.instruction == 'T') {
|
||||
ctrlPoint = [basePoint[0] + prevCtrlPoint[0], basePoint[1] + prevCtrlPoint[1]];
|
||||
addPoint(subPath, ctrlPoint);
|
||||
prevCtrlPoint = [data[0] - ctrlPoint[0], data[1] - ctrlPoint[1]];
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
// Approximate quibic Bezier curve with middle points between control points
|
||||
addPoint(subPath, [.5 * (basePoint[0] + data[0]), .5 * (basePoint[1] + data[1])]);
|
||||
addPoint(subPath, [.5 * (data[0] + data[2]), .5 * (data[1] + data[3])]);
|
||||
addPoint(subPath, [.5 * (data[2] + data[4]), .5 * (data[3] + data[5])]);
|
||||
prevCtrlPoint = [data[4] - data[2], data[5] - data[3]]; // Save control point for shorthand
|
||||
break;
|
||||
case 'S':
|
||||
if (prev.instruction == 'C' || prev.instruction == 'S') {
|
||||
addPoint(subPath, [basePoint[0] + .5 * prevCtrlPoint[0], basePoint[1] + .5 * prevCtrlPoint[1]]);
|
||||
ctrlPoint = [basePoint[0] + prevCtrlPoint[0], basePoint[1] + prevCtrlPoint[1]];
|
||||
}
|
||||
addPoint(subPath, [.5 * (ctrlPoint[0] + data[0]), .5 * (ctrlPoint[1]+ data[1])]);
|
||||
addPoint(subPath, [.5 * (data[0] + data[2]), .5 * (data[1] + data[3])]);
|
||||
prevCtrlPoint = [data[2] - data[0], data[3] - data[1]];
|
||||
break;
|
||||
case 'A':
|
||||
// Convert the arc to bezier curves and use the same approximation
|
||||
var curves = a2c.apply(0, basePoint.concat(data));
|
||||
for (var cData; (cData = curves.splice(0,6).map(toAbsolute)).length;) {
|
||||
addPoint(subPath, [.5 * (basePoint[0] + cData[0]), .5 * (basePoint[1] + cData[1])]);
|
||||
addPoint(subPath, [.5 * (cData[0] + cData[2]), .5 * (cData[1] + cData[3])]);
|
||||
addPoint(subPath, [.5 * (cData[2] + cData[4]), .5 * (cData[3] + cData[5])]);
|
||||
if (curves.length) addPoint(subPath, basePoint = cData.slice(-2));
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Save final command coordinates
|
||||
if (data && data.length >= 2) addPoint(subPath, data.slice(-2));
|
||||
return points;
|
||||
|
||||
function toAbsolute(n, i) { return n + basePoint[i % 2] }
|
||||
|
||||
// Writes data about the extreme points on each axle
|
||||
function addPoint(path, point) {
|
||||
if (!path.length || point[1] > path[path.maxY][1]) {
|
||||
path.maxY = path.length;
|
||||
points.maxY = points.length ? Math.max(point[1], points.maxY) : point[1];
|
||||
}
|
||||
if (!path.length || point[0] > path[path.maxX][0]) {
|
||||
path.maxX = path.length;
|
||||
points.maxX = points.length ? Math.max(point[0], points.maxX) : point[0];
|
||||
}
|
||||
if (!path.length || point[1] < path[path.minY][1]) {
|
||||
path.minY = path.length;
|
||||
points.minY = points.length ? Math.min(point[1], points.minY) : point[1];
|
||||
}
|
||||
if (!path.length || point[0] < path[path.minX][0]) {
|
||||
path.minX = path.length;
|
||||
points.minX = points.length ? Math.min(point[0], points.minX) : point[0];
|
||||
}
|
||||
path.push(point);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms a convex hull from set of points of every subpath using monotone chain convex hull algorithm.
|
||||
* http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain
|
||||
*
|
||||
* @param points An array of [X, Y] coordinates
|
||||
*/
|
||||
function convexHull(points) {
|
||||
/* jshint -W004 */
|
||||
|
||||
points.sort(function(a, b) {
|
||||
return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0];
|
||||
});
|
||||
|
||||
var lower = [],
|
||||
minY = 0,
|
||||
bottom = 0;
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], points[i]) <= 0) {
|
||||
lower.pop();
|
||||
}
|
||||
if (points[i][1] < points[minY][1]) {
|
||||
minY = i;
|
||||
bottom = lower.length;
|
||||
}
|
||||
lower.push(points[i]);
|
||||
}
|
||||
|
||||
var upper = [],
|
||||
maxY = points.length - 1,
|
||||
top = 0;
|
||||
for (var i = points.length; i--;) {
|
||||
while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], points[i]) <= 0) {
|
||||
upper.pop();
|
||||
}
|
||||
if (points[i][1] > points[maxY][1]) {
|
||||
maxY = i;
|
||||
top = upper.length;
|
||||
}
|
||||
upper.push(points[i]);
|
||||
}
|
||||
|
||||
// last points are equal to starting points of the other part
|
||||
upper.pop();
|
||||
lower.pop();
|
||||
|
||||
var hull = lower.concat(upper);
|
||||
|
||||
hull.minX = 0; // by sorting
|
||||
hull.maxX = lower.length;
|
||||
hull.minY = bottom;
|
||||
hull.maxY = (lower.length + top) % hull.length;
|
||||
|
||||
return hull;
|
||||
}
|
||||
|
||||
function cross(o, a, b) {
|
||||
return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
|
||||
}
|
||||
|
||||
/* Based on code from Snap.svg (Apache 2 license). http://snapsvg.io/
|
||||
* Thanks to Dmitry Baranovskiy for his great work!
|
||||
*/
|
||||
|
||||
// jshint ignore: start
|
||||
function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {
|
||||
// for more information of where this Math came from visit:
|
||||
// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
|
||||
var _120 = Math.PI * 120 / 180,
|
||||
rad = Math.PI / 180 * (+angle || 0),
|
||||
res = [],
|
||||
rotateX = function(x, y, rad) { return x * Math.cos(rad) - y * Math.sin(rad) },
|
||||
rotateY = function(x, y, rad) { return x * Math.sin(rad) + y * Math.cos(rad) };
|
||||
if (!recursive) {
|
||||
x1 = rotateX(x1, y1, -rad);
|
||||
y1 = rotateY(x1, y1, -rad);
|
||||
x2 = rotateX(x2, y2, -rad);
|
||||
y2 = rotateY(x2, y2, -rad);
|
||||
var x = (x1 - x2) / 2,
|
||||
y = (y1 - y2) / 2;
|
||||
var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
|
||||
if (h > 1) {
|
||||
h = Math.sqrt(h);
|
||||
rx = h * rx;
|
||||
ry = h * ry;
|
||||
}
|
||||
var rx2 = rx * rx,
|
||||
ry2 = ry * ry,
|
||||
k = (large_arc_flag == sweep_flag ? -1 : 1) *
|
||||
Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),
|
||||
cx = k * rx * y / ry + (x1 + x2) / 2,
|
||||
cy = k * -ry * x / rx + (y1 + y2) / 2,
|
||||
f1 = Math.asin(((y1 - cy) / ry).toFixed(9)),
|
||||
f2 = Math.asin(((y2 - cy) / ry).toFixed(9));
|
||||
|
||||
f1 = x1 < cx ? Math.PI - f1 : f1;
|
||||
f2 = x2 < cx ? Math.PI - f2 : f2;
|
||||
f1 < 0 && (f1 = Math.PI * 2 + f1);
|
||||
f2 < 0 && (f2 = Math.PI * 2 + f2);
|
||||
if (sweep_flag && f1 > f2) {
|
||||
f1 = f1 - Math.PI * 2;
|
||||
}
|
||||
if (!sweep_flag && f2 > f1) {
|
||||
f2 = f2 - Math.PI * 2;
|
||||
}
|
||||
} else {
|
||||
f1 = recursive[0];
|
||||
f2 = recursive[1];
|
||||
cx = recursive[2];
|
||||
cy = recursive[3];
|
||||
}
|
||||
var df = f2 - f1;
|
||||
if (Math.abs(df) > _120) {
|
||||
var f2old = f2,
|
||||
x2old = x2,
|
||||
y2old = y2;
|
||||
f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
|
||||
x2 = cx + rx * Math.cos(f2);
|
||||
y2 = cy + ry * Math.sin(f2);
|
||||
res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
|
||||
}
|
||||
df = f2 - f1;
|
||||
var c1 = Math.cos(f1),
|
||||
s1 = Math.sin(f1),
|
||||
c2 = Math.cos(f2),
|
||||
s2 = Math.sin(f2),
|
||||
t = Math.tan(df / 4),
|
||||
hx = 4 / 3 * rx * t,
|
||||
hy = 4 / 3 * ry * t,
|
||||
m = [
|
||||
- hx * s1, hy * c1,
|
||||
x2 + hx * s2 - x1, y2 - hy * c2 - y1,
|
||||
x2 - x1, y2 - y1
|
||||
];
|
||||
if (recursive) {
|
||||
return m.concat(res);
|
||||
} else {
|
||||
res = m.concat(res);
|
||||
var newres = [];
|
||||
for (var i = 0, n = res.length; i < n; i++) {
|
||||
newres[i] = i % 2 ? rotateY(res[i - 1], res[i], rad) : rotateX(res[i], res[i + 1], rad);
|
||||
}
|
||||
return newres;
|
||||
}
|
||||
}
|
||||
// jshint ignore: end
|
310
assets_old/node_modules/svgo/plugins/_transforms.js
generated
vendored
Normal file
310
assets_old/node_modules/svgo/plugins/_transforms.js
generated
vendored
Normal file
|
@ -0,0 +1,310 @@
|
|||
'use strict';
|
||||
|
||||
var regTransformTypes = /matrix|translate|scale|rotate|skewX|skewY/,
|
||||
regTransformSplit = /\s*(matrix|translate|scale|rotate|skewX|skewY)\s*\(\s*(.+?)\s*\)[\s,]*/,
|
||||
regNumericValues = /[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
|
||||
|
||||
/**
|
||||
* Convert transform string to JS representation.
|
||||
*
|
||||
* @param {String} transformString input string
|
||||
* @param {Object} params plugin params
|
||||
* @return {Array} output array
|
||||
*/
|
||||
exports.transform2js = function(transformString) {
|
||||
|
||||
// JS representation of the transform data
|
||||
var transforms = [],
|
||||
// current transform context
|
||||
current;
|
||||
|
||||
// split value into ['', 'translate', '10 50', '', 'scale', '2', '', 'rotate', '-45', '']
|
||||
transformString.split(regTransformSplit).forEach(function(item) {
|
||||
/*jshint -W084 */
|
||||
var num;
|
||||
|
||||
if (item) {
|
||||
// if item is a translate function
|
||||
if (regTransformTypes.test(item)) {
|
||||
// then collect it and change current context
|
||||
transforms.push(current = { name: item });
|
||||
// else if item is data
|
||||
} else {
|
||||
// then split it into [10, 50] and collect as context.data
|
||||
while (num = regNumericValues.exec(item)) {
|
||||
num = Number(num);
|
||||
if (current.data)
|
||||
current.data.push(num);
|
||||
else
|
||||
current.data = [num];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// return empty array if broken transform (no data)
|
||||
return current && current.data ? transforms : [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Multiply transforms into one.
|
||||
*
|
||||
* @param {Array} input transforms array
|
||||
* @return {Array} output matrix array
|
||||
*/
|
||||
exports.transformsMultiply = function(transforms) {
|
||||
|
||||
// convert transforms objects to the matrices
|
||||
transforms = transforms.map(function(transform) {
|
||||
if (transform.name === 'matrix') {
|
||||
return transform.data;
|
||||
}
|
||||
return transformToMatrix(transform);
|
||||
});
|
||||
|
||||
// multiply all matrices into one
|
||||
transforms = {
|
||||
name: 'matrix',
|
||||
data: transforms.length > 0 ? transforms.reduce(multiplyTransformMatrices) : []
|
||||
};
|
||||
|
||||
return transforms;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Do math like a schoolgirl.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var mth = exports.mth = {
|
||||
|
||||
rad: function(deg) {
|
||||
return deg * Math.PI / 180;
|
||||
},
|
||||
|
||||
deg: function(rad) {
|
||||
return rad * 180 / Math.PI;
|
||||
},
|
||||
|
||||
cos: function(deg) {
|
||||
return Math.cos(this.rad(deg));
|
||||
},
|
||||
|
||||
acos: function(val, floatPrecision) {
|
||||
return +(this.deg(Math.acos(val)).toFixed(floatPrecision));
|
||||
},
|
||||
|
||||
sin: function(deg) {
|
||||
return Math.sin(this.rad(deg));
|
||||
},
|
||||
|
||||
asin: function(val, floatPrecision) {
|
||||
return +(this.deg(Math.asin(val)).toFixed(floatPrecision));
|
||||
},
|
||||
|
||||
tan: function(deg) {
|
||||
return Math.tan(this.rad(deg));
|
||||
},
|
||||
|
||||
atan: function(val, floatPrecision) {
|
||||
return +(this.deg(Math.atan(val)).toFixed(floatPrecision));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Decompose matrix into simple transforms. See
|
||||
* http://frederic-wang.fr/decomposition-of-2d-transform-matrices.html
|
||||
*
|
||||
* @param {Object} data matrix transform object
|
||||
* @return {Object|Array} transforms array or original transform object
|
||||
*/
|
||||
exports.matrixToTransform = function(transform, params) {
|
||||
var floatPrecision = params.floatPrecision,
|
||||
data = transform.data,
|
||||
transforms = [],
|
||||
sx = +Math.hypot(data[0], data[1]).toFixed(params.transformPrecision),
|
||||
sy = +((data[0] * data[3] - data[1] * data[2]) / sx).toFixed(params.transformPrecision),
|
||||
colsSum = data[0] * data[2] + data[1] * data[3],
|
||||
rowsSum = data[0] * data[1] + data[2] * data[3],
|
||||
scaleBefore = rowsSum != 0 || sx == sy;
|
||||
|
||||
// [..., ..., ..., ..., tx, ty] → translate(tx, ty)
|
||||
if (data[4] || data[5]) {
|
||||
transforms.push({ name: 'translate', data: data.slice(4, data[5] ? 6 : 5) });
|
||||
}
|
||||
|
||||
// [sx, 0, tan(a)·sy, sy, 0, 0] → skewX(a)·scale(sx, sy)
|
||||
if (!data[1] && data[2]) {
|
||||
transforms.push({ name: 'skewX', data: [mth.atan(data[2] / sy, floatPrecision)] });
|
||||
|
||||
// [sx, sx·tan(a), 0, sy, 0, 0] → skewY(a)·scale(sx, sy)
|
||||
} else if (data[1] && !data[2]) {
|
||||
transforms.push({ name: 'skewY', data: [mth.atan(data[1] / data[0], floatPrecision)] });
|
||||
sx = data[0];
|
||||
sy = data[3];
|
||||
|
||||
// [sx·cos(a), sx·sin(a), sy·-sin(a), sy·cos(a), x, y] → rotate(a[, cx, cy])·(scale or skewX) or
|
||||
// [sx·cos(a), sy·sin(a), sx·-sin(a), sy·cos(a), x, y] → scale(sx, sy)·rotate(a[, cx, cy]) (if !scaleBefore)
|
||||
} else if (!colsSum || (sx == 1 && sy == 1) || !scaleBefore) {
|
||||
if (!scaleBefore) {
|
||||
sx = (data[0] < 0 ? -1 : 1) * Math.hypot(data[0], data[2]);
|
||||
sy = (data[3] < 0 ? -1 : 1) * Math.hypot(data[1], data[3]);
|
||||
transforms.push({ name: 'scale', data: [sx, sy] });
|
||||
}
|
||||
var angle = Math.min(Math.max(-1, data[0] / sx), 1),
|
||||
rotate = [mth.acos(angle, floatPrecision) * ((scaleBefore ? 1 : sy) * data[1] < 0 ? -1 : 1)];
|
||||
|
||||
if (rotate[0]) transforms.push({ name: 'rotate', data: rotate });
|
||||
|
||||
if (rowsSum && colsSum) transforms.push({
|
||||
name: 'skewX',
|
||||
data: [mth.atan(colsSum / (sx * sx), floatPrecision)]
|
||||
});
|
||||
|
||||
// rotate(a, cx, cy) can consume translate() within optional arguments cx, cy (rotation point)
|
||||
if (rotate[0] && (data[4] || data[5])) {
|
||||
transforms.shift();
|
||||
var cos = data[0] / sx,
|
||||
sin = data[1] / (scaleBefore ? sx : sy),
|
||||
x = data[4] * (scaleBefore || sy),
|
||||
y = data[5] * (scaleBefore || sx),
|
||||
denom = (Math.pow(1 - cos, 2) + Math.pow(sin, 2)) * (scaleBefore || sx * sy);
|
||||
rotate.push(((1 - cos) * x - sin * y) / denom);
|
||||
rotate.push(((1 - cos) * y + sin * x) / denom);
|
||||
}
|
||||
|
||||
// Too many transformations, return original matrix if it isn't just a scale/translate
|
||||
} else if (data[1] || data[2]) {
|
||||
return transform;
|
||||
}
|
||||
|
||||
if (scaleBefore && (sx != 1 || sy != 1) || !transforms.length) transforms.push({
|
||||
name: 'scale',
|
||||
data: sx == sy ? [sx] : [sx, sy]
|
||||
});
|
||||
|
||||
return transforms;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert transform to the matrix data.
|
||||
*
|
||||
* @param {Object} transform transform object
|
||||
* @return {Array} matrix data
|
||||
*/
|
||||
function transformToMatrix(transform) {
|
||||
|
||||
if (transform.name === 'matrix') return transform.data;
|
||||
|
||||
var matrix;
|
||||
|
||||
switch (transform.name) {
|
||||
case 'translate':
|
||||
// [1, 0, 0, 1, tx, ty]
|
||||
matrix = [1, 0, 0, 1, transform.data[0], transform.data[1] || 0];
|
||||
break;
|
||||
case 'scale':
|
||||
// [sx, 0, 0, sy, 0, 0]
|
||||
matrix = [transform.data[0], 0, 0, transform.data[1] || transform.data[0], 0, 0];
|
||||
break;
|
||||
case 'rotate':
|
||||
// [cos(a), sin(a), -sin(a), cos(a), x, y]
|
||||
var cos = mth.cos(transform.data[0]),
|
||||
sin = mth.sin(transform.data[0]),
|
||||
cx = transform.data[1] || 0,
|
||||
cy = transform.data[2] || 0;
|
||||
|
||||
matrix = [cos, sin, -sin, cos, (1 - cos) * cx + sin * cy, (1 - cos) * cy - sin * cx];
|
||||
break;
|
||||
case 'skewX':
|
||||
// [1, 0, tan(a), 1, 0, 0]
|
||||
matrix = [1, 0, mth.tan(transform.data[0]), 1, 0, 0];
|
||||
break;
|
||||
case 'skewY':
|
||||
// [1, tan(a), 0, 1, 0, 0]
|
||||
matrix = [1, mth.tan(transform.data[0]), 0, 1, 0, 0];
|
||||
break;
|
||||
}
|
||||
|
||||
return matrix;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies transformation to an arc. To do so, we represent ellipse as a matrix, multiply it
|
||||
* by the transformation matrix and use a singular value decomposition to represent in a form
|
||||
* rotate(θ)·scale(a b)·rotate(φ). This gives us new ellipse params a, b and θ.
|
||||
* SVD is being done with the formulae provided by Wolffram|Alpha (svd {{m0, m2}, {m1, m3}})
|
||||
*
|
||||
* @param {Array} arc [a, b, rotation in deg]
|
||||
* @param {Array} transform transformation matrix
|
||||
* @return {Array} arc transformed input arc
|
||||
*/
|
||||
exports.transformArc = function(arc, transform) {
|
||||
|
||||
var a = arc[0],
|
||||
b = arc[1],
|
||||
rot = arc[2] * Math.PI / 180,
|
||||
cos = Math.cos(rot),
|
||||
sin = Math.sin(rot),
|
||||
h = Math.pow(arc[5] * cos + arc[6] * sin, 2) / (4 * a * a) +
|
||||
Math.pow(arc[6] * cos - arc[5] * sin, 2) / (4 * b * b);
|
||||
if (h > 1) {
|
||||
h = Math.sqrt(h);
|
||||
a *= h;
|
||||
b *= h;
|
||||
}
|
||||
var ellipse = [a * cos, a * sin, -b * sin, b * cos, 0, 0],
|
||||
m = multiplyTransformMatrices(transform, ellipse),
|
||||
// Decompose the new ellipse matrix
|
||||
lastCol = m[2] * m[2] + m[3] * m[3],
|
||||
squareSum = m[0] * m[0] + m[1] * m[1] + lastCol,
|
||||
root = Math.hypot(m[0] - m[3], m[1] + m[2]) * Math.hypot(m[0] + m[3], m[1] - m[2]);
|
||||
|
||||
if (!root) { // circle
|
||||
arc[0] = arc[1] = Math.sqrt(squareSum / 2);
|
||||
arc[2] = 0;
|
||||
} else {
|
||||
var majorAxisSqr = (squareSum + root) / 2,
|
||||
minorAxisSqr = (squareSum - root) / 2,
|
||||
major = Math.abs(majorAxisSqr - lastCol) > 1e-6,
|
||||
sub = (major ? majorAxisSqr : minorAxisSqr) - lastCol,
|
||||
rowsSum = m[0] * m[2] + m[1] * m[3],
|
||||
term1 = m[0] * sub + m[2] * rowsSum,
|
||||
term2 = m[1] * sub + m[3] * rowsSum;
|
||||
arc[0] = Math.sqrt(majorAxisSqr);
|
||||
arc[1] = Math.sqrt(minorAxisSqr);
|
||||
arc[2] = ((major ? term2 < 0 : term1 > 0) ? -1 : 1) *
|
||||
Math.acos((major ? term1 : term2) / Math.hypot(term1, term2)) * 180 / Math.PI;
|
||||
}
|
||||
|
||||
if ((transform[0] < 0) !== (transform[3] < 0)) {
|
||||
// Flip the sweep flag if coordinates are being flipped horizontally XOR vertically
|
||||
arc[4] = 1 - arc[4];
|
||||
}
|
||||
|
||||
return arc;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Multiply transformation matrices.
|
||||
*
|
||||
* @param {Array} a matrix A data
|
||||
* @param {Array} b matrix B data
|
||||
* @return {Array} result
|
||||
*/
|
||||
function multiplyTransformMatrices(a, b) {
|
||||
|
||||
return [
|
||||
a[0] * b[0] + a[2] * b[1],
|
||||
a[1] * b[0] + a[3] * b[1],
|
||||
a[0] * b[2] + a[2] * b[3],
|
||||
a[1] * b[2] + a[3] * b[3],
|
||||
a[0] * b[4] + a[2] * b[5] + a[4],
|
||||
a[1] * b[4] + a[3] * b[5] + a[5]
|
||||
];
|
||||
|
||||
}
|
82
assets_old/node_modules/svgo/plugins/addAttributesToSVGElement.js
generated
vendored
Normal file
82
assets_old/node_modules/svgo/plugins/addAttributesToSVGElement.js
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'adds attributes to an outer <svg> element';
|
||||
|
||||
var ENOCLS = `Error in plugin "addAttributesToSVGElement": absent parameters.
|
||||
It should have a list of "attributes" or one "attribute".
|
||||
Config example:
|
||||
|
||||
plugins:
|
||||
- addAttributesToSVGElement:
|
||||
attribute: "mySvg"
|
||||
|
||||
plugins:
|
||||
- addAttributesToSVGElement:
|
||||
attributes: ["mySvg", "size-big"]
|
||||
|
||||
plugins:
|
||||
- addAttributesToSVGElement:
|
||||
attributes:
|
||||
- focusable: false
|
||||
- data-image: icon`;
|
||||
|
||||
/**
|
||||
* Add attributes to an outer <svg> element. Example config:
|
||||
*
|
||||
* plugins:
|
||||
* - addAttributesToSVGElement:
|
||||
* attribute: 'data-icon'
|
||||
*
|
||||
* plugins:
|
||||
* - addAttributesToSVGElement:
|
||||
* attributes: ['data-icon', 'data-disabled']
|
||||
*
|
||||
* plugins:
|
||||
* - addAttributesToSVGElement:
|
||||
* attributes:
|
||||
* - focusable: false
|
||||
* - data-image: icon
|
||||
*
|
||||
* @author April Arcus
|
||||
*/
|
||||
exports.fn = function(data, params) {
|
||||
if (!params || !(Array.isArray(params.attributes) || params.attribute)) {
|
||||
console.error(ENOCLS);
|
||||
return data;
|
||||
}
|
||||
|
||||
var attributes = params.attributes || [ params.attribute ],
|
||||
svg = data.content[0];
|
||||
|
||||
if (svg.isElem('svg')) {
|
||||
attributes.forEach(function (attribute) {
|
||||
if (typeof attribute === 'string') {
|
||||
if (!svg.hasAttr(attribute)) {
|
||||
svg.addAttr({
|
||||
name: attribute,
|
||||
prefix: '',
|
||||
local: attribute
|
||||
});
|
||||
}
|
||||
} else if (typeof attribute === 'object') {
|
||||
Object.keys(attribute).forEach(function (key) {
|
||||
if (!svg.hasAttr(key)) {
|
||||
svg.addAttr({
|
||||
name: key,
|
||||
value: attribute[key],
|
||||
prefix: '',
|
||||
local: key
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
};
|
50
assets_old/node_modules/svgo/plugins/addClassesToSVGElement.js
generated
vendored
Normal file
50
assets_old/node_modules/svgo/plugins/addClassesToSVGElement.js
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'adds classnames to an outer <svg> element';
|
||||
|
||||
var ENOCLS = `Error in plugin "addClassesToSVGElement": absent parameters.
|
||||
It should have a list of classes in "classNames" or one "className".
|
||||
Config example:
|
||||
|
||||
plugins:
|
||||
- addClassesToSVGElement:
|
||||
className: "mySvg"
|
||||
|
||||
plugins:
|
||||
- addClassesToSVGElement:
|
||||
classNames: ["mySvg", "size-big"]
|
||||
`;
|
||||
|
||||
/**
|
||||
* Add classnames to an outer <svg> element. Example config:
|
||||
*
|
||||
* plugins:
|
||||
* - addClassesToSVGElement:
|
||||
* className: 'mySvg'
|
||||
*
|
||||
* plugins:
|
||||
* - addClassesToSVGElement:
|
||||
* classNames: ['mySvg', 'size-big']
|
||||
*
|
||||
* @author April Arcus
|
||||
*/
|
||||
exports.fn = function(data, params) {
|
||||
if (!params || !(Array.isArray(params.classNames) && params.classNames.some(String) || params.className)) {
|
||||
console.error(ENOCLS);
|
||||
return data;
|
||||
}
|
||||
|
||||
var classNames = params.classNames || [ params.className ],
|
||||
svg = data.content[0];
|
||||
|
||||
if (svg.isElem('svg')) {
|
||||
svg.class.add.apply(svg.class, classNames);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
};
|
56
assets_old/node_modules/svgo/plugins/cleanupAttrs.js
generated
vendored
Normal file
56
assets_old/node_modules/svgo/plugins/cleanupAttrs.js
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'cleanups attributes from newlines, trailing and repeating spaces';
|
||||
|
||||
exports.params = {
|
||||
newlines: true,
|
||||
trim: true,
|
||||
spaces: true
|
||||
};
|
||||
|
||||
var regNewlinesNeedSpace = /(\S)\r?\n(\S)/g,
|
||||
regNewlines = /\r?\n/g,
|
||||
regSpaces = /\s{2,}/g;
|
||||
|
||||
/**
|
||||
* Cleanup attributes values from newlines, trailing and repeating spaces.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
if (item.isElem()) {
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
|
||||
if (params.newlines) {
|
||||
// new line which requires a space instead of themselve
|
||||
attr.value = attr.value.replace(regNewlinesNeedSpace, function(match, p1, p2) {
|
||||
return p1 + ' ' + p2;
|
||||
});
|
||||
|
||||
// simple new line
|
||||
attr.value = attr.value.replace(regNewlines, '');
|
||||
}
|
||||
|
||||
if (params.trim) {
|
||||
attr.value = attr.value.trim();
|
||||
}
|
||||
|
||||
if (params.spaces) {
|
||||
attr.value = attr.value.replace(regSpaces, ' ');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
84
assets_old/node_modules/svgo/plugins/cleanupEnableBackground.js
generated
vendored
Normal file
84
assets_old/node_modules/svgo/plugins/cleanupEnableBackground.js
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'remove or cleanup enable-background attribute when possible';
|
||||
|
||||
/**
|
||||
* Remove or cleanup enable-background attr which coincides with a width/height box.
|
||||
*
|
||||
* @see http://www.w3.org/TR/SVG/filters.html#EnableBackgroundProperty
|
||||
*
|
||||
* @example
|
||||
* <svg width="100" height="50" enable-background="new 0 0 100 50">
|
||||
* ⬇
|
||||
* <svg width="100" height="50">
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(data) {
|
||||
|
||||
var regEnableBackground = /^new\s0\s0\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)$/,
|
||||
hasFilter = false,
|
||||
elems = ['svg', 'mask', 'pattern'];
|
||||
|
||||
function checkEnableBackground(item) {
|
||||
if (
|
||||
item.isElem(elems) &&
|
||||
item.hasAttr('enable-background') &&
|
||||
item.hasAttr('width') &&
|
||||
item.hasAttr('height')
|
||||
) {
|
||||
|
||||
var match = item.attr('enable-background').value.match(regEnableBackground);
|
||||
|
||||
if (match) {
|
||||
if (
|
||||
item.attr('width').value === match[1] &&
|
||||
item.attr('height').value === match[3]
|
||||
) {
|
||||
if (item.isElem('svg')) {
|
||||
item.removeAttr('enable-background');
|
||||
} else {
|
||||
item.attr('enable-background').value = 'new';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function checkForFilter(item) {
|
||||
if (item.isElem('filter')) {
|
||||
hasFilter = true;
|
||||
}
|
||||
}
|
||||
|
||||
function monkeys(items, fn) {
|
||||
items.content.forEach(function(item) {
|
||||
fn(item);
|
||||
|
||||
if (item.content) {
|
||||
monkeys(item, fn);
|
||||
}
|
||||
});
|
||||
return items;
|
||||
}
|
||||
|
||||
var firstStep = monkeys(data, function(item) {
|
||||
checkEnableBackground(item);
|
||||
if (!hasFilter) {
|
||||
checkForFilter(item);
|
||||
}
|
||||
});
|
||||
|
||||
return hasFilter ? firstStep : monkeys(firstStep, function(item) {
|
||||
//we don't need 'enable-background' if we have no filters
|
||||
item.removeAttr('enable-background');
|
||||
});
|
||||
};
|
209
assets_old/node_modules/svgo/plugins/cleanupIDs.js
generated
vendored
Normal file
209
assets_old/node_modules/svgo/plugins/cleanupIDs.js
generated
vendored
Normal file
|
@ -0,0 +1,209 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes unused IDs and minifies used';
|
||||
|
||||
exports.params = {
|
||||
remove: true,
|
||||
minify: true,
|
||||
prefix: '',
|
||||
preserve: [],
|
||||
preservePrefixes: [],
|
||||
force: false
|
||||
};
|
||||
|
||||
var referencesProps = new Set(require('./_collections').referencesProps),
|
||||
regReferencesUrl = /\burl\(("|')?#(.+?)\1\)/,
|
||||
regReferencesHref = /^#(.+?)$/,
|
||||
regReferencesBegin = /(\w+)\./,
|
||||
styleOrScript = ['style', 'script'],
|
||||
generateIDchars = [
|
||||
'a', 'b', 'c', 'd', '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', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
|
||||
],
|
||||
maxIDindex = generateIDchars.length - 1;
|
||||
|
||||
/**
|
||||
* Remove unused and minify used IDs
|
||||
* (only if there are no any <style> or <script>).
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(data, params) {
|
||||
var currentID,
|
||||
currentIDstring,
|
||||
IDs = new Map(),
|
||||
referencesIDs = new Map(),
|
||||
hasStyleOrScript = false,
|
||||
preserveIDs = new Set(Array.isArray(params.preserve) ? params.preserve : params.preserve ? [params.preserve] : []),
|
||||
preserveIDPrefixes = new Set(Array.isArray(params.preservePrefixes) ? params.preservePrefixes : (params.preservePrefixes ? [params.preservePrefixes] : [])),
|
||||
idValuePrefix = '#',
|
||||
idValuePostfix = '.';
|
||||
|
||||
/**
|
||||
* Bananas!
|
||||
*
|
||||
* @param {Array} items input items
|
||||
* @return {Array} output items
|
||||
*/
|
||||
function monkeys(items) {
|
||||
for (var i = 0; i < items.content.length && !hasStyleOrScript; i++) {
|
||||
var item = items.content[i];
|
||||
|
||||
// quit if <style> or <script> present ('force' param prevents quitting)
|
||||
if (!params.force) {
|
||||
if (item.isElem(styleOrScript)) {
|
||||
hasStyleOrScript = true;
|
||||
continue;
|
||||
}
|
||||
// Don't remove IDs if the whole SVG consists only of defs.
|
||||
if (item.isElem('defs') && item.parentNode.isElem('svg')) {
|
||||
var hasDefsOnly = true;
|
||||
for (var j = i + 1; j < items.content.length; j++) {
|
||||
if (items.content[j].isElem()) {
|
||||
hasDefsOnly = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasDefsOnly) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// …and don't remove any ID if yes
|
||||
if (item.isElem()) {
|
||||
item.eachAttr(function(attr) {
|
||||
var key, match;
|
||||
|
||||
// save IDs
|
||||
if (attr.name === 'id') {
|
||||
key = attr.value;
|
||||
if (IDs.has(key)) {
|
||||
item.removeAttr('id'); // remove repeated id
|
||||
} else {
|
||||
IDs.set(key, item);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// save references
|
||||
if (referencesProps.has(attr.name) && (match = attr.value.match(regReferencesUrl))) {
|
||||
key = match[2]; // url() reference
|
||||
} else if (
|
||||
attr.local === 'href' && (match = attr.value.match(regReferencesHref)) ||
|
||||
attr.name === 'begin' && (match = attr.value.match(regReferencesBegin))
|
||||
) {
|
||||
key = match[1]; // href reference
|
||||
}
|
||||
if (key) {
|
||||
var ref = referencesIDs.get(key) || [];
|
||||
ref.push(attr);
|
||||
referencesIDs.set(key, ref);
|
||||
}
|
||||
});
|
||||
}
|
||||
// go deeper
|
||||
if (item.content) {
|
||||
monkeys(item);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
data = monkeys(data);
|
||||
|
||||
if (hasStyleOrScript) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const idPreserved = id => preserveIDs.has(id) || idMatchesPrefix(preserveIDPrefixes, id);
|
||||
|
||||
for (var ref of referencesIDs) {
|
||||
var key = ref[0];
|
||||
|
||||
if (IDs.has(key)) {
|
||||
// replace referenced IDs with the minified ones
|
||||
if (params.minify && !idPreserved(key)) {
|
||||
do {
|
||||
currentIDstring = getIDstring(currentID = generateID(currentID), params);
|
||||
} while (idPreserved(currentIDstring));
|
||||
|
||||
IDs.get(key).attr('id').value = currentIDstring;
|
||||
|
||||
for (var attr of ref[1]) {
|
||||
attr.value = attr.value.includes(idValuePrefix) ?
|
||||
attr.value.replace(idValuePrefix + key, idValuePrefix + currentIDstring) :
|
||||
attr.value.replace(key + idValuePostfix, currentIDstring + idValuePostfix);
|
||||
}
|
||||
}
|
||||
// don't remove referenced IDs
|
||||
IDs.delete(key);
|
||||
}
|
||||
}
|
||||
// remove non-referenced IDs attributes from elements
|
||||
if (params.remove) {
|
||||
for(var keyElem of IDs) {
|
||||
if (!idPreserved(keyElem[0])) {
|
||||
keyElem[1].removeAttr('id');
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if an ID starts with any one of a list of strings.
|
||||
*
|
||||
* @param {Array} of prefix strings
|
||||
* @param {String} current ID
|
||||
* @return {Boolean} if currentID starts with one of the strings in prefixArray
|
||||
*/
|
||||
function idMatchesPrefix(prefixArray, currentID) {
|
||||
if (!currentID) return false;
|
||||
|
||||
for (var prefix of prefixArray) if (currentID.startsWith(prefix)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate unique minimal ID.
|
||||
*
|
||||
* @param {Array} [currentID] current ID
|
||||
* @return {Array} generated ID array
|
||||
*/
|
||||
function generateID(currentID) {
|
||||
if (!currentID) return [0];
|
||||
|
||||
currentID[currentID.length - 1]++;
|
||||
|
||||
for(var i = currentID.length - 1; i > 0; i--) {
|
||||
if (currentID[i] > maxIDindex) {
|
||||
currentID[i] = 0;
|
||||
|
||||
if (currentID[i - 1] !== undefined) {
|
||||
currentID[i - 1]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentID[0] > maxIDindex) {
|
||||
currentID[0] = 0;
|
||||
currentID.unshift(0);
|
||||
}
|
||||
return currentID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string from generated ID array.
|
||||
*
|
||||
* @param {Array} arr input ID array
|
||||
* @return {String} output ID string
|
||||
*/
|
||||
function getIDstring(arr, params) {
|
||||
var str = params.prefix;
|
||||
return str + arr.map(i => generateIDchars[i]).join('');
|
||||
}
|
139
assets_old/node_modules/svgo/plugins/cleanupListOfValues.js
generated
vendored
Normal file
139
assets_old/node_modules/svgo/plugins/cleanupListOfValues.js
generated
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'rounds list of values to the fixed precision';
|
||||
|
||||
exports.params = {
|
||||
floatPrecision: 3,
|
||||
leadingZero: true,
|
||||
defaultPx: true,
|
||||
convertToPx: true
|
||||
};
|
||||
|
||||
var regNumericValues = /^([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/,
|
||||
regSeparator = /\s+,?\s*|,\s*/,
|
||||
removeLeadingZero = require('../lib/svgo/tools').removeLeadingZero,
|
||||
absoluteLengths = { // relative to px
|
||||
cm: 96/2.54,
|
||||
mm: 96/25.4,
|
||||
in: 96,
|
||||
pt: 4/3,
|
||||
pc: 16
|
||||
};
|
||||
|
||||
/**
|
||||
* Round list of values to the fixed precision.
|
||||
*
|
||||
* @example
|
||||
* <svg viewBox="0 0 200.28423 200.28423" enable-background="new 0 0 200.28423 200.28423">
|
||||
* ⬇
|
||||
* <svg viewBox="0 0 200.284 200.284" enable-background="new 0 0 200.284 200.284">
|
||||
*
|
||||
*
|
||||
* <polygon points="208.250977 77.1308594 223.069336 ... "/>
|
||||
* ⬇
|
||||
* <polygon points="208.251 77.131 223.069 ... "/>
|
||||
*
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author kiyopikko
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
|
||||
if ( item.hasAttr('points') ) {
|
||||
roundValues(item.attrs.points);
|
||||
}
|
||||
|
||||
if ( item.hasAttr('enable-background') ) {
|
||||
roundValues(item.attrs['enable-background']);
|
||||
}
|
||||
|
||||
if ( item.hasAttr('viewBox') ) {
|
||||
roundValues(item.attrs.viewBox);
|
||||
}
|
||||
|
||||
if ( item.hasAttr('stroke-dasharray') ) {
|
||||
roundValues(item.attrs['stroke-dasharray']);
|
||||
}
|
||||
|
||||
if ( item.hasAttr('dx') ) {
|
||||
roundValues(item.attrs.dx);
|
||||
}
|
||||
|
||||
if ( item.hasAttr('dy') ) {
|
||||
roundValues(item.attrs.dy);
|
||||
}
|
||||
|
||||
if ( item.hasAttr('x') ) {
|
||||
roundValues(item.attrs.x);
|
||||
}
|
||||
|
||||
if ( item.hasAttr('y') ) {
|
||||
roundValues(item.attrs.y);
|
||||
}
|
||||
|
||||
|
||||
function roundValues($prop){
|
||||
|
||||
var num, units,
|
||||
match,
|
||||
matchNew,
|
||||
lists = $prop.value,
|
||||
listsArr = lists.split(regSeparator),
|
||||
roundedListArr = [],
|
||||
roundedList;
|
||||
|
||||
listsArr.forEach(function(elem){
|
||||
|
||||
match = elem.match(regNumericValues);
|
||||
matchNew = elem.match(/new/);
|
||||
|
||||
// if attribute value matches regNumericValues
|
||||
if (match) {
|
||||
// round it to the fixed precision
|
||||
num = +(+match[1]).toFixed(params.floatPrecision),
|
||||
units = match[3] || '';
|
||||
|
||||
// convert absolute values to pixels
|
||||
if (params.convertToPx && units && (units in absoluteLengths)) {
|
||||
var pxNum = +(absoluteLengths[units] * match[1]).toFixed(params.floatPrecision);
|
||||
|
||||
if (String(pxNum).length < match[0].length)
|
||||
num = pxNum,
|
||||
units = 'px';
|
||||
}
|
||||
|
||||
// and remove leading zero
|
||||
if (params.leadingZero) {
|
||||
num = removeLeadingZero(num);
|
||||
}
|
||||
|
||||
// remove default 'px' units
|
||||
if (params.defaultPx && units === 'px') {
|
||||
units = '';
|
||||
}
|
||||
|
||||
roundedListArr.push(num+units);
|
||||
}
|
||||
// if attribute value is "new"(only enable-background).
|
||||
else if (matchNew) {
|
||||
roundedListArr.push('new');
|
||||
} else if (elem) {
|
||||
roundedListArr.push(elem);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
roundedList = roundedListArr.join(' ');
|
||||
$prop.value = roundedList;
|
||||
|
||||
}
|
||||
|
||||
};
|
88
assets_old/node_modules/svgo/plugins/cleanupNumericValues.js
generated
vendored
Normal file
88
assets_old/node_modules/svgo/plugins/cleanupNumericValues.js
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'rounds numeric values to the fixed precision, removes default ‘px’ units';
|
||||
|
||||
exports.params = {
|
||||
floatPrecision: 3,
|
||||
leadingZero: true,
|
||||
defaultPx: true,
|
||||
convertToPx: true
|
||||
};
|
||||
|
||||
var regNumericValues = /^([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/,
|
||||
removeLeadingZero = require('../lib/svgo/tools').removeLeadingZero,
|
||||
absoluteLengths = { // relative to px
|
||||
cm: 96/2.54,
|
||||
mm: 96/25.4,
|
||||
in: 96,
|
||||
pt: 4/3,
|
||||
pc: 16
|
||||
};
|
||||
|
||||
/**
|
||||
* Round numeric values to the fixed precision,
|
||||
* remove default 'px' units.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
if (item.isElem()) {
|
||||
|
||||
var floatPrecision = params.floatPrecision;
|
||||
|
||||
if (item.hasAttr('viewBox')) {
|
||||
var nums = item.attr('viewBox').value.split(/\s,?\s*|,\s*/g);
|
||||
item.attr('viewBox').value = nums.map(function(value) {
|
||||
var num = +value;
|
||||
return isNaN(num) ? value : +num.toFixed(floatPrecision);
|
||||
}).join(' ');
|
||||
}
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
// The `version` attribute is a text string and cannot be rounded
|
||||
if (attr.name === 'version') { return }
|
||||
|
||||
var match = attr.value.match(regNumericValues);
|
||||
|
||||
// if attribute value matches regNumericValues
|
||||
if (match) {
|
||||
// round it to the fixed precision
|
||||
var num = +(+match[1]).toFixed(floatPrecision),
|
||||
units = match[3] || '';
|
||||
|
||||
// convert absolute values to pixels
|
||||
if (params.convertToPx && units && (units in absoluteLengths)) {
|
||||
var pxNum = +(absoluteLengths[units] * match[1]).toFixed(floatPrecision);
|
||||
|
||||
if (String(pxNum).length < match[0].length) {
|
||||
num = pxNum;
|
||||
units = 'px';
|
||||
}
|
||||
}
|
||||
|
||||
// and remove leading zero
|
||||
if (params.leadingZero) {
|
||||
num = removeLeadingZero(num);
|
||||
}
|
||||
|
||||
// remove default 'px' units
|
||||
if (params.defaultPx && units === 'px') {
|
||||
units = '';
|
||||
}
|
||||
|
||||
attr.value = num + units;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
87
assets_old/node_modules/svgo/plugins/collapseGroups.js
generated
vendored
Normal file
87
assets_old/node_modules/svgo/plugins/collapseGroups.js
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItemReverse';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'collapses useless groups';
|
||||
|
||||
var collections = require('./_collections'),
|
||||
attrsInheritable = collections.inheritableAttrs,
|
||||
animationElems = collections.elemsGroups.animation;
|
||||
|
||||
function hasAnimatedAttr(item) {
|
||||
/* jshint validthis:true */
|
||||
return item.isElem(animationElems) && item.hasAttr('attributeName', this) ||
|
||||
!item.isEmpty() && item.content.some(hasAnimatedAttr, this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Collapse useless groups.
|
||||
*
|
||||
* @example
|
||||
* <g>
|
||||
* <g attr1="val1">
|
||||
* <path d="..."/>
|
||||
* </g>
|
||||
* </g>
|
||||
* ⬇
|
||||
* <g>
|
||||
* <g>
|
||||
* <path attr1="val1" d="..."/>
|
||||
* </g>
|
||||
* </g>
|
||||
* ⬇
|
||||
* <path attr1="val1" d="..."/>
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
// non-empty elements
|
||||
if (item.isElem() && !item.isElem('switch') && !item.isEmpty()) {
|
||||
item.content.forEach(function(g, i) {
|
||||
// non-empty groups
|
||||
if (g.isElem('g') && !g.isEmpty()) {
|
||||
// move group attibutes to the single content element
|
||||
if (g.hasAttr() && g.content.length === 1) {
|
||||
var inner = g.content[0];
|
||||
|
||||
if (inner.isElem() && !inner.hasAttr('id') && !g.hasAttr('filter') &&
|
||||
!(g.hasAttr('class') && inner.hasAttr('class')) && (
|
||||
!g.hasAttr('clip-path') && !g.hasAttr('mask') ||
|
||||
inner.isElem('g') && !g.hasAttr('transform') && !inner.hasAttr('transform')
|
||||
)
|
||||
) {
|
||||
g.eachAttr(function(attr) {
|
||||
if (g.content.some(hasAnimatedAttr, attr.name)) return;
|
||||
|
||||
if (!inner.hasAttr(attr.name)) {
|
||||
inner.addAttr(attr);
|
||||
} else if (attr.name == 'transform') {
|
||||
inner.attr(attr.name).value = attr.value + ' ' + inner.attr(attr.name).value;
|
||||
} else if (inner.hasAttr(attr.name, 'inherit')) {
|
||||
inner.attr(attr.name).value = attr.value;
|
||||
} else if (
|
||||
attrsInheritable.indexOf(attr.name) < 0 &&
|
||||
!inner.hasAttr(attr.name, attr.value)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
g.removeAttr(attr.name);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// collapse groups without attributes
|
||||
if (!g.hasAttr() && !g.content.some(function(item) { return item.isElem(animationElems) })) {
|
||||
item.spliceContent(i, 1, g.content);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
130
assets_old/node_modules/svgo/plugins/convertColors.js
generated
vendored
Normal file
130
assets_old/node_modules/svgo/plugins/convertColors.js
generated
vendored
Normal file
|
@ -0,0 +1,130 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'converts colors: rgb() to #rrggbb and #rrggbb to #rgb';
|
||||
|
||||
exports.params = {
|
||||
currentColor: false,
|
||||
names2hex: true,
|
||||
rgb2hex: true,
|
||||
shorthex: true,
|
||||
shortname: true
|
||||
};
|
||||
|
||||
var collections = require('./_collections'),
|
||||
rNumber = '([+-]?(?:\\d*\\.\\d+|\\d+\\.?)%?)',
|
||||
rComma = '\\s*,\\s*',
|
||||
regRGB = new RegExp('^rgb\\(\\s*' + rNumber + rComma + rNumber + rComma + rNumber + '\\s*\\)$'),
|
||||
regHEX = /^\#(([a-fA-F0-9])\2){3}$/,
|
||||
none = /\bnone\b/i;
|
||||
|
||||
/**
|
||||
* Convert different colors formats in element attributes to hex.
|
||||
*
|
||||
* @see http://www.w3.org/TR/SVG/types.html#DataTypeColor
|
||||
* @see http://www.w3.org/TR/SVG/single-page.html#types-ColorKeywords
|
||||
*
|
||||
* @example
|
||||
* Convert color name keyword to long hex:
|
||||
* fuchsia ➡ #ff00ff
|
||||
*
|
||||
* Convert rgb() to long hex:
|
||||
* rgb(255, 0, 255) ➡ #ff00ff
|
||||
* rgb(50%, 100, 100%) ➡ #7f64ff
|
||||
*
|
||||
* Convert long hex to short hex:
|
||||
* #aabbcc ➡ #abc
|
||||
*
|
||||
* Convert hex to short name
|
||||
* #000080 ➡ navy
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
if (item.elem) {
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
|
||||
if (collections.colorsProps.indexOf(attr.name) > -1) {
|
||||
|
||||
var val = attr.value,
|
||||
match;
|
||||
|
||||
// Convert colors to currentColor
|
||||
if (params.currentColor) {
|
||||
if (typeof params.currentColor === 'string') {
|
||||
match = val === params.currentColor;
|
||||
} else if (params.currentColor.exec) {
|
||||
match = params.currentColor.exec(val);
|
||||
} else {
|
||||
match = !val.match(none);
|
||||
}
|
||||
if (match) {
|
||||
val = 'currentColor';
|
||||
}
|
||||
}
|
||||
|
||||
// Convert color name keyword to long hex
|
||||
if (params.names2hex && val.toLowerCase() in collections.colorsNames) {
|
||||
val = collections.colorsNames[val.toLowerCase()];
|
||||
}
|
||||
|
||||
// Convert rgb() to long hex
|
||||
if (params.rgb2hex && (match = val.match(regRGB))) {
|
||||
match = match.slice(1, 4).map(function(m) {
|
||||
if (m.indexOf('%') > -1)
|
||||
m = Math.round(parseFloat(m) * 2.55);
|
||||
|
||||
return Math.max(0, Math.min(m, 255));
|
||||
});
|
||||
|
||||
val = rgb2hex(match);
|
||||
}
|
||||
|
||||
// Convert long hex to short hex
|
||||
if (params.shorthex && (match = val.match(regHEX))) {
|
||||
val = '#' + match[0][1] + match[0][3] + match[0][5];
|
||||
}
|
||||
|
||||
// Convert hex to short name
|
||||
if (params.shortname) {
|
||||
var lowerVal = val.toLowerCase();
|
||||
if (lowerVal in collections.colorsShortNames) {
|
||||
val = collections.colorsShortNames[lowerVal];
|
||||
}
|
||||
}
|
||||
|
||||
attr.value = val;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert [r, g, b] to #rrggbb.
|
||||
*
|
||||
* @see https://gist.github.com/983535
|
||||
*
|
||||
* @example
|
||||
* rgb2hex([255, 255, 255]) // '#ffffff'
|
||||
*
|
||||
* @param {Array} rgb [r, g, b]
|
||||
* @return {String} #rrggbb
|
||||
*
|
||||
* @author Jed Schmidt
|
||||
*/
|
||||
function rgb2hex(rgb) {
|
||||
return '#' + ('00000' + (rgb[0] << 16 | rgb[1] << 8 | rgb[2]).toString(16)).slice(-6).toUpperCase();
|
||||
}
|
39
assets_old/node_modules/svgo/plugins/convertEllipseToCircle.js
generated
vendored
Normal file
39
assets_old/node_modules/svgo/plugins/convertEllipseToCircle.js
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'converts non-eccentric <ellipse>s to <circle>s';
|
||||
|
||||
/**
|
||||
* Converts non-eccentric <ellipse>s to <circle>s.
|
||||
*
|
||||
* @see http://www.w3.org/TR/SVG/shapes.html
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Taylor Hunt
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
if (item.isElem('ellipse')) {
|
||||
var rx = item.attr('rx').value || 0;
|
||||
var ry = item.attr('ry').value || 0;
|
||||
|
||||
if (rx === ry ||
|
||||
rx === 'auto' || ry === 'auto' // SVG2
|
||||
) {
|
||||
var radius = rx !== 'auto' ? rx : ry;
|
||||
item.renameElem('circle');
|
||||
item.removeAttr(['rx', 'ry']);
|
||||
item.addAttr({
|
||||
name: 'r',
|
||||
value: radius,
|
||||
prefix: '',
|
||||
local: 'r',
|
||||
});
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
971
assets_old/node_modules/svgo/plugins/convertPathData.js
generated
vendored
Normal file
971
assets_old/node_modules/svgo/plugins/convertPathData.js
generated
vendored
Normal file
|
@ -0,0 +1,971 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'optimizes path data: writes in shorter form, applies transformations';
|
||||
|
||||
exports.params = {
|
||||
applyTransforms: true,
|
||||
applyTransformsStroked: true,
|
||||
makeArcs: {
|
||||
threshold: 2.5, // coefficient of rounding error
|
||||
tolerance: 0.5 // percentage of radius
|
||||
},
|
||||
straightCurves: true,
|
||||
lineShorthands: true,
|
||||
curveSmoothShorthands: true,
|
||||
floatPrecision: 3,
|
||||
transformPrecision: 5,
|
||||
removeUseless: true,
|
||||
collapseRepeated: true,
|
||||
utilizeAbsolute: true,
|
||||
leadingZero: true,
|
||||
negativeExtraSpace: true,
|
||||
noSpaceAfterFlags: true,
|
||||
forceAbsolutePath: false
|
||||
};
|
||||
|
||||
var pathElems = require('./_collections.js').pathElems,
|
||||
path2js = require('./_path.js').path2js,
|
||||
js2path = require('./_path.js').js2path,
|
||||
applyTransforms = require('./_path.js').applyTransforms,
|
||||
cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
|
||||
roundData,
|
||||
precision,
|
||||
error,
|
||||
arcThreshold,
|
||||
arcTolerance,
|
||||
hasMarkerMid,
|
||||
hasStrokeLinecap;
|
||||
|
||||
/**
|
||||
* Convert absolute Path to relative,
|
||||
* collapse repeated instructions,
|
||||
* detect and convert Lineto shorthands,
|
||||
* remove useless instructions like "l0,0",
|
||||
* trim useless delimiters and leading zeros,
|
||||
* decrease accuracy of floating-point numbers.
|
||||
*
|
||||
* @see http://www.w3.org/TR/SVG/paths.html#PathData
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
if (item.isElem(pathElems) && item.hasAttr('d')) {
|
||||
|
||||
precision = params.floatPrecision;
|
||||
error = precision !== false ? +Math.pow(.1, precision).toFixed(precision) : 1e-2;
|
||||
roundData = precision > 0 && precision < 20 ? strongRound : round;
|
||||
if (params.makeArcs) {
|
||||
arcThreshold = params.makeArcs.threshold;
|
||||
arcTolerance = params.makeArcs.tolerance;
|
||||
}
|
||||
hasMarkerMid = item.hasAttr('marker-mid');
|
||||
|
||||
var stroke = item.computedAttr('stroke'),
|
||||
strokeLinecap = item.computedAttr('stroke');
|
||||
hasStrokeLinecap = stroke && stroke != 'none' && strokeLinecap && strokeLinecap != 'butt';
|
||||
|
||||
var data = path2js(item);
|
||||
|
||||
// TODO: get rid of functions returns
|
||||
if (data.length) {
|
||||
convertToRelative(data);
|
||||
|
||||
if (params.applyTransforms) {
|
||||
data = applyTransforms(item, data, params);
|
||||
}
|
||||
|
||||
data = filters(data, params);
|
||||
|
||||
if (params.utilizeAbsolute) {
|
||||
data = convertToMixed(data, params);
|
||||
}
|
||||
|
||||
js2path(item, data, params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert absolute path data coordinates to relative.
|
||||
*
|
||||
* @param {Array} path input path data
|
||||
* @param {Object} params plugin params
|
||||
* @return {Array} output path data
|
||||
*/
|
||||
function convertToRelative(path) {
|
||||
|
||||
var point = [0, 0],
|
||||
subpathPoint = [0, 0],
|
||||
baseItem;
|
||||
|
||||
path.forEach(function(item, index) {
|
||||
|
||||
var instruction = item.instruction,
|
||||
data = item.data;
|
||||
|
||||
// data !== !z
|
||||
if (data) {
|
||||
|
||||
// already relative
|
||||
// recalculate current point
|
||||
if ('mcslqta'.indexOf(instruction) > -1) {
|
||||
|
||||
point[0] += data[data.length - 2];
|
||||
point[1] += data[data.length - 1];
|
||||
|
||||
if (instruction === 'm') {
|
||||
subpathPoint[0] = point[0];
|
||||
subpathPoint[1] = point[1];
|
||||
baseItem = item;
|
||||
}
|
||||
|
||||
} else if (instruction === 'h') {
|
||||
|
||||
point[0] += data[0];
|
||||
|
||||
} else if (instruction === 'v') {
|
||||
|
||||
point[1] += data[0];
|
||||
|
||||
}
|
||||
|
||||
// convert absolute path data coordinates to relative
|
||||
// if "M" was not transformed from "m"
|
||||
// M → m
|
||||
if (instruction === 'M') {
|
||||
|
||||
if (index > 0) instruction = 'm';
|
||||
|
||||
data[0] -= point[0];
|
||||
data[1] -= point[1];
|
||||
|
||||
subpathPoint[0] = point[0] += data[0];
|
||||
subpathPoint[1] = point[1] += data[1];
|
||||
|
||||
baseItem = item;
|
||||
|
||||
}
|
||||
|
||||
// L → l
|
||||
// T → t
|
||||
else if ('LT'.indexOf(instruction) > -1) {
|
||||
|
||||
instruction = instruction.toLowerCase();
|
||||
|
||||
// x y
|
||||
// 0 1
|
||||
data[0] -= point[0];
|
||||
data[1] -= point[1];
|
||||
|
||||
point[0] += data[0];
|
||||
point[1] += data[1];
|
||||
|
||||
// C → c
|
||||
} else if (instruction === 'C') {
|
||||
|
||||
instruction = 'c';
|
||||
|
||||
// x1 y1 x2 y2 x y
|
||||
// 0 1 2 3 4 5
|
||||
data[0] -= point[0];
|
||||
data[1] -= point[1];
|
||||
data[2] -= point[0];
|
||||
data[3] -= point[1];
|
||||
data[4] -= point[0];
|
||||
data[5] -= point[1];
|
||||
|
||||
point[0] += data[4];
|
||||
point[1] += data[5];
|
||||
|
||||
// S → s
|
||||
// Q → q
|
||||
} else if ('SQ'.indexOf(instruction) > -1) {
|
||||
|
||||
instruction = instruction.toLowerCase();
|
||||
|
||||
// x1 y1 x y
|
||||
// 0 1 2 3
|
||||
data[0] -= point[0];
|
||||
data[1] -= point[1];
|
||||
data[2] -= point[0];
|
||||
data[3] -= point[1];
|
||||
|
||||
point[0] += data[2];
|
||||
point[1] += data[3];
|
||||
|
||||
// A → a
|
||||
} else if (instruction === 'A') {
|
||||
|
||||
instruction = 'a';
|
||||
|
||||
// rx ry x-axis-rotation large-arc-flag sweep-flag x y
|
||||
// 0 1 2 3 4 5 6
|
||||
data[5] -= point[0];
|
||||
data[6] -= point[1];
|
||||
|
||||
point[0] += data[5];
|
||||
point[1] += data[6];
|
||||
|
||||
// H → h
|
||||
} else if (instruction === 'H') {
|
||||
|
||||
instruction = 'h';
|
||||
|
||||
data[0] -= point[0];
|
||||
|
||||
point[0] += data[0];
|
||||
|
||||
// V → v
|
||||
} else if (instruction === 'V') {
|
||||
|
||||
instruction = 'v';
|
||||
|
||||
data[0] -= point[1];
|
||||
|
||||
point[1] += data[0];
|
||||
|
||||
}
|
||||
|
||||
item.instruction = instruction;
|
||||
item.data = data;
|
||||
|
||||
// store absolute coordinates for later use
|
||||
item.coords = point.slice(-2);
|
||||
|
||||
}
|
||||
|
||||
// !data === z, reset current point
|
||||
else if (instruction == 'z') {
|
||||
if (baseItem) {
|
||||
item.coords = baseItem.coords;
|
||||
}
|
||||
point[0] = subpathPoint[0];
|
||||
point[1] = subpathPoint[1];
|
||||
}
|
||||
|
||||
item.base = index > 0 ? path[index - 1].coords : [0, 0];
|
||||
|
||||
});
|
||||
|
||||
return path;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Main filters loop.
|
||||
*
|
||||
* @param {Array} path input path data
|
||||
* @param {Object} params plugin params
|
||||
* @return {Array} output path data
|
||||
*/
|
||||
function filters(path, params) {
|
||||
|
||||
var stringify = data2Path.bind(null, params),
|
||||
relSubpoint = [0, 0],
|
||||
pathBase = [0, 0],
|
||||
prev = {};
|
||||
|
||||
path = path.filter(function(item, index, path) {
|
||||
|
||||
var instruction = item.instruction,
|
||||
data = item.data,
|
||||
next = path[index + 1];
|
||||
|
||||
if (data) {
|
||||
|
||||
var sdata = data,
|
||||
circle;
|
||||
|
||||
if (instruction === 's') {
|
||||
sdata = [0, 0].concat(data);
|
||||
|
||||
if ('cs'.indexOf(prev.instruction) > -1) {
|
||||
var pdata = prev.data,
|
||||
n = pdata.length;
|
||||
|
||||
// (-x, -y) of the prev tangent point relative to the current point
|
||||
sdata[0] = pdata[n - 2] - pdata[n - 4];
|
||||
sdata[1] = pdata[n - 1] - pdata[n - 3];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// convert curves to arcs if possible
|
||||
if (
|
||||
params.makeArcs &&
|
||||
(instruction == 'c' || instruction == 's') &&
|
||||
isConvex(sdata) &&
|
||||
(circle = findCircle(sdata))
|
||||
) {
|
||||
var r = roundData([circle.radius])[0],
|
||||
angle = findArcAngle(sdata, circle),
|
||||
sweep = sdata[5] * sdata[0] - sdata[4] * sdata[1] > 0 ? 1 : 0,
|
||||
arc = {
|
||||
instruction: 'a',
|
||||
data: [r, r, 0, 0, sweep, sdata[4], sdata[5]],
|
||||
coords: item.coords.slice(),
|
||||
base: item.base
|
||||
},
|
||||
output = [arc],
|
||||
// relative coordinates to adjust the found circle
|
||||
relCenter = [circle.center[0] - sdata[4], circle.center[1] - sdata[5]],
|
||||
relCircle = { center: relCenter, radius: circle.radius },
|
||||
arcCurves = [item],
|
||||
hasPrev = 0,
|
||||
suffix = '',
|
||||
nextLonghand;
|
||||
|
||||
if (
|
||||
prev.instruction == 'c' && isConvex(prev.data) && isArcPrev(prev.data, circle) ||
|
||||
prev.instruction == 'a' && prev.sdata && isArcPrev(prev.sdata, circle)
|
||||
) {
|
||||
arcCurves.unshift(prev);
|
||||
arc.base = prev.base;
|
||||
arc.data[5] = arc.coords[0] - arc.base[0];
|
||||
arc.data[6] = arc.coords[1] - arc.base[1];
|
||||
var prevData = prev.instruction == 'a' ? prev.sdata : prev.data;
|
||||
var prevAngle = findArcAngle(prevData,
|
||||
{
|
||||
center: [prevData[4] + circle.center[0], prevData[5] + circle.center[1]],
|
||||
radius: circle.radius
|
||||
}
|
||||
);
|
||||
angle += prevAngle;
|
||||
if (angle > Math.PI) arc.data[3] = 1;
|
||||
hasPrev = 1;
|
||||
}
|
||||
|
||||
// check if next curves are fitting the arc
|
||||
for (var j = index; (next = path[++j]) && ~'cs'.indexOf(next.instruction);) {
|
||||
var nextData = next.data;
|
||||
if (next.instruction == 's') {
|
||||
nextLonghand = makeLonghand({instruction: 's', data: next.data.slice() },
|
||||
path[j - 1].data);
|
||||
nextData = nextLonghand.data;
|
||||
nextLonghand.data = nextData.slice(0, 2);
|
||||
suffix = stringify([nextLonghand]);
|
||||
}
|
||||
if (isConvex(nextData) && isArc(nextData, relCircle)) {
|
||||
angle += findArcAngle(nextData, relCircle);
|
||||
if (angle - 2 * Math.PI > 1e-3) break; // more than 360°
|
||||
if (angle > Math.PI) arc.data[3] = 1;
|
||||
arcCurves.push(next);
|
||||
if (2 * Math.PI - angle > 1e-3) { // less than 360°
|
||||
arc.coords = next.coords;
|
||||
arc.data[5] = arc.coords[0] - arc.base[0];
|
||||
arc.data[6] = arc.coords[1] - arc.base[1];
|
||||
} else {
|
||||
// full circle, make a half-circle arc and add a second one
|
||||
arc.data[5] = 2 * (relCircle.center[0] - nextData[4]);
|
||||
arc.data[6] = 2 * (relCircle.center[1] - nextData[5]);
|
||||
arc.coords = [arc.base[0] + arc.data[5], arc.base[1] + arc.data[6]];
|
||||
arc = {
|
||||
instruction: 'a',
|
||||
data: [r, r, 0, 0, sweep,
|
||||
next.coords[0] - arc.coords[0], next.coords[1] - arc.coords[1]],
|
||||
coords: next.coords,
|
||||
base: arc.coords
|
||||
};
|
||||
output.push(arc);
|
||||
j++;
|
||||
break;
|
||||
}
|
||||
relCenter[0] -= nextData[4];
|
||||
relCenter[1] -= nextData[5];
|
||||
} else break;
|
||||
}
|
||||
|
||||
if ((stringify(output) + suffix).length < stringify(arcCurves).length) {
|
||||
if (path[j] && path[j].instruction == 's') {
|
||||
makeLonghand(path[j], path[j - 1].data);
|
||||
}
|
||||
if (hasPrev) {
|
||||
var prevArc = output.shift();
|
||||
roundData(prevArc.data);
|
||||
relSubpoint[0] += prevArc.data[5] - prev.data[prev.data.length - 2];
|
||||
relSubpoint[1] += prevArc.data[6] - prev.data[prev.data.length - 1];
|
||||
prev.instruction = 'a';
|
||||
prev.data = prevArc.data;
|
||||
item.base = prev.coords = prevArc.coords;
|
||||
}
|
||||
arc = output.shift();
|
||||
if (arcCurves.length == 1) {
|
||||
item.sdata = sdata.slice(); // preserve curve data for future checks
|
||||
} else if (arcCurves.length - 1 - hasPrev > 0) {
|
||||
// filter out consumed next items
|
||||
path.splice.apply(path, [index + 1, arcCurves.length - 1 - hasPrev].concat(output));
|
||||
}
|
||||
if (!arc) return false;
|
||||
instruction = 'a';
|
||||
data = arc.data;
|
||||
item.coords = arc.coords;
|
||||
}
|
||||
}
|
||||
|
||||
// Rounding relative coordinates, taking in account accummulating error
|
||||
// to get closer to absolute coordinates. Sum of rounded value remains same:
|
||||
// l .25 3 .25 2 .25 3 .25 2 -> l .3 3 .2 2 .3 3 .2 2
|
||||
if (precision !== false) {
|
||||
if ('mltqsc'.indexOf(instruction) > -1) {
|
||||
for (var i = data.length; i--;) {
|
||||
data[i] += item.base[i % 2] - relSubpoint[i % 2];
|
||||
}
|
||||
} else if (instruction == 'h') {
|
||||
data[0] += item.base[0] - relSubpoint[0];
|
||||
} else if (instruction == 'v') {
|
||||
data[0] += item.base[1] - relSubpoint[1];
|
||||
} else if (instruction == 'a') {
|
||||
data[5] += item.base[0] - relSubpoint[0];
|
||||
data[6] += item.base[1] - relSubpoint[1];
|
||||
}
|
||||
roundData(data);
|
||||
|
||||
if (instruction == 'h') relSubpoint[0] += data[0];
|
||||
else if (instruction == 'v') relSubpoint[1] += data[0];
|
||||
else {
|
||||
relSubpoint[0] += data[data.length - 2];
|
||||
relSubpoint[1] += data[data.length - 1];
|
||||
}
|
||||
roundData(relSubpoint);
|
||||
|
||||
if (instruction.toLowerCase() == 'm') {
|
||||
pathBase[0] = relSubpoint[0];
|
||||
pathBase[1] = relSubpoint[1];
|
||||
}
|
||||
}
|
||||
|
||||
// convert straight curves into lines segments
|
||||
if (params.straightCurves) {
|
||||
|
||||
if (
|
||||
instruction === 'c' &&
|
||||
isCurveStraightLine(data) ||
|
||||
instruction === 's' &&
|
||||
isCurveStraightLine(sdata)
|
||||
) {
|
||||
if (next && next.instruction == 's')
|
||||
makeLonghand(next, data); // fix up next curve
|
||||
instruction = 'l';
|
||||
data = data.slice(-2);
|
||||
}
|
||||
|
||||
else if (
|
||||
instruction === 'q' &&
|
||||
isCurveStraightLine(data)
|
||||
) {
|
||||
if (next && next.instruction == 't')
|
||||
makeLonghand(next, data); // fix up next curve
|
||||
instruction = 'l';
|
||||
data = data.slice(-2);
|
||||
}
|
||||
|
||||
else if (
|
||||
instruction === 't' &&
|
||||
prev.instruction !== 'q' &&
|
||||
prev.instruction !== 't'
|
||||
) {
|
||||
instruction = 'l';
|
||||
data = data.slice(-2);
|
||||
}
|
||||
|
||||
else if (
|
||||
instruction === 'a' &&
|
||||
(data[0] === 0 || data[1] === 0)
|
||||
) {
|
||||
instruction = 'l';
|
||||
data = data.slice(-2);
|
||||
}
|
||||
}
|
||||
|
||||
// horizontal and vertical line shorthands
|
||||
// l 50 0 → h 50
|
||||
// l 0 50 → v 50
|
||||
if (
|
||||
params.lineShorthands &&
|
||||
instruction === 'l'
|
||||
) {
|
||||
if (data[1] === 0) {
|
||||
instruction = 'h';
|
||||
data.pop();
|
||||
} else if (data[0] === 0) {
|
||||
instruction = 'v';
|
||||
data.shift();
|
||||
}
|
||||
}
|
||||
|
||||
// collapse repeated commands
|
||||
// h 20 h 30 -> h 50
|
||||
if (
|
||||
params.collapseRepeated &&
|
||||
!hasMarkerMid &&
|
||||
('mhv'.indexOf(instruction) > -1) &&
|
||||
prev.instruction &&
|
||||
instruction == prev.instruction.toLowerCase() &&
|
||||
(
|
||||
(instruction != 'h' && instruction != 'v') ||
|
||||
(prev.data[0] >= 0) == (item.data[0] >= 0)
|
||||
)) {
|
||||
prev.data[0] += data[0];
|
||||
if (instruction != 'h' && instruction != 'v') {
|
||||
prev.data[1] += data[1];
|
||||
}
|
||||
prev.coords = item.coords;
|
||||
path[index] = prev;
|
||||
return false;
|
||||
}
|
||||
|
||||
// convert curves into smooth shorthands
|
||||
if (params.curveSmoothShorthands && prev.instruction) {
|
||||
|
||||
// curveto
|
||||
if (instruction === 'c') {
|
||||
|
||||
// c + c → c + s
|
||||
if (
|
||||
prev.instruction === 'c' &&
|
||||
data[0] === -(prev.data[2] - prev.data[4]) &&
|
||||
data[1] === -(prev.data[3] - prev.data[5])
|
||||
) {
|
||||
instruction = 's';
|
||||
data = data.slice(2);
|
||||
}
|
||||
|
||||
// s + c → s + s
|
||||
else if (
|
||||
prev.instruction === 's' &&
|
||||
data[0] === -(prev.data[0] - prev.data[2]) &&
|
||||
data[1] === -(prev.data[1] - prev.data[3])
|
||||
) {
|
||||
instruction = 's';
|
||||
data = data.slice(2);
|
||||
}
|
||||
|
||||
// [^cs] + c → [^cs] + s
|
||||
else if (
|
||||
'cs'.indexOf(prev.instruction) === -1 &&
|
||||
data[0] === 0 &&
|
||||
data[1] === 0
|
||||
) {
|
||||
instruction = 's';
|
||||
data = data.slice(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// quadratic Bézier curveto
|
||||
else if (instruction === 'q') {
|
||||
|
||||
// q + q → q + t
|
||||
if (
|
||||
prev.instruction === 'q' &&
|
||||
data[0] === (prev.data[2] - prev.data[0]) &&
|
||||
data[1] === (prev.data[3] - prev.data[1])
|
||||
) {
|
||||
instruction = 't';
|
||||
data = data.slice(2);
|
||||
}
|
||||
|
||||
// t + q → t + t
|
||||
else if (
|
||||
prev.instruction === 't' &&
|
||||
data[2] === prev.data[0] &&
|
||||
data[3] === prev.data[1]
|
||||
) {
|
||||
instruction = 't';
|
||||
data = data.slice(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// remove useless non-first path segments
|
||||
if (params.removeUseless && !hasStrokeLinecap) {
|
||||
|
||||
// l 0,0 / h 0 / v 0 / q 0,0 0,0 / t 0,0 / c 0,0 0,0 0,0 / s 0,0 0,0
|
||||
if (
|
||||
(
|
||||
'lhvqtcs'.indexOf(instruction) > -1
|
||||
) &&
|
||||
data.every(function(i) { return i === 0; })
|
||||
) {
|
||||
path[index] = prev;
|
||||
return false;
|
||||
}
|
||||
|
||||
// a 25,25 -30 0,1 0,0
|
||||
if (
|
||||
instruction === 'a' &&
|
||||
data[5] === 0 &&
|
||||
data[6] === 0
|
||||
) {
|
||||
path[index] = prev;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
item.instruction = instruction;
|
||||
item.data = data;
|
||||
|
||||
prev = item;
|
||||
|
||||
} else {
|
||||
|
||||
// z resets coordinates
|
||||
relSubpoint[0] = pathBase[0];
|
||||
relSubpoint[1] = pathBase[1];
|
||||
if (prev.instruction == 'z') return false;
|
||||
prev = item;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
return path;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes data in shortest form using absolute or relative coordinates.
|
||||
*
|
||||
* @param {Array} data input path data
|
||||
* @return {Boolean} output
|
||||
*/
|
||||
function convertToMixed(path, params) {
|
||||
|
||||
var prev = path[0];
|
||||
|
||||
path = path.filter(function(item, index) {
|
||||
|
||||
if (index == 0) return true;
|
||||
if (!item.data) {
|
||||
prev = item;
|
||||
return true;
|
||||
}
|
||||
|
||||
var instruction = item.instruction,
|
||||
data = item.data,
|
||||
adata = data && data.slice(0);
|
||||
|
||||
if ('mltqsc'.indexOf(instruction) > -1) {
|
||||
for (var i = adata.length; i--;) {
|
||||
adata[i] += item.base[i % 2];
|
||||
}
|
||||
} else if (instruction == 'h') {
|
||||
adata[0] += item.base[0];
|
||||
} else if (instruction == 'v') {
|
||||
adata[0] += item.base[1];
|
||||
} else if (instruction == 'a') {
|
||||
adata[5] += item.base[0];
|
||||
adata[6] += item.base[1];
|
||||
}
|
||||
|
||||
roundData(adata);
|
||||
|
||||
var absoluteDataStr = cleanupOutData(adata, params),
|
||||
relativeDataStr = cleanupOutData(data, params);
|
||||
|
||||
// Convert to absolute coordinates if it's shorter or forceAbsolutePath is true.
|
||||
// v-20 -> V0
|
||||
// Don't convert if it fits following previous instruction.
|
||||
// l20 30-10-50 instead of l20 30L20 30
|
||||
if (
|
||||
params.forceAbsolutePath || (
|
||||
absoluteDataStr.length < relativeDataStr.length &&
|
||||
!(
|
||||
params.negativeExtraSpace &&
|
||||
instruction == prev.instruction &&
|
||||
prev.instruction.charCodeAt(0) > 96 &&
|
||||
absoluteDataStr.length == relativeDataStr.length - 1 &&
|
||||
(data[0] < 0 || /^0\./.test(data[0]) && prev.data[prev.data.length - 1] % 1)
|
||||
))
|
||||
) {
|
||||
item.instruction = instruction.toUpperCase();
|
||||
item.data = adata;
|
||||
}
|
||||
|
||||
prev = item;
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
return path;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if curve is convex. Control points of such a curve must form
|
||||
* a convex quadrilateral with diagonals crosspoint inside of it.
|
||||
*
|
||||
* @param {Array} data input path data
|
||||
* @return {Boolean} output
|
||||
*/
|
||||
function isConvex(data) {
|
||||
|
||||
var center = getIntersection([0, 0, data[2], data[3], data[0], data[1], data[4], data[5]]);
|
||||
|
||||
return center &&
|
||||
(data[2] < center[0] == center[0] < 0) &&
|
||||
(data[3] < center[1] == center[1] < 0) &&
|
||||
(data[4] < center[0] == center[0] < data[0]) &&
|
||||
(data[5] < center[1] == center[1] < data[1]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes lines equations by two points and returns their intersection point.
|
||||
*
|
||||
* @param {Array} coords 8 numbers for 4 pairs of coordinates (x,y)
|
||||
* @return {Array|undefined} output coordinate of lines' crosspoint
|
||||
*/
|
||||
function getIntersection(coords) {
|
||||
|
||||
// Prev line equation parameters.
|
||||
var a1 = coords[1] - coords[3], // y1 - y2
|
||||
b1 = coords[2] - coords[0], // x2 - x1
|
||||
c1 = coords[0] * coords[3] - coords[2] * coords[1], // x1 * y2 - x2 * y1
|
||||
|
||||
// Next line equation parameters
|
||||
a2 = coords[5] - coords[7], // y1 - y2
|
||||
b2 = coords[6] - coords[4], // x2 - x1
|
||||
c2 = coords[4] * coords[7] - coords[5] * coords[6], // x1 * y2 - x2 * y1
|
||||
denom = (a1 * b2 - a2 * b1);
|
||||
|
||||
if (!denom) return; // parallel lines havn't an intersection
|
||||
|
||||
var cross = [
|
||||
(b1 * c2 - b2 * c1) / denom,
|
||||
(a1 * c2 - a2 * c1) / -denom
|
||||
];
|
||||
if (
|
||||
!isNaN(cross[0]) && !isNaN(cross[1]) &&
|
||||
isFinite(cross[0]) && isFinite(cross[1])
|
||||
) {
|
||||
return cross;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrease accuracy of floating-point numbers
|
||||
* in path data keeping a specified number of decimals.
|
||||
* Smart rounds values like 2.3491 to 2.35 instead of 2.349.
|
||||
* Doesn't apply "smartness" if the number precision fits already.
|
||||
*
|
||||
* @param {Array} data input data array
|
||||
* @return {Array} output data array
|
||||
*/
|
||||
function strongRound(data) {
|
||||
for (var i = data.length; i-- > 0;) {
|
||||
if (data[i].toFixed(precision) != data[i]) {
|
||||
var rounded = +data[i].toFixed(precision - 1);
|
||||
data[i] = +Math.abs(rounded - data[i]).toFixed(precision + 1) >= error ?
|
||||
+data[i].toFixed(precision) :
|
||||
rounded;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple rounding function if precision is 0.
|
||||
*
|
||||
* @param {Array} data input data array
|
||||
* @return {Array} output data array
|
||||
*/
|
||||
function round(data) {
|
||||
for (var i = data.length; i-- > 0;) {
|
||||
data[i] = Math.round(data[i]);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a curve is a straight line by measuring distance
|
||||
* from middle points to the line formed by end points.
|
||||
*
|
||||
* @param {Array} xs array of curve points x-coordinates
|
||||
* @param {Array} ys array of curve points y-coordinates
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
function isCurveStraightLine(data) {
|
||||
|
||||
// Get line equation a·x + b·y + c = 0 coefficients a, b (c = 0) by start and end points.
|
||||
var i = data.length - 2,
|
||||
a = -data[i + 1], // y1 − y2 (y1 = 0)
|
||||
b = data[i], // x2 − x1 (x1 = 0)
|
||||
d = 1 / (a * a + b * b); // same part for all points
|
||||
|
||||
if (i <= 1 || !isFinite(d)) return false; // curve that ends at start point isn't the case
|
||||
|
||||
// Distance from point (x0, y0) to the line is sqrt((c − a·x0 − b·y0)² / (a² + b²))
|
||||
while ((i -= 2) >= 0) {
|
||||
if (Math.sqrt(Math.pow(a * data[i] + b * data[i + 1], 2) * d) > error)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts next curve from shorthand to full form using the current curve data.
|
||||
*
|
||||
* @param {Object} item curve to convert
|
||||
* @param {Array} data current curve data
|
||||
*/
|
||||
|
||||
function makeLonghand(item, data) {
|
||||
switch (item.instruction) {
|
||||
case 's': item.instruction = 'c'; break;
|
||||
case 't': item.instruction = 'q'; break;
|
||||
}
|
||||
item.data.unshift(data[data.length - 2] - data[data.length - 4], data[data.length - 1] - data[data.length - 3]);
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns distance between two points
|
||||
*
|
||||
* @param {Array} point1 first point coordinates
|
||||
* @param {Array} point2 second point coordinates
|
||||
* @return {Number} distance
|
||||
*/
|
||||
|
||||
function getDistance(point1, point2) {
|
||||
return Math.hypot(point1[0] - point2[0], point1[1] - point2[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns coordinates of the curve point corresponding to the certain t
|
||||
* a·(1 - t)³·p1 + b·(1 - t)²·t·p2 + c·(1 - t)·t²·p3 + d·t³·p4,
|
||||
* where pN are control points and p1 is zero due to relative coordinates.
|
||||
*
|
||||
* @param {Array} curve array of curve points coordinates
|
||||
* @param {Number} t parametric position from 0 to 1
|
||||
* @return {Array} Point coordinates
|
||||
*/
|
||||
|
||||
function getCubicBezierPoint(curve, t) {
|
||||
var sqrT = t * t,
|
||||
cubT = sqrT * t,
|
||||
mt = 1 - t,
|
||||
sqrMt = mt * mt;
|
||||
|
||||
return [
|
||||
3 * sqrMt * t * curve[0] + 3 * mt * sqrT * curve[2] + cubT * curve[4],
|
||||
3 * sqrMt * t * curve[1] + 3 * mt * sqrT * curve[3] + cubT * curve[5]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds circle by 3 points of the curve and checks if the curve fits the found circle.
|
||||
*
|
||||
* @param {Array} curve
|
||||
* @return {Object|undefined} circle
|
||||
*/
|
||||
|
||||
function findCircle(curve) {
|
||||
var midPoint = getCubicBezierPoint(curve, 1/2),
|
||||
m1 = [midPoint[0] / 2, midPoint[1] / 2],
|
||||
m2 = [(midPoint[0] + curve[4]) / 2, (midPoint[1] + curve[5]) / 2],
|
||||
center = getIntersection([
|
||||
m1[0], m1[1],
|
||||
m1[0] + m1[1], m1[1] - m1[0],
|
||||
m2[0], m2[1],
|
||||
m2[0] + (m2[1] - midPoint[1]), m2[1] - (m2[0] - midPoint[0])
|
||||
]),
|
||||
radius = center && getDistance([0, 0], center),
|
||||
tolerance = Math.min(arcThreshold * error, arcTolerance * radius / 100);
|
||||
|
||||
if (center && radius < 1e15 &&
|
||||
[1/4, 3/4].every(function(point) {
|
||||
return Math.abs(getDistance(getCubicBezierPoint(curve, point), center) - radius) <= tolerance;
|
||||
}))
|
||||
return { center: center, radius: radius};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a curve fits the given circle.
|
||||
*
|
||||
* @param {Object} circle
|
||||
* @param {Array} curve
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
function isArc(curve, circle) {
|
||||
var tolerance = Math.min(arcThreshold * error, arcTolerance * circle.radius / 100);
|
||||
|
||||
return [0, 1/4, 1/2, 3/4, 1].every(function(point) {
|
||||
return Math.abs(getDistance(getCubicBezierPoint(curve, point), circle.center) - circle.radius) <= tolerance;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a previous curve fits the given circle.
|
||||
*
|
||||
* @param {Object} circle
|
||||
* @param {Array} curve
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
function isArcPrev(curve, circle) {
|
||||
return isArc(curve, {
|
||||
center: [circle.center[0] + curve[4], circle.center[1] + curve[5]],
|
||||
radius: circle.radius
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds angle of a curve fitting the given arc.
|
||||
|
||||
* @param {Array} curve
|
||||
* @param {Object} relCircle
|
||||
* @return {Number} angle
|
||||
*/
|
||||
|
||||
function findArcAngle(curve, relCircle) {
|
||||
var x1 = -relCircle.center[0],
|
||||
y1 = -relCircle.center[1],
|
||||
x2 = curve[4] - relCircle.center[0],
|
||||
y2 = curve[5] - relCircle.center[1];
|
||||
|
||||
return Math.acos(
|
||||
(x1 * x2 + y1 * y2) /
|
||||
Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts given path data to string.
|
||||
*
|
||||
* @param {Object} params
|
||||
* @param {Array} pathData
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
function data2Path(params, pathData) {
|
||||
return pathData.reduce(function(pathString, item) {
|
||||
var strData = '';
|
||||
if (item.data) {
|
||||
strData = cleanupOutData(roundData(item.data.slice()), params);
|
||||
}
|
||||
return pathString + item.instruction + strData;
|
||||
}, '');
|
||||
}
|
149
assets_old/node_modules/svgo/plugins/convertShapeToPath.js
generated
vendored
Normal file
149
assets_old/node_modules/svgo/plugins/convertShapeToPath.js
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'converts basic shapes to more compact path form';
|
||||
|
||||
exports.params = {
|
||||
convertArcs: false
|
||||
};
|
||||
|
||||
var none = { value: 0 },
|
||||
regNumber = /[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
|
||||
|
||||
/**
|
||||
* Converts basic shape to more compact path.
|
||||
* It also allows further optimizations like
|
||||
* combining paths with similar attributes.
|
||||
*
|
||||
* @see http://www.w3.org/TR/SVG/shapes.html
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Lev Solntsev
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
var convertArcs = params && params.convertArcs;
|
||||
|
||||
if (
|
||||
item.isElem('rect') &&
|
||||
item.hasAttr('width') &&
|
||||
item.hasAttr('height') &&
|
||||
!item.hasAttr('rx') &&
|
||||
!item.hasAttr('ry')
|
||||
) {
|
||||
|
||||
var x = +(item.attr('x') || none).value,
|
||||
y = +(item.attr('y') || none).value,
|
||||
width = +item.attr('width').value,
|
||||
height = +item.attr('height').value;
|
||||
|
||||
// Values like '100%' compute to NaN, thus running after
|
||||
// cleanupNumericValues when 'px' units has already been removed.
|
||||
// TODO: Calculate sizes from % and non-px units if possible.
|
||||
if (isNaN(x - y + width - height)) return;
|
||||
|
||||
var pathData =
|
||||
'M' + x + ' ' + y +
|
||||
'H' + (x + width) +
|
||||
'V' + (y + height) +
|
||||
'H' + x +
|
||||
'z';
|
||||
|
||||
item.addAttr({
|
||||
name: 'd',
|
||||
value: pathData,
|
||||
prefix: '',
|
||||
local: 'd'
|
||||
});
|
||||
|
||||
item.renameElem('path')
|
||||
.removeAttr(['x', 'y', 'width', 'height']);
|
||||
|
||||
} else if (item.isElem('line')) {
|
||||
|
||||
var x1 = +(item.attr('x1') || none).value,
|
||||
y1 = +(item.attr('y1') || none).value,
|
||||
x2 = +(item.attr('x2') || none).value,
|
||||
y2 = +(item.attr('y2') || none).value;
|
||||
if (isNaN(x1 - y1 + x2 - y2)) return;
|
||||
|
||||
item.addAttr({
|
||||
name: 'd',
|
||||
value: 'M' + x1 + ' ' + y1 + 'L' + x2 + ' ' + y2,
|
||||
prefix: '',
|
||||
local: 'd'
|
||||
});
|
||||
|
||||
item.renameElem('path')
|
||||
.removeAttr(['x1', 'y1', 'x2', 'y2']);
|
||||
|
||||
} else if ((
|
||||
item.isElem('polyline') ||
|
||||
item.isElem('polygon')
|
||||
) &&
|
||||
item.hasAttr('points')
|
||||
) {
|
||||
|
||||
var coords = (item.attr('points').value.match(regNumber) || []).map(Number);
|
||||
if (coords.length < 4) return false;
|
||||
|
||||
item.addAttr({
|
||||
name: 'd',
|
||||
value: 'M' + coords.slice(0,2).join(' ') +
|
||||
'L' + coords.slice(2).join(' ') +
|
||||
(item.isElem('polygon') ? 'z' : ''),
|
||||
prefix: '',
|
||||
local: 'd'
|
||||
});
|
||||
|
||||
item.renameElem('path')
|
||||
.removeAttr('points');
|
||||
} else if (item.isElem('circle') && convertArcs) {
|
||||
|
||||
var cx = +(item.attr('cx') || none).value;
|
||||
var cy = +(item.attr('cy') || none).value;
|
||||
var r = +(item.attr('r') || none).value;
|
||||
if (isNaN(cx - cy + r)) {
|
||||
return;
|
||||
}
|
||||
var cPathData =
|
||||
'M' + cx + ' ' + (cy - r) +
|
||||
'A' + r + ' ' + r + ' 0 1 0 ' + cx + ' ' + (cy + r) +
|
||||
'A' + r + ' ' + r + ' 0 1 0 ' + cx + ' ' + (cy - r) +
|
||||
'Z';
|
||||
item.addAttr({
|
||||
name: 'd',
|
||||
value: cPathData,
|
||||
prefix: '',
|
||||
local: 'd',
|
||||
});
|
||||
item.renameElem('path').removeAttr(['cx', 'cy', 'r']);
|
||||
|
||||
} else if (item.isElem('ellipse') && convertArcs) {
|
||||
|
||||
var ecx = +(item.attr('cx') || none).value;
|
||||
var ecy = +(item.attr('cy') || none).value;
|
||||
var rx = +(item.attr('rx') || none).value;
|
||||
var ry = +(item.attr('ry') || none).value;
|
||||
if (isNaN(ecx - ecy + rx - ry)) {
|
||||
return;
|
||||
}
|
||||
var ePathData =
|
||||
'M' + ecx + ' ' + (ecy - ry) +
|
||||
'A' + rx + ' ' + ry + ' 0 1 0 ' + ecx + ' ' + (ecy + ry) +
|
||||
'A' + rx + ' ' + ry + ' 0 1 0 ' + ecx + ' ' + (ecy - ry) +
|
||||
'Z';
|
||||
item.addAttr({
|
||||
name: 'd',
|
||||
value: ePathData,
|
||||
prefix: '',
|
||||
local: 'd',
|
||||
});
|
||||
item.renameElem('path').removeAttr(['cx', 'cy', 'rx', 'ry']);
|
||||
}
|
||||
};
|
125
assets_old/node_modules/svgo/plugins/convertStyleToAttrs.js
generated
vendored
Normal file
125
assets_old/node_modules/svgo/plugins/convertStyleToAttrs.js
generated
vendored
Normal file
|
@ -0,0 +1,125 @@
|
|||
/* jshint quotmark: false */
|
||||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'converts style to attributes';
|
||||
|
||||
exports.params = {
|
||||
keepImportant: false
|
||||
};
|
||||
|
||||
var stylingProps = require('./_collections').attrsGroups.presentation,
|
||||
rEscape = '\\\\(?:[0-9a-f]{1,6}\\s?|\\r\\n|.)', // Like \" or \2051. Code points consume one space.
|
||||
rAttr = '\\s*(' + g('[^:;\\\\]', rEscape) + '*?)\\s*', // attribute name like ‘fill’
|
||||
rSingleQuotes = "'(?:[^'\\n\\r\\\\]|" + rEscape + ")*?(?:'|$)", // string in single quotes: 'smth'
|
||||
rQuotes = '"(?:[^"\\n\\r\\\\]|' + rEscape + ')*?(?:"|$)', // string in double quotes: "smth"
|
||||
rQuotedString = new RegExp('^' + g(rSingleQuotes, rQuotes) + '$'),
|
||||
|
||||
// Parentheses, E.g.: url(data:image/png;base64,iVBO...).
|
||||
// ':' and ';' inside of it should be threated as is. (Just like in strings.)
|
||||
rParenthesis = '\\(' + g('[^\'"()\\\\]+', rEscape, rSingleQuotes, rQuotes) + '*?' + '\\)',
|
||||
|
||||
// The value. It can have strings and parentheses (see above). Fallbacks to anything in case of unexpected input.
|
||||
rValue = '\\s*(' + g('[^!\'"();\\\\]+?', rEscape, rSingleQuotes, rQuotes, rParenthesis, '[^;]*?') + '*?' + ')',
|
||||
|
||||
// End of declaration. Spaces outside of capturing groups help to do natural trimming.
|
||||
rDeclEnd = '\\s*(?:;\\s*|$)',
|
||||
|
||||
// Important rule
|
||||
rImportant = '(\\s*!important(?![-(\w]))?',
|
||||
|
||||
// Final RegExp to parse CSS declarations.
|
||||
regDeclarationBlock = new RegExp(rAttr + ':' + rValue + rImportant + rDeclEnd, 'ig'),
|
||||
|
||||
// Comments expression. Honors escape sequences and strings.
|
||||
regStripComments = new RegExp(g(rEscape, rSingleQuotes, rQuotes, '/\\*[^]*?\\*/'), 'ig');
|
||||
|
||||
/**
|
||||
* Convert style in attributes. Cleanups comments and illegal declarations (without colon) as a side effect.
|
||||
*
|
||||
* @example
|
||||
* <g style="fill:#000; color: #fff;">
|
||||
* ⬇
|
||||
* <g fill="#000" color="#fff">
|
||||
*
|
||||
* @example
|
||||
* <g style="fill:#000; color: #fff; -webkit-blah: blah">
|
||||
* ⬇
|
||||
* <g fill="#000" color="#fff" style="-webkit-blah: blah">
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
/* jshint boss: true */
|
||||
|
||||
if (item.elem && item.hasAttr('style')) {
|
||||
// ['opacity: 1', 'color: #000']
|
||||
var styleValue = item.attr('style').value,
|
||||
styles = [],
|
||||
attrs = {};
|
||||
|
||||
// Strip CSS comments preserving escape sequences and strings.
|
||||
styleValue = styleValue.replace(regStripComments, function(match) {
|
||||
return match[0] == '/' ? '' :
|
||||
match[0] == '\\' && /[-g-z]/i.test(match[1]) ? match[1] : match;
|
||||
});
|
||||
|
||||
regDeclarationBlock.lastIndex = 0;
|
||||
for (var rule; rule = regDeclarationBlock.exec(styleValue);) {
|
||||
if (!params.keepImportant || !rule[3]) {
|
||||
styles.push([rule[1], rule[2]]);
|
||||
}
|
||||
}
|
||||
|
||||
if (styles.length) {
|
||||
|
||||
styles = styles.filter(function(style) {
|
||||
if (style[0]) {
|
||||
var prop = style[0].toLowerCase(),
|
||||
val = style[1];
|
||||
|
||||
if (rQuotedString.test(val)) {
|
||||
val = val.slice(1, -1);
|
||||
}
|
||||
|
||||
if (stylingProps.indexOf(prop) > -1) {
|
||||
|
||||
attrs[prop] = {
|
||||
name: prop,
|
||||
value: val,
|
||||
local: prop,
|
||||
prefix: ''
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
Object.assign(item.attrs, attrs);
|
||||
|
||||
if (styles.length) {
|
||||
item.attr('style').value = styles
|
||||
.map(function(declaration) { return declaration.join(':') })
|
||||
.join(';');
|
||||
} else {
|
||||
item.removeAttr('style');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function g() {
|
||||
return '(?:' + Array.prototype.join.call(arguments, '|') + ')';
|
||||
}
|
363
assets_old/node_modules/svgo/plugins/convertTransform.js
generated
vendored
Normal file
363
assets_old/node_modules/svgo/plugins/convertTransform.js
generated
vendored
Normal file
|
@ -0,0 +1,363 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'collapses multiple transformations and optimizes it';
|
||||
|
||||
exports.params = {
|
||||
convertToShorts: true,
|
||||
// degPrecision: 3, // transformPrecision (or matrix precision) - 2 by default
|
||||
floatPrecision: 3,
|
||||
transformPrecision: 5,
|
||||
matrixToTransform: true,
|
||||
shortTranslate: true,
|
||||
shortScale: true,
|
||||
shortRotate: true,
|
||||
removeUseless: true,
|
||||
collapseIntoOne: true,
|
||||
leadingZero: true,
|
||||
negativeExtraSpace: false
|
||||
};
|
||||
|
||||
var cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
|
||||
transform2js = require('./_transforms.js').transform2js,
|
||||
transformsMultiply = require('./_transforms.js').transformsMultiply,
|
||||
matrixToTransform = require('./_transforms.js').matrixToTransform,
|
||||
degRound,
|
||||
floatRound,
|
||||
transformRound;
|
||||
|
||||
/**
|
||||
* Convert matrices to the short aliases,
|
||||
* convert long translate, scale or rotate transform notations to the shorts ones,
|
||||
* convert transforms to the matrices and multiply them all into one,
|
||||
* remove useless transforms.
|
||||
*
|
||||
* @see http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
if (item.elem) {
|
||||
|
||||
// transform
|
||||
if (item.hasAttr('transform')) {
|
||||
convertTransform(item, 'transform', params);
|
||||
}
|
||||
|
||||
// gradientTransform
|
||||
if (item.hasAttr('gradientTransform')) {
|
||||
convertTransform(item, 'gradientTransform', params);
|
||||
}
|
||||
|
||||
// patternTransform
|
||||
if (item.hasAttr('patternTransform')) {
|
||||
convertTransform(item, 'patternTransform', params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Main function.
|
||||
*
|
||||
* @param {Object} item input item
|
||||
* @param {String} attrName attribute name
|
||||
* @param {Object} params plugin params
|
||||
*/
|
||||
function convertTransform(item, attrName, params) {
|
||||
var data = transform2js(item.attr(attrName).value);
|
||||
params = definePrecision(data, params);
|
||||
|
||||
if (params.collapseIntoOne && data.length > 1) {
|
||||
data = [transformsMultiply(data)];
|
||||
}
|
||||
|
||||
if (params.convertToShorts) {
|
||||
data = convertToShorts(data, params);
|
||||
} else {
|
||||
data.forEach(roundTransform);
|
||||
}
|
||||
|
||||
if (params.removeUseless) {
|
||||
data = removeUseless(data);
|
||||
}
|
||||
|
||||
if (data.length) {
|
||||
item.attr(attrName).value = js2transform(data, params);
|
||||
} else {
|
||||
item.removeAttr(attrName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines precision to work with certain parts.
|
||||
* transformPrecision - for scale and four first matrix parameters (needs a better precision due to multiplying),
|
||||
* floatPrecision - for translate including two last matrix and rotate parameters,
|
||||
* degPrecision - for rotate and skew. By default it's equal to (rougly)
|
||||
* transformPrecision - 2 or floatPrecision whichever is lower. Can be set in params.
|
||||
*
|
||||
* @param {Array} transforms input array
|
||||
* @param {Object} params plugin params
|
||||
* @return {Array} output array
|
||||
*/
|
||||
function definePrecision(data, params) {
|
||||
/* jshint validthis: true */
|
||||
var matrixData = data.reduce(getMatrixData, []),
|
||||
significantDigits = params.transformPrecision;
|
||||
|
||||
// Clone params so it don't affect other elements transformations.
|
||||
params = Object.assign({}, params);
|
||||
|
||||
// Limit transform precision with matrix one. Calculating with larger precision doesn't add any value.
|
||||
if (matrixData.length) {
|
||||
params.transformPrecision = Math.min(params.transformPrecision,
|
||||
Math.max.apply(Math, matrixData.map(floatDigits)) || params.transformPrecision);
|
||||
|
||||
significantDigits = Math.max.apply(Math, matrixData.map(function(n) {
|
||||
return String(n).replace(/\D+/g, '').length; // Number of digits in a number. 123.45 → 5
|
||||
}));
|
||||
}
|
||||
// No sense in angle precision more then number of significant digits in matrix.
|
||||
if (!('degPrecision' in params)) {
|
||||
params.degPrecision = Math.max(0, Math.min(params.floatPrecision, significantDigits - 2));
|
||||
}
|
||||
|
||||
floatRound = params.floatPrecision >= 1 && params.floatPrecision < 20 ?
|
||||
smartRound.bind(this, params.floatPrecision) :
|
||||
round;
|
||||
degRound = params.degPrecision >= 1 && params.floatPrecision < 20 ?
|
||||
smartRound.bind(this, params.degPrecision) :
|
||||
round;
|
||||
transformRound = params.transformPrecision >= 1 && params.floatPrecision < 20 ?
|
||||
smartRound.bind(this, params.transformPrecision) :
|
||||
round;
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers four first matrix parameters.
|
||||
*
|
||||
* @param {Array} a array of data
|
||||
* @param {Object} transform
|
||||
* @return {Array} output array
|
||||
*/
|
||||
function getMatrixData(a, b) {
|
||||
return b.name == 'matrix' ? a.concat(b.data.slice(0, 4)) : a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of digits after the point. 0.125 → 3
|
||||
*/
|
||||
function floatDigits(n) {
|
||||
return (n = String(n)).slice(n.indexOf('.')).length - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert transforms to the shorthand alternatives.
|
||||
*
|
||||
* @param {Array} transforms input array
|
||||
* @param {Object} params plugin params
|
||||
* @return {Array} output array
|
||||
*/
|
||||
function convertToShorts(transforms, params) {
|
||||
|
||||
for(var i = 0; i < transforms.length; i++) {
|
||||
|
||||
var transform = transforms[i];
|
||||
|
||||
// convert matrix to the short aliases
|
||||
if (
|
||||
params.matrixToTransform &&
|
||||
transform.name === 'matrix'
|
||||
) {
|
||||
var decomposed = matrixToTransform(transform, params);
|
||||
if (decomposed != transform &&
|
||||
js2transform(decomposed, params).length <= js2transform([transform], params).length) {
|
||||
|
||||
transforms.splice.apply(transforms, [i, 1].concat(decomposed));
|
||||
}
|
||||
transform = transforms[i];
|
||||
}
|
||||
|
||||
// fixed-point numbers
|
||||
// 12.754997 → 12.755
|
||||
roundTransform(transform);
|
||||
|
||||
// convert long translate transform notation to the shorts one
|
||||
// translate(10 0) → translate(10)
|
||||
if (
|
||||
params.shortTranslate &&
|
||||
transform.name === 'translate' &&
|
||||
transform.data.length === 2 &&
|
||||
!transform.data[1]
|
||||
) {
|
||||
transform.data.pop();
|
||||
}
|
||||
|
||||
// convert long scale transform notation to the shorts one
|
||||
// scale(2 2) → scale(2)
|
||||
if (
|
||||
params.shortScale &&
|
||||
transform.name === 'scale' &&
|
||||
transform.data.length === 2 &&
|
||||
transform.data[0] === transform.data[1]
|
||||
) {
|
||||
transform.data.pop();
|
||||
}
|
||||
|
||||
// convert long rotate transform notation to the short one
|
||||
// translate(cx cy) rotate(a) translate(-cx -cy) → rotate(a cx cy)
|
||||
if (
|
||||
params.shortRotate &&
|
||||
transforms[i - 2] &&
|
||||
transforms[i - 2].name === 'translate' &&
|
||||
transforms[i - 1].name === 'rotate' &&
|
||||
transforms[i].name === 'translate' &&
|
||||
transforms[i - 2].data[0] === -transforms[i].data[0] &&
|
||||
transforms[i - 2].data[1] === -transforms[i].data[1]
|
||||
) {
|
||||
transforms.splice(i - 2, 3, {
|
||||
name: 'rotate',
|
||||
data: [
|
||||
transforms[i - 1].data[0],
|
||||
transforms[i - 2].data[0],
|
||||
transforms[i - 2].data[1]
|
||||
]
|
||||
});
|
||||
|
||||
// splice compensation
|
||||
i -= 2;
|
||||
|
||||
transform = transforms[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return transforms;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove useless transforms.
|
||||
*
|
||||
* @param {Array} transforms input array
|
||||
* @return {Array} output array
|
||||
*/
|
||||
function removeUseless(transforms) {
|
||||
|
||||
return transforms.filter(function(transform) {
|
||||
|
||||
// translate(0), rotate(0[, cx, cy]), skewX(0), skewY(0)
|
||||
if (
|
||||
['translate', 'rotate', 'skewX', 'skewY'].indexOf(transform.name) > -1 &&
|
||||
(transform.data.length == 1 || transform.name == 'rotate') &&
|
||||
!transform.data[0] ||
|
||||
|
||||
// translate(0, 0)
|
||||
transform.name == 'translate' &&
|
||||
!transform.data[0] &&
|
||||
!transform.data[1] ||
|
||||
|
||||
// scale(1)
|
||||
transform.name == 'scale' &&
|
||||
transform.data[0] == 1 &&
|
||||
(transform.data.length < 2 || transform.data[1] == 1) ||
|
||||
|
||||
// matrix(1 0 0 1 0 0)
|
||||
transform.name == 'matrix' &&
|
||||
transform.data[0] == 1 &&
|
||||
transform.data[3] == 1 &&
|
||||
!(transform.data[1] || transform.data[2] || transform.data[4] || transform.data[5])
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert transforms JS representation to string.
|
||||
*
|
||||
* @param {Array} transformJS JS representation array
|
||||
* @param {Object} params plugin params
|
||||
* @return {String} output string
|
||||
*/
|
||||
function js2transform(transformJS, params) {
|
||||
|
||||
var transformString = '';
|
||||
|
||||
// collect output value string
|
||||
transformJS.forEach(function(transform) {
|
||||
roundTransform(transform);
|
||||
transformString += (transformString && ' ') + transform.name + '(' + cleanupOutData(transform.data, params) + ')';
|
||||
});
|
||||
|
||||
return transformString;
|
||||
|
||||
}
|
||||
|
||||
function roundTransform(transform) {
|
||||
switch (transform.name) {
|
||||
case 'translate':
|
||||
transform.data = floatRound(transform.data);
|
||||
break;
|
||||
case 'rotate':
|
||||
transform.data = degRound(transform.data.slice(0, 1)).concat(floatRound(transform.data.slice(1)));
|
||||
break;
|
||||
case 'skewX':
|
||||
case 'skewY':
|
||||
transform.data = degRound(transform.data);
|
||||
break;
|
||||
case 'scale':
|
||||
transform.data = transformRound(transform.data);
|
||||
break;
|
||||
case 'matrix':
|
||||
transform.data = transformRound(transform.data.slice(0, 4)).concat(floatRound(transform.data.slice(4)));
|
||||
break;
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds numbers in array.
|
||||
*
|
||||
* @param {Array} data input data array
|
||||
* @return {Array} output data array
|
||||
*/
|
||||
function round(data) {
|
||||
return data.map(Math.round);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrease accuracy of floating-point numbers
|
||||
* in transforms keeping a specified number of decimals.
|
||||
* Smart rounds values like 2.349 to 2.35.
|
||||
*
|
||||
* @param {Number} fixed number of decimals
|
||||
* @param {Array} data input data array
|
||||
* @return {Array} output data array
|
||||
*/
|
||||
function smartRound(precision, data) {
|
||||
for (var i = data.length, tolerance = +Math.pow(.1, precision).toFixed(precision); i--;) {
|
||||
if (data[i].toFixed(precision) != data[i]) {
|
||||
var rounded = +data[i].toFixed(precision - 1);
|
||||
data[i] = +Math.abs(rounded - data[i]).toFixed(precision + 1) >= tolerance ?
|
||||
+data[i].toFixed(precision) :
|
||||
rounded;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
245
assets_old/node_modules/svgo/plugins/inlineStyles.js
generated
vendored
Normal file
245
assets_old/node_modules/svgo/plugins/inlineStyles.js
generated
vendored
Normal file
|
@ -0,0 +1,245 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.params = {
|
||||
onlyMatchedOnce: true,
|
||||
removeMatchedSelectors: true,
|
||||
useMqs: ['', 'screen'],
|
||||
usePseudos: ['']
|
||||
};
|
||||
|
||||
exports.description = 'inline styles (additional options)';
|
||||
|
||||
|
||||
var csstree = require('css-tree'),
|
||||
cssTools = require('../lib/css-tools');
|
||||
|
||||
/**
|
||||
* Moves + merges styles from style elements to element styles
|
||||
*
|
||||
* Options
|
||||
* onlyMatchedOnce (default: true)
|
||||
* inline only selectors that match once
|
||||
*
|
||||
* removeMatchedSelectors (default: true)
|
||||
* clean up matched selectors,
|
||||
* leave selectors that hadn't matched
|
||||
*
|
||||
* useMqs (default: ['', 'screen'])
|
||||
* what media queries to be used
|
||||
* empty string element for styles outside media queries
|
||||
*
|
||||
* usePseudos (default: [''])
|
||||
* what pseudo-classes/-elements to be used
|
||||
* empty string element for all non-pseudo-classes and/or -elements
|
||||
*
|
||||
* @param {Object} document document element
|
||||
* @param {Object} opts plugin params
|
||||
*
|
||||
* @author strarsis <strarsis@gmail.com>
|
||||
*/
|
||||
exports.fn = function(document, opts) {
|
||||
|
||||
// collect <style/>s
|
||||
var styleEls = document.querySelectorAll('style');
|
||||
|
||||
//no <styles/>s, nothing to do
|
||||
if (styleEls === null) {
|
||||
return document;
|
||||
}
|
||||
|
||||
var styles = [],
|
||||
selectors = [];
|
||||
|
||||
for (var styleEl of styleEls) {
|
||||
if (styleEl.isEmpty() || styleEl.closestElem('foreignObject')) {
|
||||
// skip empty <style/>s or <foreignObject> content.
|
||||
continue;
|
||||
}
|
||||
|
||||
var cssStr = cssTools.getCssStr(styleEl);
|
||||
|
||||
// collect <style/>s and their css ast
|
||||
var cssAst = {};
|
||||
try {
|
||||
cssAst = csstree.parse(cssStr, {
|
||||
parseValue: false,
|
||||
parseCustomProperty: false
|
||||
});
|
||||
} catch (parseError) {
|
||||
// console.warn('Warning: Parse error of styles of <style/> element, skipped. Error details: ' + parseError);
|
||||
continue;
|
||||
}
|
||||
|
||||
styles.push({
|
||||
styleEl: styleEl,
|
||||
cssAst: cssAst
|
||||
});
|
||||
|
||||
selectors = selectors.concat(cssTools.flattenToSelectors(cssAst));
|
||||
}
|
||||
|
||||
|
||||
// filter for mediaqueries to be used or without any mediaquery
|
||||
var selectorsMq = cssTools.filterByMqs(selectors, opts.useMqs);
|
||||
|
||||
|
||||
// filter for pseudo elements to be used
|
||||
var selectorsPseudo = cssTools.filterByPseudos(selectorsMq, opts.usePseudos);
|
||||
|
||||
// remove PseudoClass from its SimpleSelector for proper matching
|
||||
cssTools.cleanPseudos(selectorsPseudo);
|
||||
|
||||
|
||||
// stable sort selectors
|
||||
var sortedSelectors = cssTools.sortSelectors(selectorsPseudo).reverse();
|
||||
|
||||
|
||||
var selector,
|
||||
selectedEl;
|
||||
|
||||
// match selectors
|
||||
for (selector of sortedSelectors) {
|
||||
var selectorStr = csstree.generate(selector.item.data),
|
||||
selectedEls = null;
|
||||
|
||||
try {
|
||||
selectedEls = document.querySelectorAll(selectorStr);
|
||||
} catch (selectError) {
|
||||
if (selectError.constructor === SyntaxError) {
|
||||
// console.warn('Warning: Syntax error when trying to select \n\n' + selectorStr + '\n\n, skipped. Error details: ' + selectError);
|
||||
continue;
|
||||
}
|
||||
throw selectError;
|
||||
}
|
||||
|
||||
if (selectedEls === null) {
|
||||
// nothing selected
|
||||
continue;
|
||||
}
|
||||
|
||||
selector.selectedEls = selectedEls;
|
||||
}
|
||||
|
||||
|
||||
// apply <style/> styles to matched elements
|
||||
for (selector of sortedSelectors) {
|
||||
if(!selector.selectedEls) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (opts.onlyMatchedOnce && selector.selectedEls !== null && selector.selectedEls.length > 1) {
|
||||
// skip selectors that match more than once if option onlyMatchedOnce is enabled
|
||||
continue;
|
||||
}
|
||||
|
||||
// apply <style/> to matched elements
|
||||
for (selectedEl of selector.selectedEls) {
|
||||
if (selector.rule === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// merge declarations
|
||||
csstree.walk(selector.rule, {visit: 'Declaration', enter: function(styleCsstreeDeclaration) {
|
||||
|
||||
// existing inline styles have higher priority
|
||||
// no inline styles, external styles, external styles used
|
||||
// inline styles, external styles same priority as inline styles, inline styles used
|
||||
// inline styles, external styles higher priority than inline styles, external styles used
|
||||
var styleDeclaration = cssTools.csstreeToStyleDeclaration(styleCsstreeDeclaration);
|
||||
if (selectedEl.style.getPropertyValue(styleDeclaration.name) !== null &&
|
||||
selectedEl.style.getPropertyPriority(styleDeclaration.name) >= styleDeclaration.priority) {
|
||||
return;
|
||||
}
|
||||
selectedEl.style.setProperty(styleDeclaration.name, styleDeclaration.value, styleDeclaration.priority);
|
||||
}});
|
||||
}
|
||||
|
||||
if (opts.removeMatchedSelectors && selector.selectedEls !== null && selector.selectedEls.length > 0) {
|
||||
// clean up matching simple selectors if option removeMatchedSelectors is enabled
|
||||
selector.rule.prelude.children.remove(selector.item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!opts.removeMatchedSelectors) {
|
||||
return document; // no further processing required
|
||||
}
|
||||
|
||||
|
||||
// clean up matched class + ID attribute values
|
||||
for (selector of sortedSelectors) {
|
||||
if(!selector.selectedEls) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (opts.onlyMatchedOnce && selector.selectedEls !== null && selector.selectedEls.length > 1) {
|
||||
// skip selectors that match more than once if option onlyMatchedOnce is enabled
|
||||
continue;
|
||||
}
|
||||
|
||||
for (selectedEl of selector.selectedEls) {
|
||||
// class
|
||||
var firstSubSelector = selector.item.data.children.first();
|
||||
if(firstSubSelector.type === 'ClassSelector') {
|
||||
selectedEl.class.remove(firstSubSelector.name);
|
||||
}
|
||||
// clean up now empty class attributes
|
||||
if(typeof selectedEl.class.item(0) === 'undefined') {
|
||||
selectedEl.removeAttr('class');
|
||||
}
|
||||
|
||||
// ID
|
||||
if(firstSubSelector.type === 'IdSelector') {
|
||||
selectedEl.removeAttr('id', firstSubSelector.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// clean up now empty elements
|
||||
for (var style of styles) {
|
||||
csstree.walk(style.cssAst, {visit: 'Rule', enter: function(node, item, list) {
|
||||
// clean up <style/> atrules without any rulesets left
|
||||
if (node.type === 'Atrule' &&
|
||||
// only Atrules containing rulesets
|
||||
node.block !== null &&
|
||||
node.block.children.isEmpty()) {
|
||||
list.remove(item);
|
||||
return;
|
||||
}
|
||||
|
||||
// clean up <style/> rulesets without any css selectors left
|
||||
if (node.type === 'Rule' &&
|
||||
node.prelude.children.isEmpty()) {
|
||||
list.remove(item);
|
||||
}
|
||||
}});
|
||||
|
||||
|
||||
if (style.cssAst.children.isEmpty()) {
|
||||
// clean up now emtpy <style/>s
|
||||
var styleParentEl = style.styleEl.parentNode;
|
||||
styleParentEl.spliceContent(styleParentEl.content.indexOf(style.styleEl), 1);
|
||||
|
||||
if (styleParentEl.elem === 'defs' &&
|
||||
styleParentEl.content.length === 0) {
|
||||
// also clean up now empty <def/>s
|
||||
var defsParentEl = styleParentEl.parentNode;
|
||||
defsParentEl.spliceContent(defsParentEl.content.indexOf(styleParentEl), 1);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// update existing, left over <style>s
|
||||
cssTools.setCssStr(style.styleEl, csstree.generate(style.cssAst));
|
||||
}
|
||||
|
||||
|
||||
return document;
|
||||
};
|
73
assets_old/node_modules/svgo/plugins/mergePaths.js
generated
vendored
Normal file
73
assets_old/node_modules/svgo/plugins/mergePaths.js
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'merges multiple paths in one if possible';
|
||||
|
||||
exports.params = {
|
||||
collapseRepeated: true,
|
||||
force: false,
|
||||
leadingZero: true,
|
||||
negativeExtraSpace: true,
|
||||
noSpaceAfterFlags: true
|
||||
};
|
||||
|
||||
var path2js = require('./_path.js').path2js,
|
||||
js2path = require('./_path.js').js2path,
|
||||
intersects = require('./_path.js').intersects;
|
||||
|
||||
/**
|
||||
* Merge multiple Paths into one.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich, Lev Solntsev
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
if (!item.isElem() || item.isEmpty()) return;
|
||||
|
||||
var prevContentItem = null,
|
||||
prevContentItemKeys = null;
|
||||
|
||||
item.content = item.content.filter(function(contentItem) {
|
||||
|
||||
if (prevContentItem &&
|
||||
prevContentItem.isElem('path') &&
|
||||
prevContentItem.isEmpty() &&
|
||||
prevContentItem.hasAttr('d') &&
|
||||
contentItem.isElem('path') &&
|
||||
contentItem.isEmpty() &&
|
||||
contentItem.hasAttr('d')
|
||||
) {
|
||||
|
||||
if (!prevContentItemKeys) {
|
||||
prevContentItemKeys = Object.keys(prevContentItem.attrs);
|
||||
}
|
||||
|
||||
var contentItemAttrs = Object.keys(contentItem.attrs),
|
||||
equalData = prevContentItemKeys.length == contentItemAttrs.length &&
|
||||
contentItemAttrs.every(function(key) {
|
||||
return key == 'd' ||
|
||||
prevContentItem.hasAttr(key) &&
|
||||
prevContentItem.attr(key).value == contentItem.attr(key).value;
|
||||
}),
|
||||
prevPathJS = path2js(prevContentItem),
|
||||
curPathJS = path2js(contentItem);
|
||||
|
||||
if (equalData && (params.force || !intersects(prevPathJS, curPathJS))) {
|
||||
js2path(prevContentItem, prevPathJS.concat(curPathJS), params);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
prevContentItem = contentItem;
|
||||
prevContentItemKeys = null;
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
};
|
160
assets_old/node_modules/svgo/plugins/minifyStyles.js
generated
vendored
Executable file
160
assets_old/node_modules/svgo/plugins/minifyStyles.js
generated
vendored
Executable file
|
@ -0,0 +1,160 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'minifies styles and removes unused styles based on usage data';
|
||||
|
||||
exports.params = {
|
||||
// ... CSSO options goes here
|
||||
|
||||
// additional
|
||||
usage: {
|
||||
force: false, // force to use usage data even if it unsafe (document contains <script> or on* attributes)
|
||||
ids: true,
|
||||
classes: true,
|
||||
tags: true
|
||||
}
|
||||
};
|
||||
|
||||
var csso = require('csso');
|
||||
|
||||
/**
|
||||
* Minifies styles (<style> element + style attribute) using CSSO
|
||||
*
|
||||
* @author strarsis <strarsis@gmail.com>
|
||||
*/
|
||||
exports.fn = function(ast, options) {
|
||||
options = options || {};
|
||||
|
||||
var minifyOptionsForStylesheet = cloneObject(options);
|
||||
var minifyOptionsForAttribute = cloneObject(options);
|
||||
var elems = findStyleElems(ast);
|
||||
|
||||
minifyOptionsForStylesheet.usage = collectUsageData(ast, options);
|
||||
minifyOptionsForAttribute.usage = null;
|
||||
|
||||
elems.forEach(function(elem) {
|
||||
if (elem.isElem('style')) {
|
||||
// <style> element
|
||||
var styleCss = elem.content[0].text || elem.content[0].cdata || [];
|
||||
var DATA = styleCss.indexOf('>') >= 0 || styleCss.indexOf('<') >= 0 ? 'cdata' : 'text';
|
||||
|
||||
elem.content[0][DATA] = csso.minify(styleCss, minifyOptionsForStylesheet).css;
|
||||
} else {
|
||||
// style attribute
|
||||
var elemStyle = elem.attr('style').value;
|
||||
|
||||
elem.attr('style').value = csso.minifyBlock(elemStyle, minifyOptionsForAttribute).css;
|
||||
}
|
||||
});
|
||||
|
||||
return ast;
|
||||
};
|
||||
|
||||
function cloneObject(obj) {
|
||||
var result = {};
|
||||
|
||||
for (var key in obj) {
|
||||
result[key] = obj[key];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function findStyleElems(ast) {
|
||||
|
||||
function walk(items, styles) {
|
||||
for (var i = 0; i < items.content.length; i++) {
|
||||
var item = items.content[i];
|
||||
|
||||
// go deeper
|
||||
if (item.content) {
|
||||
walk(item, styles);
|
||||
}
|
||||
|
||||
if (item.isElem('style') && !item.isEmpty()) {
|
||||
styles.push(item);
|
||||
} else if (item.isElem() && item.hasAttr('style')) {
|
||||
styles.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return styles;
|
||||
}
|
||||
|
||||
return walk(ast, []);
|
||||
}
|
||||
|
||||
function shouldFilter(options, name) {
|
||||
if ('usage' in options === false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (options.usage && name in options.usage === false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Boolean(options.usage && options.usage[name]);
|
||||
}
|
||||
|
||||
function collectUsageData(ast, options) {
|
||||
|
||||
function walk(items, usageData) {
|
||||
for (var i = 0; i < items.content.length; i++) {
|
||||
var item = items.content[i];
|
||||
|
||||
// go deeper
|
||||
if (item.content) {
|
||||
walk(item, usageData);
|
||||
}
|
||||
|
||||
if (item.isElem('script')) {
|
||||
safe = false;
|
||||
}
|
||||
|
||||
if (item.isElem()) {
|
||||
usageData.tags[item.elem] = true;
|
||||
|
||||
if (item.hasAttr('id')) {
|
||||
usageData.ids[item.attr('id').value] = true;
|
||||
}
|
||||
|
||||
if (item.hasAttr('class')) {
|
||||
item.attr('class').value.replace(/^\s+|\s+$/g, '').split(/\s+/).forEach(function(className) {
|
||||
usageData.classes[className] = true;
|
||||
});
|
||||
}
|
||||
|
||||
if (item.attrs && Object.keys(item.attrs).some(function(name) { return /^on/i.test(name); })) {
|
||||
safe = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usageData;
|
||||
}
|
||||
|
||||
var safe = true;
|
||||
var usageData = {};
|
||||
var hasData = false;
|
||||
var rawData = walk(ast, {
|
||||
ids: Object.create(null),
|
||||
classes: Object.create(null),
|
||||
tags: Object.create(null)
|
||||
});
|
||||
|
||||
if (!safe && options.usage && options.usage.force) {
|
||||
safe = true;
|
||||
}
|
||||
|
||||
for (var key in rawData) {
|
||||
if (shouldFilter(options, key)) {
|
||||
usageData[key] = Object.keys(rawData[key]);
|
||||
hasData = true;
|
||||
}
|
||||
}
|
||||
|
||||
return safe && hasData ? usageData : null;
|
||||
}
|
126
assets_old/node_modules/svgo/plugins/moveElemsAttrsToGroup.js
generated
vendored
Normal file
126
assets_old/node_modules/svgo/plugins/moveElemsAttrsToGroup.js
generated
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItemReverse';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'moves elements attributes to the existing group wrapper';
|
||||
|
||||
var inheritableAttrs = require('./_collections').inheritableAttrs,
|
||||
pathElems = require('./_collections.js').pathElems;
|
||||
|
||||
/**
|
||||
* Collapse content's intersected and inheritable
|
||||
* attributes to the existing group wrapper.
|
||||
*
|
||||
* @example
|
||||
* <g attr1="val1">
|
||||
* <g attr2="val2">
|
||||
* text
|
||||
* </g>
|
||||
* <circle attr2="val2" attr3="val3"/>
|
||||
* </g>
|
||||
* ⬇
|
||||
* <g attr1="val1" attr2="val2">
|
||||
* <g>
|
||||
* text
|
||||
* </g>
|
||||
* <circle attr3="val3"/>
|
||||
* </g>
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (item.isElem('g') && !item.isEmpty() && item.content.length > 1) {
|
||||
|
||||
var intersection = {},
|
||||
hasTransform = false,
|
||||
hasClip = item.hasAttr('clip-path') || item.hasAttr('mask'),
|
||||
intersected = item.content.every(function(inner) {
|
||||
if (inner.isElem() && inner.hasAttr()) {
|
||||
// don't mess with possible styles (hack until CSS parsing is implemented)
|
||||
if (inner.hasAttr('class')) return false;
|
||||
if (!Object.keys(intersection).length) {
|
||||
intersection = inner.attrs;
|
||||
} else {
|
||||
intersection = intersectInheritableAttrs(intersection, inner.attrs);
|
||||
|
||||
if (!intersection) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}),
|
||||
allPath = item.content.every(function(inner) {
|
||||
return inner.isElem(pathElems);
|
||||
});
|
||||
|
||||
if (intersected) {
|
||||
|
||||
item.content.forEach(function(g) {
|
||||
|
||||
for (var name in intersection) {
|
||||
|
||||
if (!allPath && !hasClip || name !== 'transform') {
|
||||
|
||||
g.removeAttr(name);
|
||||
|
||||
if (name === 'transform') {
|
||||
if (!hasTransform) {
|
||||
if (item.hasAttr('transform')) {
|
||||
item.attr('transform').value += ' ' + intersection[name].value;
|
||||
} else {
|
||||
item.addAttr(intersection[name]);
|
||||
}
|
||||
|
||||
hasTransform = true;
|
||||
}
|
||||
} else {
|
||||
item.addAttr(intersection[name]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Intersect inheritable attributes.
|
||||
*
|
||||
* @param {Object} a first attrs object
|
||||
* @param {Object} b second attrs object
|
||||
*
|
||||
* @return {Object} intersected attrs object
|
||||
*/
|
||||
function intersectInheritableAttrs(a, b) {
|
||||
|
||||
var c = {};
|
||||
|
||||
for (var n in a) {
|
||||
if (
|
||||
b.hasOwnProperty(n) &&
|
||||
inheritableAttrs.indexOf(n) > -1 &&
|
||||
a[n].name === b[n].name &&
|
||||
a[n].value === b[n].value &&
|
||||
a[n].prefix === b[n].prefix &&
|
||||
a[n].local === b[n].local
|
||||
) {
|
||||
c[n] = a[n];
|
||||
}
|
||||
}
|
||||
|
||||
if (!Object.keys(c).length) return false;
|
||||
|
||||
return c;
|
||||
|
||||
}
|
63
assets_old/node_modules/svgo/plugins/moveGroupAttrsToElems.js
generated
vendored
Normal file
63
assets_old/node_modules/svgo/plugins/moveGroupAttrsToElems.js
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'moves some group attributes to the content elements';
|
||||
|
||||
var collections = require('./_collections.js'),
|
||||
pathElems = collections.pathElems.concat(['g', 'text']),
|
||||
referencesProps = collections.referencesProps;
|
||||
|
||||
/**
|
||||
* Move group attrs to the content elements.
|
||||
*
|
||||
* @example
|
||||
* <g transform="scale(2)">
|
||||
* <path transform="rotate(45)" d="M0,0 L10,20"/>
|
||||
* <path transform="translate(10, 20)" d="M0,10 L20,30"/>
|
||||
* </g>
|
||||
* ⬇
|
||||
* <g>
|
||||
* <path transform="scale(2) rotate(45)" d="M0,0 L10,20"/>
|
||||
* <path transform="scale(2) translate(10, 20)" d="M0,10 L20,30"/>
|
||||
* </g>
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
// move group transform attr to content's pathElems
|
||||
if (
|
||||
item.isElem('g') &&
|
||||
item.hasAttr('transform') &&
|
||||
!item.isEmpty() &&
|
||||
!item.someAttr(function(attr) {
|
||||
return ~referencesProps.indexOf(attr.name) && ~attr.value.indexOf('url(');
|
||||
}) &&
|
||||
item.content.every(function(inner) {
|
||||
return inner.isElem(pathElems) && !inner.hasAttr('id');
|
||||
})
|
||||
) {
|
||||
item.content.forEach(function(inner) {
|
||||
var attr = item.attr('transform');
|
||||
if (inner.hasAttr('transform')) {
|
||||
inner.attr('transform').value = attr.value + ' ' + inner.attr('transform').value;
|
||||
} else {
|
||||
inner.addAttr({
|
||||
'name': attr.name,
|
||||
'local': attr.local,
|
||||
'prefix': attr.prefix,
|
||||
'value': attr.value
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
item.removeAttr('transform');
|
||||
}
|
||||
|
||||
};
|
243
assets_old/node_modules/svgo/plugins/prefixIds.js
generated
vendored
Executable file
243
assets_old/node_modules/svgo/plugins/prefixIds.js
generated
vendored
Executable file
|
@ -0,0 +1,243 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.params = {
|
||||
delim: '__',
|
||||
prefixIds: true,
|
||||
prefixClassNames: true,
|
||||
};
|
||||
|
||||
exports.description = 'prefix IDs';
|
||||
|
||||
|
||||
var path = require('path'),
|
||||
csstree = require('css-tree'),
|
||||
unquote = require('unquote'),
|
||||
collections = require('./_collections.js'),
|
||||
referencesProps = collections.referencesProps,
|
||||
rxId = /^#(.*)$/, // regular expression for matching an ID + extracing its name
|
||||
addPrefix = null;
|
||||
|
||||
|
||||
// Escapes a string for being used as ID
|
||||
var escapeIdentifierName = function(str) {
|
||||
return str.replace(/[\. ]/g, '_');
|
||||
};
|
||||
|
||||
// Matches an #ID value, captures the ID name
|
||||
var matchId = function(urlVal) {
|
||||
var idUrlMatches = urlVal.match(rxId);
|
||||
if (idUrlMatches === null) {
|
||||
return false;
|
||||
}
|
||||
return idUrlMatches[1];
|
||||
};
|
||||
|
||||
// Matches an url(...) value, captures the URL
|
||||
var matchUrl = function(val) {
|
||||
var urlMatches = /url\((.*?)\)/gi.exec(val);
|
||||
if (urlMatches === null) {
|
||||
return false;
|
||||
}
|
||||
return urlMatches[1];
|
||||
};
|
||||
|
||||
// Checks if attribute is empty
|
||||
var attrNotEmpty = function(attr) {
|
||||
return (attr && attr.value && attr.value.length > 0);
|
||||
};
|
||||
|
||||
// prefixes an #ID
|
||||
var prefixId = function(val) {
|
||||
var idName = matchId(val);
|
||||
if (!idName) {
|
||||
return false;
|
||||
}
|
||||
return '#' + addPrefix(idName);
|
||||
};
|
||||
|
||||
|
||||
// attr.value helper methods
|
||||
|
||||
// prefixes a class attribute value
|
||||
var addPrefixToClassAttr = function(attr) {
|
||||
if (!attrNotEmpty(attr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
attr.value = attr.value.split(/\s+/).map(addPrefix).join(' ');
|
||||
};
|
||||
|
||||
// prefixes an ID attribute value
|
||||
var addPrefixToIdAttr = function(attr) {
|
||||
if (!attrNotEmpty(attr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
attr.value = addPrefix(attr.value);
|
||||
};
|
||||
|
||||
// prefixes a href attribute value
|
||||
var addPrefixToHrefAttr = function(attr) {
|
||||
if (!attrNotEmpty(attr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var idPrefixed = prefixId(attr.value);
|
||||
if (!idPrefixed) {
|
||||
return;
|
||||
}
|
||||
attr.value = idPrefixed;
|
||||
};
|
||||
|
||||
// prefixes an URL attribute value
|
||||
var addPrefixToUrlAttr = function(attr) {
|
||||
if (!attrNotEmpty(attr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// url(...) in value
|
||||
var urlVal = matchUrl(attr.value);
|
||||
if (!urlVal) {
|
||||
return;
|
||||
}
|
||||
|
||||
var idPrefixed = prefixId(urlVal);
|
||||
if (!idPrefixed) {
|
||||
return;
|
||||
}
|
||||
|
||||
attr.value = 'url(' + idPrefixed + ')';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Prefixes identifiers
|
||||
*
|
||||
* @param {Object} node node
|
||||
* @param {Object} opts plugin params
|
||||
* @param {Object} extra plugin extra information
|
||||
*
|
||||
* @author strarsis <strarsis@gmail.com>
|
||||
*/
|
||||
exports.fn = function(node, opts, extra) {
|
||||
|
||||
// skip subsequent passes when multipass is used
|
||||
if(extra.multipassCount && extra.multipassCount > 0) {
|
||||
return node;
|
||||
}
|
||||
|
||||
// prefix, from file name or option
|
||||
var prefix = 'prefix';
|
||||
if (opts.prefix) {
|
||||
if (typeof opts.prefix === 'function') {
|
||||
prefix = opts.prefix(node, extra);
|
||||
} else {
|
||||
prefix = opts.prefix;
|
||||
}
|
||||
} else if (opts.prefix === false) {
|
||||
prefix = false;
|
||||
} else if (extra && extra.path && extra.path.length > 0) {
|
||||
var filename = path.basename(extra.path);
|
||||
prefix = filename;
|
||||
}
|
||||
|
||||
|
||||
// prefixes a normal value
|
||||
addPrefix = function(name) {
|
||||
if(prefix === false){
|
||||
return escapeIdentifierName(name);
|
||||
}
|
||||
return escapeIdentifierName(prefix + opts.delim + name);
|
||||
};
|
||||
|
||||
|
||||
// <style/> property values
|
||||
|
||||
if (node.elem === 'style') {
|
||||
if (node.isEmpty()) {
|
||||
// skip empty <style/>s
|
||||
return node;
|
||||
}
|
||||
|
||||
var cssStr = node.content[0].text || node.content[0].cdata || [];
|
||||
|
||||
var cssAst = {};
|
||||
try {
|
||||
cssAst = csstree.parse(cssStr, {
|
||||
parseValue: true,
|
||||
parseCustomProperty: false
|
||||
});
|
||||
} catch (parseError) {
|
||||
console.warn('Warning: Parse error of styles of <style/> element, skipped. Error details: ' + parseError);
|
||||
return node;
|
||||
}
|
||||
|
||||
var idPrefixed = '';
|
||||
csstree.walk(cssAst, function(node) {
|
||||
|
||||
// #ID, .class
|
||||
if (((opts.prefixIds && node.type === 'IdSelector') ||
|
||||
(opts.prefixClassNames && node.type === 'ClassSelector')) &&
|
||||
node.name) {
|
||||
node.name = addPrefix(node.name);
|
||||
return;
|
||||
}
|
||||
|
||||
// url(...) in value
|
||||
if (node.type === 'Url' &&
|
||||
node.value.value && node.value.value.length > 0) {
|
||||
idPrefixed = prefixId(unquote(node.value.value));
|
||||
if (!idPrefixed) {
|
||||
return;
|
||||
}
|
||||
node.value.value = idPrefixed;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// update <style>s
|
||||
node.content[0].text = csstree.generate(cssAst);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
// element attributes
|
||||
|
||||
if (!node.attrs) {
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
// Nodes
|
||||
|
||||
if(opts.prefixIds) {
|
||||
// ID
|
||||
addPrefixToIdAttr(node.attrs.id);
|
||||
}
|
||||
|
||||
if(opts.prefixClassNames) {
|
||||
// Class
|
||||
addPrefixToClassAttr(node.attrs.class);
|
||||
}
|
||||
|
||||
|
||||
// References
|
||||
|
||||
// href
|
||||
addPrefixToHrefAttr(node.attrs.href);
|
||||
|
||||
// (xlink:)href (deprecated, must be still supported)
|
||||
addPrefixToHrefAttr(node.attrs['xlink:href']);
|
||||
|
||||
// (referenceable) properties
|
||||
for (var referencesProp of referencesProps) {
|
||||
addPrefixToUrlAttr(node.attrs[referencesProp]);
|
||||
}
|
||||
|
||||
|
||||
return node;
|
||||
};
|
70
assets_old/node_modules/svgo/plugins/removeAttributesBySelector.js
generated
vendored
Normal file
70
assets_old/node_modules/svgo/plugins/removeAttributesBySelector.js
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'removes attributes of elements that match a css selector';
|
||||
|
||||
|
||||
/**
|
||||
* Removes attributes of elements that match a css selector.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @example
|
||||
* <caption>A selector removing a single attribute</caption>
|
||||
* plugins:
|
||||
* - removeAttributesBySelector:
|
||||
* selector: "[fill='#00ff00']"
|
||||
* attributes: "fill"
|
||||
*
|
||||
* <rect x="0" y="0" width="100" height="100" fill="#00ff00" stroke="#00ff00"/>
|
||||
* ↓
|
||||
* <rect x="0" y="0" width="100" height="100" stroke="#00ff00"/>
|
||||
*
|
||||
* <caption>A selector removing multiple attributes</caption>
|
||||
* plugins:
|
||||
* - removeAttributesBySelector:
|
||||
* selector: "[fill='#00ff00']"
|
||||
* attributes:
|
||||
* - fill
|
||||
* - stroke
|
||||
*
|
||||
* <rect x="0" y="0" width="100" height="100" fill="#00ff00" stroke="#00ff00"/>
|
||||
* ↓
|
||||
* <rect x="0" y="0" width="100" height="100"/>
|
||||
*
|
||||
* <caption>Multiple selectors removing attributes</caption>
|
||||
* plugins:
|
||||
* - removeAttributesBySelector:
|
||||
* selectors:
|
||||
* - selector: "[fill='#00ff00']"
|
||||
* attributes: "fill"
|
||||
*
|
||||
* - selector: "#remove"
|
||||
* attributes:
|
||||
* - stroke
|
||||
* - id
|
||||
*
|
||||
* <rect x="0" y="0" width="100" height="100" fill="#00ff00" stroke="#00ff00"/>
|
||||
* ↓
|
||||
* <rect x="0" y="0" width="100" height="100"/>
|
||||
*
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors|MDN CSS Selectors}
|
||||
*
|
||||
* @author Bradley Mease
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
var selectors = Array.isArray(params.selectors) ? params.selectors : [params];
|
||||
|
||||
selectors.map(function(i) {
|
||||
if (item.matches(i.selector)) {
|
||||
item.removeAttr(i.attributes);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
150
assets_old/node_modules/svgo/plugins/removeAttrs.js
generated
vendored
Normal file
150
assets_old/node_modules/svgo/plugins/removeAttrs.js
generated
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
'use strict';
|
||||
|
||||
var DEFAULT_SEPARATOR = ':';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'removes specified attributes';
|
||||
|
||||
exports.params = {
|
||||
elemSeparator: DEFAULT_SEPARATOR,
|
||||
preserveCurrentColor: false,
|
||||
attrs: []
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove attributes
|
||||
*
|
||||
* @param elemSeparator
|
||||
* format: string
|
||||
*
|
||||
* @param preserveCurrentColor
|
||||
* format: boolean
|
||||
*
|
||||
* @param attrs:
|
||||
*
|
||||
* format: [ element* : attribute* : value* ]
|
||||
*
|
||||
* element : regexp (wrapped into ^...$), single * or omitted > all elements (must be present when value is used)
|
||||
* attribute : regexp (wrapped into ^...$)
|
||||
* value : regexp (wrapped into ^...$), single * or omitted > all values
|
||||
*
|
||||
* examples:
|
||||
*
|
||||
* > basic: remove fill attribute
|
||||
* ---
|
||||
* removeAttrs:
|
||||
* attrs: 'fill'
|
||||
*
|
||||
* > remove fill attribute on path element
|
||||
* ---
|
||||
* attrs: 'path:fill'
|
||||
*
|
||||
* > remove fill attribute on path element where value is none
|
||||
* ---
|
||||
* attrs: 'path:fill:none'
|
||||
*
|
||||
*
|
||||
* > remove all fill and stroke attribute
|
||||
* ---
|
||||
* attrs:
|
||||
* - 'fill'
|
||||
* - 'stroke'
|
||||
*
|
||||
* [is same as]
|
||||
*
|
||||
* attrs: '(fill|stroke)'
|
||||
*
|
||||
* [is same as]
|
||||
*
|
||||
* attrs: '*:(fill|stroke)'
|
||||
*
|
||||
* [is same as]
|
||||
*
|
||||
* attrs: '.*:(fill|stroke)'
|
||||
*
|
||||
* [is same as]
|
||||
*
|
||||
* attrs: '.*:(fill|stroke):.*'
|
||||
*
|
||||
*
|
||||
* > remove all stroke related attributes
|
||||
* ----
|
||||
* attrs: 'stroke.*'
|
||||
*
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Benny Schudel
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
// wrap into an array if params is not
|
||||
if (!Array.isArray(params.attrs)) {
|
||||
params.attrs = [params.attrs];
|
||||
}
|
||||
|
||||
if (item.isElem()) {
|
||||
var elemSeparator = typeof params.elemSeparator == 'string' ? params.elemSeparator : DEFAULT_SEPARATOR;
|
||||
var preserveCurrentColor = typeof params.preserveCurrentColor == 'boolean' ? params.preserveCurrentColor : false;
|
||||
|
||||
// prepare patterns
|
||||
var patterns = params.attrs.map(function(pattern) {
|
||||
|
||||
// if no element separators (:), assume it's attribute name, and apply to all elements *regardless of value*
|
||||
if (pattern.indexOf(elemSeparator) === -1) {
|
||||
pattern = ['.*', elemSeparator, pattern, elemSeparator, '.*'].join('');
|
||||
|
||||
// if only 1 separator, assume it's element and attribute name, and apply regardless of attribute value
|
||||
} else if (pattern.split(elemSeparator).length < 3) {
|
||||
pattern = [pattern, elemSeparator, '.*'].join('');
|
||||
}
|
||||
|
||||
// create regexps for element, attribute name, and attribute value
|
||||
return pattern.split(elemSeparator)
|
||||
.map(function(value) {
|
||||
|
||||
// adjust single * to match anything
|
||||
if (value === '*') { value = '.*'; }
|
||||
|
||||
return new RegExp(['^', value, '$'].join(''), 'i');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// loop patterns
|
||||
patterns.forEach(function(pattern) {
|
||||
|
||||
// matches element
|
||||
if (pattern[0].test(item.elem)) {
|
||||
|
||||
// loop attributes
|
||||
item.eachAttr(function(attr) {
|
||||
var name = attr.name;
|
||||
var value = attr.value;
|
||||
var isFillCurrentColor = preserveCurrentColor && name == 'fill' && value == 'currentColor';
|
||||
var isStrokeCurrentColor = preserveCurrentColor && name == 'stroke' && value == 'currentColor';
|
||||
|
||||
if (!(isFillCurrentColor || isStrokeCurrentColor)) {
|
||||
// matches attribute name
|
||||
if (pattern[1].test(name)) {
|
||||
|
||||
// matches attribute value
|
||||
if (pattern[2].test(attr.value)) {
|
||||
item.removeAttr(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
27
assets_old/node_modules/svgo/plugins/removeComments.js
generated
vendored
Normal file
27
assets_old/node_modules/svgo/plugins/removeComments.js
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes comments';
|
||||
|
||||
/**
|
||||
* Remove comments.
|
||||
*
|
||||
* @example
|
||||
* <!-- Generator: Adobe Illustrator 15.0.0, SVG Export
|
||||
* Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (item.comment && item.comment.charAt(0) !== '!') {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
32
assets_old/node_modules/svgo/plugins/removeDesc.js
generated
vendored
Normal file
32
assets_old/node_modules/svgo/plugins/removeDesc.js
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.params = {
|
||||
removeAny: true
|
||||
};
|
||||
|
||||
exports.description = 'removes <desc>';
|
||||
|
||||
var standardDescs = /^(Created with|Created using)/;
|
||||
|
||||
/**
|
||||
* Removes <desc>.
|
||||
* Removes only standard editors content or empty elements 'cause it can be used for accessibility.
|
||||
* Enable parameter 'removeAny' to remove any description.
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/SVG/Element/desc
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Daniel Wabyick
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
return !item.isElem('desc') || !(params.removeAny || item.isEmpty() ||
|
||||
standardDescs.test(item.content[0].text));
|
||||
|
||||
};
|
49
assets_old/node_modules/svgo/plugins/removeDimensions.js
generated
vendored
Normal file
49
assets_old/node_modules/svgo/plugins/removeDimensions.js
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'removes width and height in presence of viewBox (opposite to removeViewBox, disable it first)';
|
||||
|
||||
/**
|
||||
* Remove width/height attributes and add the viewBox attribute if it's missing
|
||||
*
|
||||
* @example
|
||||
* <svg width="100" height="50" />
|
||||
* ↓
|
||||
* <svg viewBox="0 0 100 50" />
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if true, with and height will be filtered out
|
||||
*
|
||||
* @author Benny Schudel
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (item.isElem('svg')) {
|
||||
if (item.hasAttr('viewBox')) {
|
||||
item.removeAttr('width');
|
||||
item.removeAttr('height');
|
||||
} else if (
|
||||
item.hasAttr('width') &&
|
||||
item.hasAttr('height') &&
|
||||
!isNaN(Number(item.attr('width').value)) &&
|
||||
!isNaN(Number(item.attr('height').value))
|
||||
) {
|
||||
item.addAttr({
|
||||
name: 'viewBox',
|
||||
value:
|
||||
'0 0 ' +
|
||||
Number(item.attr('width').value) +
|
||||
' ' +
|
||||
Number(item.attr('height').value),
|
||||
prefix: '',
|
||||
local: 'viewBox'
|
||||
});
|
||||
item.removeAttr('width');
|
||||
item.removeAttr('height');
|
||||
}
|
||||
}
|
||||
|
||||
};
|
40
assets_old/node_modules/svgo/plugins/removeDoctype.js
generated
vendored
Normal file
40
assets_old/node_modules/svgo/plugins/removeDoctype.js
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes doctype declaration';
|
||||
|
||||
/**
|
||||
* Remove DOCTYPE declaration.
|
||||
*
|
||||
* "Unfortunately the SVG DTDs are a source of so many
|
||||
* issues that the SVG WG has decided not to write one
|
||||
* for the upcoming SVG 1.2 standard. In fact SVG WG
|
||||
* members are even telling people not to use a DOCTYPE
|
||||
* declaration in SVG 1.0 and 1.1 documents"
|
||||
* https://jwatt.org/svg/authoring/#doctype-declaration
|
||||
*
|
||||
* @example
|
||||
* <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
* q"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
*
|
||||
* @example
|
||||
* <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
* "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [
|
||||
* <!-- an internal subset can be embedded here -->
|
||||
* ]>
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (item.doctype) {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
65
assets_old/node_modules/svgo/plugins/removeEditorsNSData.js
generated
vendored
Normal file
65
assets_old/node_modules/svgo/plugins/removeEditorsNSData.js
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes editors namespaces, elements and attributes';
|
||||
|
||||
var editorNamespaces = require('./_collections').editorNamespaces,
|
||||
prefixes = [];
|
||||
|
||||
exports.params = {
|
||||
additionalNamespaces: []
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove editors namespaces, elements and attributes.
|
||||
*
|
||||
* @example
|
||||
* <svg xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd">
|
||||
* <sodipodi:namedview/>
|
||||
* <path sodipodi:nodetypes="cccc"/>
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
if (Array.isArray(params.additionalNamespaces)) {
|
||||
editorNamespaces = editorNamespaces.concat(params.additionalNamespaces);
|
||||
}
|
||||
|
||||
if (item.elem) {
|
||||
|
||||
if (item.isElem('svg')) {
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
if (attr.prefix === 'xmlns' && editorNamespaces.indexOf(attr.value) > -1) {
|
||||
prefixes.push(attr.local);
|
||||
|
||||
// <svg xmlns:sodipodi="">
|
||||
item.removeAttr(attr.name);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// <* sodipodi:*="">
|
||||
item.eachAttr(function(attr) {
|
||||
if (prefixes.indexOf(attr.prefix) > -1) {
|
||||
item.removeAttr(attr.name);
|
||||
}
|
||||
});
|
||||
|
||||
// <sodipodi:*>
|
||||
if (prefixes.indexOf(item.prefix) > -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
80
assets_old/node_modules/svgo/plugins/removeElementsByAttr.js
generated
vendored
Normal file
80
assets_old/node_modules/svgo/plugins/removeElementsByAttr.js
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'removes arbitrary elements by ID or className (disabled by default)';
|
||||
|
||||
exports.params = {
|
||||
id: [],
|
||||
class: []
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove arbitrary SVG elements by ID or className.
|
||||
*
|
||||
* @param id
|
||||
* examples:
|
||||
*
|
||||
* > single: remove element with ID of `elementID`
|
||||
* ---
|
||||
* removeElementsByAttr:
|
||||
* id: 'elementID'
|
||||
*
|
||||
* > list: remove multiple elements by ID
|
||||
* ---
|
||||
* removeElementsByAttr:
|
||||
* id:
|
||||
* - 'elementID'
|
||||
* - 'anotherID'
|
||||
*
|
||||
* @param class
|
||||
* examples:
|
||||
*
|
||||
* > single: remove all elements with class of `elementClass`
|
||||
* ---
|
||||
* removeElementsByAttr:
|
||||
* class: 'elementClass'
|
||||
*
|
||||
* > list: remove all elements with class of `elementClass` or `anotherClass`
|
||||
* ---
|
||||
* removeElementsByAttr:
|
||||
* class:
|
||||
* - 'elementClass'
|
||||
* - 'anotherClass'
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Eli Dupuis (@elidupuis)
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
var elemId, elemClass;
|
||||
|
||||
// wrap params in an array if not already
|
||||
['id', 'class'].forEach(function(key) {
|
||||
if (!Array.isArray(params[key])) {
|
||||
params[key] = [ params[key] ];
|
||||
}
|
||||
});
|
||||
|
||||
// abort if current item is no an element
|
||||
if (!item.isElem()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// remove element if it's `id` matches configured `id` params
|
||||
elemId = item.attr('id');
|
||||
if (elemId) {
|
||||
return params.id.indexOf(elemId.value) === -1;
|
||||
}
|
||||
|
||||
// remove element if it's `class` contains any of the configured `class` params
|
||||
elemClass = item.attr('class');
|
||||
if (elemClass) {
|
||||
var hasClassRegex = new RegExp(params.class.join('|'));
|
||||
return !hasClassRegex.test(elemClass.value);
|
||||
}
|
||||
};
|
29
assets_old/node_modules/svgo/plugins/removeEmptyAttrs.js
generated
vendored
Normal file
29
assets_old/node_modules/svgo/plugins/removeEmptyAttrs.js
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes empty attributes';
|
||||
|
||||
/**
|
||||
* Remove attributes with empty values.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (item.elem) {
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
if (attr.value === '') {
|
||||
item.removeAttr(attr.name);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
32
assets_old/node_modules/svgo/plugins/removeEmptyContainers.js
generated
vendored
Normal file
32
assets_old/node_modules/svgo/plugins/removeEmptyContainers.js
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItemReverse';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes empty container elements';
|
||||
|
||||
var container = require('./_collections').elemsGroups.container;
|
||||
|
||||
/**
|
||||
* Remove empty containers.
|
||||
*
|
||||
* @see http://www.w3.org/TR/SVG/intro.html#TermContainerElement
|
||||
*
|
||||
* @example
|
||||
* <defs/>
|
||||
*
|
||||
* @example
|
||||
* <g><marker><a/></marker></g>
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
return !(item.isElem(container) && !item.isElem('svg') && item.isEmpty() &&
|
||||
(!item.isElem('pattern') || !item.hasAttrLocal('href')));
|
||||
|
||||
};
|
59
assets_old/node_modules/svgo/plugins/removeEmptyText.js
generated
vendored
Normal file
59
assets_old/node_modules/svgo/plugins/removeEmptyText.js
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes empty <text> elements';
|
||||
|
||||
exports.params = {
|
||||
text: true,
|
||||
tspan: true,
|
||||
tref: true
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove empty Text elements.
|
||||
*
|
||||
* @see http://www.w3.org/TR/SVG/text.html
|
||||
*
|
||||
* @example
|
||||
* Remove empty text element:
|
||||
* <text/>
|
||||
*
|
||||
* Remove empty tspan element:
|
||||
* <tspan/>
|
||||
*
|
||||
* Remove tref with empty xlink:href attribute:
|
||||
* <tref xlink:href=""/>
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
// Remove empty text element
|
||||
if (
|
||||
params.text &&
|
||||
item.isElem('text') &&
|
||||
item.isEmpty()
|
||||
) return false;
|
||||
|
||||
// Remove empty tspan element
|
||||
if (
|
||||
params.tspan &&
|
||||
item.isElem('tspan') &&
|
||||
item.isEmpty()
|
||||
) return false;
|
||||
|
||||
// Remove tref with empty xlink:href attribute
|
||||
if (
|
||||
params.tref &&
|
||||
item.isElem('tref') &&
|
||||
!item.hasAttrLocal('href')
|
||||
) return false;
|
||||
|
||||
};
|
225
assets_old/node_modules/svgo/plugins/removeHiddenElems.js
generated
vendored
Normal file
225
assets_old/node_modules/svgo/plugins/removeHiddenElems.js
generated
vendored
Normal file
|
@ -0,0 +1,225 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes hidden elements (zero sized, with absent attributes)';
|
||||
|
||||
exports.params = {
|
||||
isHidden: true,
|
||||
displayNone: true,
|
||||
opacity0: true,
|
||||
circleR0: true,
|
||||
ellipseRX0: true,
|
||||
ellipseRY0: true,
|
||||
rectWidth0: true,
|
||||
rectHeight0: true,
|
||||
patternWidth0: true,
|
||||
patternHeight0: true,
|
||||
imageWidth0: true,
|
||||
imageHeight0: true,
|
||||
pathEmptyD: true,
|
||||
polylineEmptyPoints: true,
|
||||
polygonEmptyPoints: true
|
||||
};
|
||||
|
||||
var regValidPath = /M\s*(?:[-+]?(?:\d*\.\d+|\d+(?:\.|(?!\.)))([eE][-+]?\d+)?(?!\d)\s*,?\s*){2}\D*\d/i;
|
||||
|
||||
/**
|
||||
* Remove hidden elements with disabled rendering:
|
||||
* - display="none"
|
||||
* - opacity="0"
|
||||
* - circle with zero radius
|
||||
* - ellipse with zero x-axis or y-axis radius
|
||||
* - rectangle with zero width or height
|
||||
* - pattern with zero width or height
|
||||
* - image with zero width or height
|
||||
* - path with empty data
|
||||
* - polyline with empty points
|
||||
* - polygon with empty points
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function (item, params) {
|
||||
|
||||
if (item.elem) {
|
||||
// Removes hidden elements
|
||||
// https://www.w3schools.com/cssref/pr_class_visibility.asp
|
||||
if (
|
||||
params.isHidden &&
|
||||
item.hasAttr('visibility', 'hidden')
|
||||
) return false;
|
||||
|
||||
// display="none"
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/painting.html#DisplayProperty
|
||||
// "A value of display: none indicates that the given element
|
||||
// and its children shall not be rendered directly"
|
||||
if (
|
||||
params.displayNone &&
|
||||
item.hasAttr('display', 'none')
|
||||
) return false;
|
||||
|
||||
// opacity="0"
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/masking.html#ObjectAndGroupOpacityProperties
|
||||
if (
|
||||
params.opacity0 &&
|
||||
item.hasAttr('opacity', '0')
|
||||
) return false;
|
||||
|
||||
// Circles with zero radius
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/shapes.html#CircleElementRAttribute
|
||||
// "A value of zero disables rendering of the element"
|
||||
//
|
||||
// <circle r="0">
|
||||
if (
|
||||
params.circleR0 &&
|
||||
item.isElem('circle') &&
|
||||
item.isEmpty() &&
|
||||
item.hasAttr('r', '0')
|
||||
) return false;
|
||||
|
||||
// Ellipse with zero x-axis radius
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/shapes.html#EllipseElementRXAttribute
|
||||
// "A value of zero disables rendering of the element"
|
||||
//
|
||||
// <ellipse rx="0">
|
||||
if (
|
||||
params.ellipseRX0 &&
|
||||
item.isElem('ellipse') &&
|
||||
item.isEmpty() &&
|
||||
item.hasAttr('rx', '0')
|
||||
) return false;
|
||||
|
||||
// Ellipse with zero y-axis radius
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/shapes.html#EllipseElementRYAttribute
|
||||
// "A value of zero disables rendering of the element"
|
||||
//
|
||||
// <ellipse ry="0">
|
||||
if (
|
||||
params.ellipseRY0 &&
|
||||
item.isElem('ellipse') &&
|
||||
item.isEmpty() &&
|
||||
item.hasAttr('ry', '0')
|
||||
) return false;
|
||||
|
||||
// Rectangle with zero width
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/shapes.html#RectElementWidthAttribute
|
||||
// "A value of zero disables rendering of the element"
|
||||
//
|
||||
// <rect width="0">
|
||||
if (
|
||||
params.rectWidth0 &&
|
||||
item.isElem('rect') &&
|
||||
item.isEmpty() &&
|
||||
item.hasAttr('width', '0')
|
||||
) return false;
|
||||
|
||||
// Rectangle with zero height
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/shapes.html#RectElementHeightAttribute
|
||||
// "A value of zero disables rendering of the element"
|
||||
//
|
||||
// <rect height="0">
|
||||
if (
|
||||
params.rectHeight0 &&
|
||||
params.rectWidth0 &&
|
||||
item.isElem('rect') &&
|
||||
item.isEmpty() &&
|
||||
item.hasAttr('height', '0')
|
||||
) return false;
|
||||
|
||||
// Pattern with zero width
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/pservers.html#PatternElementWidthAttribute
|
||||
// "A value of zero disables rendering of the element (i.e., no paint is applied)"
|
||||
//
|
||||
// <pattern width="0">
|
||||
if (
|
||||
params.patternWidth0 &&
|
||||
item.isElem('pattern') &&
|
||||
item.hasAttr('width', '0')
|
||||
) return false;
|
||||
|
||||
// Pattern with zero height
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/pservers.html#PatternElementHeightAttribute
|
||||
// "A value of zero disables rendering of the element (i.e., no paint is applied)"
|
||||
//
|
||||
// <pattern height="0">
|
||||
if (
|
||||
params.patternHeight0 &&
|
||||
item.isElem('pattern') &&
|
||||
item.hasAttr('height', '0')
|
||||
) return false;
|
||||
|
||||
// Image with zero width
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/struct.html#ImageElementWidthAttribute
|
||||
// "A value of zero disables rendering of the element"
|
||||
//
|
||||
// <image width="0">
|
||||
if (
|
||||
params.imageWidth0 &&
|
||||
item.isElem('image') &&
|
||||
item.hasAttr('width', '0')
|
||||
) return false;
|
||||
|
||||
// Image with zero height
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/struct.html#ImageElementHeightAttribute
|
||||
// "A value of zero disables rendering of the element"
|
||||
//
|
||||
// <image height="0">
|
||||
if (
|
||||
params.imageHeight0 &&
|
||||
item.isElem('image') &&
|
||||
item.hasAttr('height', '0')
|
||||
) return false;
|
||||
|
||||
// Path with empty data
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/paths.html#DAttribute
|
||||
//
|
||||
// <path d=""/>
|
||||
if (
|
||||
params.pathEmptyD &&
|
||||
item.isElem('path') &&
|
||||
(!item.hasAttr('d') || !regValidPath.test(item.attr('d').value))
|
||||
) return false;
|
||||
|
||||
// Polyline with empty points
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/shapes.html#PolylineElementPointsAttribute
|
||||
//
|
||||
// <polyline points="">
|
||||
if (
|
||||
params.polylineEmptyPoints &&
|
||||
item.isElem('polyline') &&
|
||||
!item.hasAttr('points')
|
||||
) return false;
|
||||
|
||||
// Polygon with empty points
|
||||
//
|
||||
// http://www.w3.org/TR/SVG/shapes.html#PolygonElementPointsAttribute
|
||||
//
|
||||
// <polygon points="">
|
||||
if (
|
||||
params.polygonEmptyPoints &&
|
||||
item.isElem('polygon') &&
|
||||
!item.hasAttr('points')
|
||||
) return false;
|
||||
|
||||
}
|
||||
|
||||
};
|
23
assets_old/node_modules/svgo/plugins/removeMetadata.js
generated
vendored
Normal file
23
assets_old/node_modules/svgo/plugins/removeMetadata.js
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes <metadata>';
|
||||
|
||||
/**
|
||||
* Remove <metadata>.
|
||||
*
|
||||
* http://www.w3.org/TR/SVG/metadata.html
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
return !item.isElem('metadata');
|
||||
|
||||
};
|
37
assets_old/node_modules/svgo/plugins/removeNonInheritableGroupAttrs.js
generated
vendored
Normal file
37
assets_old/node_modules/svgo/plugins/removeNonInheritableGroupAttrs.js
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes non-inheritable group’s presentational attributes';
|
||||
|
||||
var inheritableAttrs = require('./_collections').inheritableAttrs,
|
||||
attrsGroups = require('./_collections').attrsGroups,
|
||||
applyGroups = require('./_collections').presentationNonInheritableGroupAttrs;
|
||||
|
||||
/**
|
||||
* Remove non-inheritable group's "presentation" attributes.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (item.isElem('g')) {
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
if (
|
||||
~attrsGroups.presentation.indexOf(attr.name) &&
|
||||
!~inheritableAttrs.indexOf(attr.name) &&
|
||||
!~applyGroups.indexOf(attr.name)
|
||||
) {
|
||||
item.removeAttr(attr.name);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
133
assets_old/node_modules/svgo/plugins/removeOffCanvasPaths.js
generated
vendored
Normal file
133
assets_old/node_modules/svgo/plugins/removeOffCanvasPaths.js
generated
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'removes elements that are drawn outside of the viewbox (disabled by default)';
|
||||
|
||||
var SVGO = require('../lib/svgo.js'),
|
||||
_path = require('./_path.js'),
|
||||
intersects = _path.intersects,
|
||||
path2js = _path.path2js,
|
||||
viewBox,
|
||||
viewBoxJS;
|
||||
|
||||
/**
|
||||
* Remove elements that are drawn outside of the viewbox.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author JoshyPHP
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (item.isElem('path') && item.hasAttr('d') && typeof viewBox !== 'undefined')
|
||||
{
|
||||
// Consider that any item with a transform attribute or a M instruction
|
||||
// within the viewBox is visible
|
||||
if (hasTransform(item) || pathMovesWithinViewBox(item.attr('d').value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var pathJS = path2js(item);
|
||||
if (pathJS.length === 2)
|
||||
{
|
||||
// Use a closed clone of the path if it's too short for intersects()
|
||||
pathJS = JSON.parse(JSON.stringify(pathJS));
|
||||
pathJS.push({ instruction: 'z' });
|
||||
}
|
||||
|
||||
return intersects(viewBoxJS, pathJS);
|
||||
}
|
||||
if (item.isElem('svg'))
|
||||
{
|
||||
parseViewBox(item);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether given item or any of its ancestors has a transform attribute.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function hasTransform(item)
|
||||
{
|
||||
return item.hasAttr('transform') || (item.parentNode && hasTransform(item.parentNode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the viewBox coordinates and compute the JS representation of its path.
|
||||
*
|
||||
* @param {Object} svg svg element item
|
||||
*/
|
||||
function parseViewBox(svg)
|
||||
{
|
||||
var viewBoxData = '';
|
||||
if (svg.hasAttr('viewBox'))
|
||||
{
|
||||
// Remove commas and plus signs, normalize and trim whitespace
|
||||
viewBoxData = svg.attr('viewBox').value;
|
||||
}
|
||||
else if (svg.hasAttr('height') && svg.hasAttr('width'))
|
||||
{
|
||||
viewBoxData = '0 0 ' + svg.attr('width').value + ' ' + svg.attr('height').value;
|
||||
}
|
||||
|
||||
// Remove commas and plus signs, normalize and trim whitespace
|
||||
viewBoxData = viewBoxData.replace(/[,+]|px/g, ' ').replace(/\s+/g, ' ').replace(/^\s*|\s*$/g, '');
|
||||
|
||||
// Ensure that the dimensions are 4 values separated by space
|
||||
var m = /^(-?\d*\.?\d+) (-?\d*\.?\d+) (\d*\.?\d+) (\d*\.?\d+)$/.exec(viewBoxData);
|
||||
if (!m)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the viewBox boundaries
|
||||
viewBox = {
|
||||
left: parseFloat(m[1]),
|
||||
top: parseFloat(m[2]),
|
||||
right: parseFloat(m[1]) + parseFloat(m[3]),
|
||||
bottom: parseFloat(m[2]) + parseFloat(m[4])
|
||||
};
|
||||
|
||||
var path = new SVGO().createContentItem({
|
||||
elem: 'path',
|
||||
prefix: '',
|
||||
local: 'path'
|
||||
});
|
||||
path.addAttr({
|
||||
name: 'd',
|
||||
prefix: '',
|
||||
local: 'd',
|
||||
value: 'M' + m[1] + ' ' + m[2] + 'h' + m[3] + 'v' + m[4] + 'H' + m[1] + 'z'
|
||||
});
|
||||
|
||||
viewBoxJS = path2js(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether given path has a M instruction with coordinates within the viewBox.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function pathMovesWithinViewBox(path)
|
||||
{
|
||||
var regexp = /M\s*(-?\d*\.?\d+)(?!\d)\s*(-?\d*\.?\d+)/g, m;
|
||||
while (null !== (m = regexp.exec(path)))
|
||||
{
|
||||
if (m[1] >= viewBox.left && m[1] <= viewBox.right && m[2] >= viewBox.top && m[2] <= viewBox.bottom)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
28
assets_old/node_modules/svgo/plugins/removeRasterImages.js
generated
vendored
Normal file
28
assets_old/node_modules/svgo/plugins/removeRasterImages.js
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'removes raster images (disabled by default)';
|
||||
|
||||
/**
|
||||
* Remove raster images references in <image>.
|
||||
*
|
||||
* @see https://bugs.webkit.org/show_bug.cgi?id=63548
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (
|
||||
item.isElem('image') &&
|
||||
item.hasAttrLocal('href', /(\.|image\/)(jpg|png|gif)/)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
23
assets_old/node_modules/svgo/plugins/removeScriptElement.js
generated
vendored
Normal file
23
assets_old/node_modules/svgo/plugins/removeScriptElement.js
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'removes <script> elements (disabled by default)';
|
||||
|
||||
/**
|
||||
* Remove <script>.
|
||||
*
|
||||
* https://www.w3.org/TR/SVG/script.html
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Patrick Klingemann
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
return !item.isElem('script');
|
||||
|
||||
};
|
23
assets_old/node_modules/svgo/plugins/removeStyleElement.js
generated
vendored
Normal file
23
assets_old/node_modules/svgo/plugins/removeStyleElement.js
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'removes <style> element (disabled by default)';
|
||||
|
||||
/**
|
||||
* Remove <style>.
|
||||
*
|
||||
* http://www.w3.org/TR/SVG/styling.html#StyleElement
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Betsy Dupuis
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
return !item.isElem('style');
|
||||
|
||||
};
|
23
assets_old/node_modules/svgo/plugins/removeTitle.js
generated
vendored
Normal file
23
assets_old/node_modules/svgo/plugins/removeTitle.js
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes <title>';
|
||||
|
||||
/**
|
||||
* Remove <title>.
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Igor Kalashnikov
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
return !item.isElem('title');
|
||||
|
||||
};
|
150
assets_old/node_modules/svgo/plugins/removeUnknownsAndDefaults.js
generated
vendored
Normal file
150
assets_old/node_modules/svgo/plugins/removeUnknownsAndDefaults.js
generated
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes unknown elements content and attributes, removes attrs with default values';
|
||||
|
||||
exports.params = {
|
||||
unknownContent: true,
|
||||
unknownAttrs: true,
|
||||
defaultAttrs: true,
|
||||
uselessOverrides: true,
|
||||
keepDataAttrs: true,
|
||||
keepAriaAttrs: true,
|
||||
keepRoleAttr: false
|
||||
};
|
||||
|
||||
var collections = require('./_collections'),
|
||||
elems = collections.elems,
|
||||
attrsGroups = collections.attrsGroups,
|
||||
elemsGroups = collections.elemsGroups,
|
||||
attrsGroupsDefaults = collections.attrsGroupsDefaults,
|
||||
attrsInheritable = collections.inheritableAttrs,
|
||||
applyGroups = collections.presentationNonInheritableGroupAttrs;
|
||||
|
||||
// collect and extend all references
|
||||
for (var elem in elems) {
|
||||
elem = elems[elem];
|
||||
|
||||
if (elem.attrsGroups) {
|
||||
elem.attrs = elem.attrs || [];
|
||||
|
||||
elem.attrsGroups.forEach(function(attrsGroupName) {
|
||||
elem.attrs = elem.attrs.concat(attrsGroups[attrsGroupName]);
|
||||
|
||||
var groupDefaults = attrsGroupsDefaults[attrsGroupName];
|
||||
|
||||
if (groupDefaults) {
|
||||
elem.defaults = elem.defaults || {};
|
||||
|
||||
for (var attrName in groupDefaults) {
|
||||
elem.defaults[attrName] = groupDefaults[attrName];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (elem.contentGroups) {
|
||||
elem.content = elem.content || [];
|
||||
|
||||
elem.contentGroups.forEach(function(contentGroupName) {
|
||||
elem.content = elem.content.concat(elemsGroups[contentGroupName]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove unknown elements content and attributes,
|
||||
* remove attributes with default values.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
// elems w/o namespace prefix
|
||||
if (item.isElem() && !item.prefix) {
|
||||
|
||||
var elem = item.elem;
|
||||
|
||||
// remove unknown element's content
|
||||
if (
|
||||
params.unknownContent &&
|
||||
!item.isEmpty() &&
|
||||
elems[elem] && // make sure we know of this element before checking its children
|
||||
elem !== 'foreignObject' // Don't check foreignObject
|
||||
) {
|
||||
item.content.forEach(function(content, i) {
|
||||
if (
|
||||
content.isElem() &&
|
||||
!content.prefix &&
|
||||
(
|
||||
(
|
||||
elems[elem].content && // Do we have a record of its permitted content?
|
||||
elems[elem].content.indexOf(content.elem) === -1
|
||||
) ||
|
||||
(
|
||||
!elems[elem].content && // we dont know about its permitted content
|
||||
!elems[content.elem] // check that we know about the element at all
|
||||
)
|
||||
)
|
||||
) {
|
||||
item.content.splice(i, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// remove element's unknown attrs and attrs with default values
|
||||
if (elems[elem] && elems[elem].attrs) {
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
|
||||
if (
|
||||
attr.name !== 'xmlns' &&
|
||||
(attr.prefix === 'xml' || !attr.prefix) &&
|
||||
(!params.keepDataAttrs || attr.name.indexOf('data-') != 0) &&
|
||||
(!params.keepAriaAttrs || attr.name.indexOf('aria-') != 0) &&
|
||||
(!params.keepRoleAttr || attr.name != 'role')
|
||||
) {
|
||||
if (
|
||||
// unknown attrs
|
||||
(
|
||||
params.unknownAttrs &&
|
||||
elems[elem].attrs.indexOf(attr.name) === -1
|
||||
) ||
|
||||
// attrs with default values
|
||||
(
|
||||
params.defaultAttrs &&
|
||||
!item.hasAttr('id') &&
|
||||
elems[elem].defaults &&
|
||||
elems[elem].defaults[attr.name] === attr.value && (
|
||||
attrsInheritable.indexOf(attr.name) < 0 ||
|
||||
!item.parentNode.computedAttr(attr.name)
|
||||
)
|
||||
) ||
|
||||
// useless overrides
|
||||
(
|
||||
params.uselessOverrides &&
|
||||
!item.hasAttr('id') &&
|
||||
applyGroups.indexOf(attr.name) < 0 &&
|
||||
attrsInheritable.indexOf(attr.name) > -1 &&
|
||||
item.parentNode.computedAttr(attr.name, attr.value)
|
||||
)
|
||||
) {
|
||||
item.removeAttr(attr.name);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
109
assets_old/node_modules/svgo/plugins/removeUnusedNS.js
generated
vendored
Normal file
109
assets_old/node_modules/svgo/plugins/removeUnusedNS.js
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes unused namespaces declaration';
|
||||
|
||||
/**
|
||||
* Remove unused namespaces declaration.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(data) {
|
||||
|
||||
var svgElem,
|
||||
xmlnsCollection = [];
|
||||
|
||||
/**
|
||||
* Remove namespace from collection.
|
||||
*
|
||||
* @param {String} ns namescape name
|
||||
*/
|
||||
function removeNSfromCollection(ns) {
|
||||
|
||||
var pos = xmlnsCollection.indexOf(ns);
|
||||
|
||||
// if found - remove ns from the namespaces collection
|
||||
if (pos > -1) {
|
||||
xmlnsCollection.splice(pos, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Bananas!
|
||||
*
|
||||
* @param {Array} items input items
|
||||
*
|
||||
* @return {Array} output items
|
||||
*/
|
||||
function monkeys(items) {
|
||||
|
||||
var i = 0,
|
||||
length = items.content.length;
|
||||
|
||||
while(i < length) {
|
||||
|
||||
var item = items.content[i];
|
||||
|
||||
if (item.isElem('svg')) {
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
// collect namespaces
|
||||
if (attr.prefix === 'xmlns' && attr.local) {
|
||||
xmlnsCollection.push(attr.local);
|
||||
}
|
||||
});
|
||||
|
||||
// if svg element has ns-attr
|
||||
if (xmlnsCollection.length) {
|
||||
// save svg element
|
||||
svgElem = item;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (xmlnsCollection.length) {
|
||||
|
||||
// check item for the ns-attrs
|
||||
if (item.prefix) {
|
||||
removeNSfromCollection(item.prefix);
|
||||
}
|
||||
|
||||
// check each attr for the ns-attrs
|
||||
item.eachAttr(function(attr) {
|
||||
removeNSfromCollection(attr.prefix);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// if nothing is found - go deeper
|
||||
if (xmlnsCollection.length && item.content) {
|
||||
monkeys(item);
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
return items;
|
||||
|
||||
}
|
||||
|
||||
data = monkeys(data);
|
||||
|
||||
// remove svg element ns-attributes if they are not used even once
|
||||
if (xmlnsCollection.length) {
|
||||
xmlnsCollection.forEach(function(name) {
|
||||
svgElem.removeAttr('xmlns:' + name);
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
};
|
53
assets_old/node_modules/svgo/plugins/removeUselessDefs.js
generated
vendored
Normal file
53
assets_old/node_modules/svgo/plugins/removeUselessDefs.js
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes elements in <defs> without id';
|
||||
|
||||
var nonRendering = require('./_collections').elemsGroups.nonRendering;
|
||||
|
||||
/**
|
||||
* Removes content of defs and properties that aren't rendered directly without ids.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Lev Solntsev
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (item.isElem('defs')) {
|
||||
|
||||
if (item.content) {
|
||||
item.content = getUsefulItems(item, []);
|
||||
}
|
||||
|
||||
if (item.isEmpty()) return false;
|
||||
|
||||
} else if (item.isElem(nonRendering) && !item.hasAttr('id')) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function getUsefulItems(item, usefulItems) {
|
||||
|
||||
item.content.forEach(function(child) {
|
||||
if (child.hasAttr('id') || child.isElem('style')) {
|
||||
|
||||
usefulItems.push(child);
|
||||
child.parentNode = item;
|
||||
|
||||
} else if (!child.isEmpty()) {
|
||||
|
||||
child.content = getUsefulItems(child, usefulItems);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
return usefulItems;
|
||||
}
|
100
assets_old/node_modules/svgo/plugins/removeUselessStrokeAndFill.js
generated
vendored
Normal file
100
assets_old/node_modules/svgo/plugins/removeUselessStrokeAndFill.js
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes useless stroke and fill attributes';
|
||||
|
||||
exports.params = {
|
||||
stroke: true,
|
||||
fill: true,
|
||||
removeNone: false,
|
||||
hasStyleOrScript: false
|
||||
};
|
||||
|
||||
var shape = require('./_collections').elemsGroups.shape,
|
||||
regStrokeProps = /^stroke/,
|
||||
regFillProps = /^fill-/,
|
||||
styleOrScript = ['style', 'script'];
|
||||
|
||||
/**
|
||||
* Remove useless stroke and fill attrs.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
if (item.isElem(styleOrScript)) {
|
||||
params.hasStyleOrScript = true;
|
||||
}
|
||||
|
||||
if (!params.hasStyleOrScript && item.isElem(shape) && !item.computedAttr('id')) {
|
||||
|
||||
var stroke = params.stroke && item.computedAttr('stroke'),
|
||||
fill = params.fill && !item.computedAttr('fill', 'none');
|
||||
|
||||
// remove stroke*
|
||||
if (
|
||||
params.stroke &&
|
||||
(!stroke ||
|
||||
stroke == 'none' ||
|
||||
item.computedAttr('stroke-opacity', '0') ||
|
||||
item.computedAttr('stroke-width', '0')
|
||||
)
|
||||
) {
|
||||
var parentStroke = item.parentNode.computedAttr('stroke'),
|
||||
declineStroke = parentStroke && parentStroke != 'none';
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
if (regStrokeProps.test(attr.name)) {
|
||||
item.removeAttr(attr.name);
|
||||
}
|
||||
});
|
||||
|
||||
if (declineStroke) item.addAttr({
|
||||
name: 'stroke',
|
||||
value: 'none',
|
||||
prefix: '',
|
||||
local: 'stroke'
|
||||
});
|
||||
}
|
||||
|
||||
// remove fill*
|
||||
if (
|
||||
params.fill &&
|
||||
(!fill || item.computedAttr('fill-opacity', '0'))
|
||||
) {
|
||||
item.eachAttr(function(attr) {
|
||||
if (regFillProps.test(attr.name)) {
|
||||
item.removeAttr(attr.name);
|
||||
}
|
||||
});
|
||||
|
||||
if (fill) {
|
||||
if (item.hasAttr('fill'))
|
||||
item.attr('fill').value = 'none';
|
||||
else
|
||||
item.addAttr({
|
||||
name: 'fill',
|
||||
value: 'none',
|
||||
prefix: '',
|
||||
local: 'fill'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (params.removeNone &&
|
||||
(!stroke || item.hasAttr('stroke') && item.attr('stroke').value=='none') &&
|
||||
(!fill || item.hasAttr('fill') && item.attr('fill').value=='none')) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
48
assets_old/node_modules/svgo/plugins/removeViewBox.js
generated
vendored
Normal file
48
assets_old/node_modules/svgo/plugins/removeViewBox.js
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes viewBox attribute when possible';
|
||||
|
||||
var viewBoxElems = ['svg', 'pattern', 'symbol'];
|
||||
|
||||
/**
|
||||
* Remove viewBox attr which coincides with a width/height box.
|
||||
*
|
||||
* @see http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
|
||||
*
|
||||
* @example
|
||||
* <svg width="100" height="50" viewBox="0 0 100 50">
|
||||
* ⬇
|
||||
* <svg width="100" height="50">
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (
|
||||
item.isElem(viewBoxElems) &&
|
||||
item.hasAttr('viewBox') &&
|
||||
item.hasAttr('width') &&
|
||||
item.hasAttr('height')
|
||||
) {
|
||||
|
||||
var nums = item.attr('viewBox').value.split(/[ ,]+/g);
|
||||
|
||||
if (
|
||||
nums[0] === '0' &&
|
||||
nums[1] === '0' &&
|
||||
item.attr('width').value.replace(/px$/, '') === nums[2] && // could use parseFloat too
|
||||
item.attr('height').value.replace(/px$/, '') === nums[3]
|
||||
) {
|
||||
item.removeAttr('viewBox');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
28
assets_old/node_modules/svgo/plugins/removeXMLNS.js
generated
vendored
Normal file
28
assets_old/node_modules/svgo/plugins/removeXMLNS.js
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'removes xmlns attribute (for inline svg, disabled by default)';
|
||||
|
||||
/**
|
||||
* Remove the xmlns attribute when present.
|
||||
*
|
||||
* @example
|
||||
* <svg viewBox="0 0 100 50" xmlns="http://www.w3.org/2000/svg">
|
||||
* ↓
|
||||
* <svg viewBox="0 0 100 50">
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if true, xmlns will be filtered out
|
||||
*
|
||||
* @author Ricardo Tomasi
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (item.isElem('svg') && item.hasAttr('xmlns')) {
|
||||
item.removeAttr('xmlns');
|
||||
}
|
||||
|
||||
};
|
24
assets_old/node_modules/svgo/plugins/removeXMLProcInst.js
generated
vendored
Normal file
24
assets_old/node_modules/svgo/plugins/removeXMLProcInst.js
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes XML processing instructions';
|
||||
|
||||
/**
|
||||
* Remove XML Processing Instruction.
|
||||
*
|
||||
* @example
|
||||
* <?xml version="1.0" encoding="utf-8"?>
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
return !(item.processinginstruction && item.processinginstruction.name === 'xml');
|
||||
|
||||
};
|
168
assets_old/node_modules/svgo/plugins/reusePaths.js
generated
vendored
Normal file
168
assets_old/node_modules/svgo/plugins/reusePaths.js
generated
vendored
Normal file
|
@ -0,0 +1,168 @@
|
|||
/**
|
||||
* @license
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright © 2012–2016 Kir Belevich
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
*
|
||||
* Лицензия MIT
|
||||
*
|
||||
* Copyright © 2012–2016 Кир Белевич
|
||||
*
|
||||
* Данная лицензия разрешает лицам, получившим копию
|
||||
* данного
|
||||
* программного обеспечения и сопутствующей
|
||||
* документации
|
||||
* (в дальнейшем именуемыми «Программное Обеспечение»),
|
||||
* безвозмездно
|
||||
* использовать Программное Обеспечение без
|
||||
* ограничений, включая
|
||||
* неограниченное право на использование, копирование,
|
||||
* изменение,
|
||||
* добавление, публикацию, распространение,
|
||||
* сублицензирование
|
||||
* и/или продажу копий Программного Обеспечения, также
|
||||
* как и лицам,
|
||||
* которым предоставляется данное Программное
|
||||
* Обеспечение,
|
||||
* при соблюдении следующих условий:
|
||||
*
|
||||
* Указанное выше уведомление об авторском праве и
|
||||
* данные условия
|
||||
* должны быть включены во все копии или значимые части
|
||||
* данного
|
||||
* Программного Обеспечения.
|
||||
*
|
||||
* ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК
|
||||
* ЕСТЬ»,
|
||||
* БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ
|
||||
* ПОДРАЗУМЕВАЕМЫХ,
|
||||
* ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ
|
||||
* ПРИГОДНОСТИ,
|
||||
* СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И
|
||||
* ОТСУТСТВИЯ НАРУШЕНИЙ
|
||||
* ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ
|
||||
* НЕСУТ
|
||||
* ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ
|
||||
* ИЛИ ДРУГИХ
|
||||
* ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ
|
||||
* ИНОМУ,
|
||||
* ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ С
|
||||
* ПРОГРАММНЫМ
|
||||
* ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО
|
||||
* ОБЕСПЕЧЕНИЯ
|
||||
* ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var JSAPI = require('../lib/svgo/jsAPI');
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'Finds <path> elements with the same d, fill, and ' +
|
||||
'stroke, and converts them to <use> elements ' +
|
||||
'referencing a single <path> def.';
|
||||
|
||||
/**
|
||||
* Finds <path> elements with the same d, fill, and stroke, and converts them to
|
||||
* <use> elements referencing a single <path> def.
|
||||
*
|
||||
* @author Jacob Howcroft
|
||||
*/
|
||||
exports.fn = function(data) {
|
||||
const seen = new Map();
|
||||
let count = 0;
|
||||
const defs = [];
|
||||
traverse(data, item => {
|
||||
if (!item.isElem('path') || !item.hasAttr('d')) {
|
||||
return;
|
||||
}
|
||||
const d = item.attr('d').value;
|
||||
const fill = (item.hasAttr('fill') && item.attr('fill').value) || '';
|
||||
const stroke = (item.hasAttr('stroke') && item.attr('stroke').value) || '';
|
||||
const key = d + ';s:' + stroke + ';f:' + fill;
|
||||
const hasSeen = seen.get(key);
|
||||
if (!hasSeen) {
|
||||
seen.set(key, {elem: item, reused: false});
|
||||
return;
|
||||
}
|
||||
if (!hasSeen.reused) {
|
||||
hasSeen.reused = true;
|
||||
if (!hasSeen.elem.hasAttr('id')) {
|
||||
hasSeen.elem.addAttr({name: 'id', local: 'id',
|
||||
prefix: '', value: 'reuse-' + (count++)});
|
||||
}
|
||||
defs.push(hasSeen.elem);
|
||||
}
|
||||
item = convertToUse(item, hasSeen.elem.attr('id').value);
|
||||
});
|
||||
const defsTag = new JSAPI({
|
||||
elem: 'defs', prefix: '', local: 'defs', content: [], attrs: []}, data);
|
||||
data.content[0].spliceContent(0, 0, defsTag);
|
||||
for (let def of defs) {
|
||||
// Remove class and style before copying to avoid circular refs in
|
||||
// JSON.stringify. This is fine because we don't actually want class or
|
||||
// style information to be copied.
|
||||
const style = def.style;
|
||||
const defClass = def.class;
|
||||
delete def.style;
|
||||
delete def.class;
|
||||
const defClone = def.clone();
|
||||
def.style = style;
|
||||
def.class = defClass;
|
||||
defClone.removeAttr('transform');
|
||||
defsTag.spliceContent(0, 0, defClone);
|
||||
// Convert the original def to a use so the first usage isn't duplicated.
|
||||
def = convertToUse(def, defClone.attr('id').value);
|
||||
def.removeAttr('id');
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
/** */
|
||||
function convertToUse(item, href) {
|
||||
item.renameElem('use');
|
||||
item.removeAttr('d');
|
||||
item.removeAttr('stroke');
|
||||
item.removeAttr('fill');
|
||||
item.addAttr({name: 'xlink:href', local: 'xlink:href',
|
||||
prefix: 'none', value: '#' + href});
|
||||
delete item.pathJS;
|
||||
return item;
|
||||
}
|
||||
|
||||
/** */
|
||||
function traverse(parent, callback) {
|
||||
if (parent.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (let child of parent.content) {
|
||||
callback(child);
|
||||
traverse(child, callback);
|
||||
}
|
||||
}
|
84
assets_old/node_modules/svgo/plugins/sortAttrs.js
generated
vendored
Normal file
84
assets_old/node_modules/svgo/plugins/sortAttrs.js
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'sorts element attributes (disabled by default)';
|
||||
|
||||
exports.params = {
|
||||
order: [
|
||||
'id',
|
||||
'width', 'height',
|
||||
'x', 'x1', 'x2',
|
||||
'y', 'y1', 'y2',
|
||||
'cx', 'cy', 'r',
|
||||
'fill', 'stroke', 'marker',
|
||||
'd', 'points'
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Sort element attributes for epic readability.
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @param {Object} params plugin params
|
||||
*
|
||||
* @author Nikolay Frantsev
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
var attrs = [],
|
||||
sorted = {},
|
||||
orderlen = params.order.length + 1,
|
||||
xmlnsOrder = params.xmlnsOrder || 'front';
|
||||
|
||||
if (item.elem) {
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
attrs.push(attr);
|
||||
});
|
||||
|
||||
attrs.sort(function(a, b) {
|
||||
if (a.prefix != b.prefix) {
|
||||
// xmlns attributes implicitly have the prefix xmlns
|
||||
if (xmlnsOrder == 'front') {
|
||||
if (a.prefix == 'xmlns')
|
||||
return -1;
|
||||
if (b.prefix == 'xmlns')
|
||||
return 1;
|
||||
}
|
||||
return a.prefix < b.prefix ? -1 : 1;
|
||||
}
|
||||
|
||||
var aindex = orderlen;
|
||||
var bindex = orderlen;
|
||||
|
||||
for (var i = 0; i < params.order.length; i++) {
|
||||
if (a.name == params.order[i]) {
|
||||
aindex = i;
|
||||
} else if (a.name.indexOf(params.order[i] + '-') === 0) {
|
||||
aindex = i + .5;
|
||||
}
|
||||
if (b.name == params.order[i]) {
|
||||
bindex = i;
|
||||
} else if (b.name.indexOf(params.order[i] + '-') === 0) {
|
||||
bindex = i + .5;
|
||||
}
|
||||
}
|
||||
|
||||
if (aindex != bindex) {
|
||||
return aindex - bindex;
|
||||
}
|
||||
return a.name < b.name ? -1 : 1;
|
||||
});
|
||||
|
||||
attrs.forEach(function (attr) {
|
||||
sorted[attr.name] = attr;
|
||||
});
|
||||
|
||||
item.attrs = sorted;
|
||||
|
||||
}
|
||||
|
||||
};
|
47
assets_old/node_modules/svgo/plugins/sortDefsChildren.js
generated
vendored
Normal file
47
assets_old/node_modules/svgo/plugins/sortDefsChildren.js
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'Sorts children of <defs> to improve compression';
|
||||
|
||||
/**
|
||||
* Sorts children of defs in order to improve compression.
|
||||
* Sorted first by frequency then by element name length then by element name (to ensure grouping).
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
*
|
||||
* @author David Leston
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
|
||||
if (item.isElem('defs')) {
|
||||
|
||||
if (item.content) {
|
||||
var frequency = item.content.reduce(function (frequency, child) {
|
||||
if (child.elem in frequency) {
|
||||
frequency[child.elem]++;
|
||||
} else {
|
||||
frequency[child.elem] = 1;
|
||||
}
|
||||
return frequency;
|
||||
}, {});
|
||||
item.content.sort(function (a, b) {
|
||||
var frequencyComparison = frequency[b.elem] - frequency[a.elem];
|
||||
if (frequencyComparison !== 0 ) {
|
||||
return frequencyComparison;
|
||||
}
|
||||
var lengthComparison = b.elem.length - a.elem.length;
|
||||
if (lengthComparison !== 0) {
|
||||
return lengthComparison;
|
||||
}
|
||||
return a.elem != b.elem ? a.elem > b.elem ? -1 : 1 : 0;
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue