svger-cli 3.1.1 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +369 -0
- package/README.md +432 -25
- package/SECURITY.md +3 -3
- package/assets/svges/500px.svg +3 -0
- package/assets/svges/adobe.svg +3 -0
- package/assets/svges/adonis.svg +3 -0
- package/assets/svges/aeroplane-1.svg +3 -0
- package/assets/svges/agenda.svg +3 -0
- package/assets/svges/airbnb.svg +3 -0
- package/assets/svges/airtable.svg +3 -0
- package/assets/svges/alarm-1.svg +7 -0
- package/assets/svges/align-text-center.svg +6 -0
- package/assets/svges/align-text-left.svg +6 -0
- package/assets/svges/align-text-right.svg +6 -0
- package/assets/svges/alpinejs.svg +4 -0
- package/assets/svges/amazon-original.svg +5 -0
- package/assets/svges/amazon-pay.svg +7 -0
- package/assets/svges/amazon.svg +10 -0
- package/assets/svges/ambulance-1.svg +4 -0
- package/assets/svges/amd.svg +3 -0
- package/assets/svges/amex.svg +4 -0
- package/assets/svges/anchor.svg +3 -0
- package/assets/svges/android-old.svg +3 -0
- package/assets/svges/android.svg +3 -0
- package/assets/svges/angellist.svg +3 -0
- package/assets/svges/angle-double-down.svg +4 -0
- package/assets/svges/angle-double-left.svg +4 -0
- package/assets/svges/angle-double-right.svg +4 -0
- package/assets/svges/angle-double-up.svg +4 -0
- package/assets/svges/angular.svg +3 -0
- package/assets/svges/app-store.svg +3 -0
- package/assets/svges/apple-brand.svg +3 -0
- package/assets/svges/apple-music-alt.svg +3 -0
- package/assets/svges/apple-music.svg +3 -0
- package/assets/svges/apple-pay.svg +3 -0
- package/assets/svges/arc-browser.svg +6 -0
- package/assets/svges/arrow-all-direction.svg +6 -0
- package/assets/svges/arrow-angular-top-left.svg +3 -0
- package/assets/svges/arrow-angular-top-right.svg +3 -0
- package/assets/svges/arrow-both-direction-horizontal-1.svg +3 -0
- package/assets/svges/arrow-both-direction-vertical-1.svg +3 -0
- package/assets/svges/arrow-downward.svg +3 -0
- package/assets/svges/arrow-left-circle.svg +4 -0
- package/assets/svges/arrow-left.svg +3 -0
- package/assets/svges/arrow-right-circle.svg +4 -0
- package/assets/svges/arrow-right.svg +3 -0
- package/assets/svges/arrow-upward.svg +3 -0
- package/assets/svges/asana.svg +3 -0
- package/assets/svges/astro.svg +4 -0
- package/assets/svges/atlassian.svg +3 -0
- package/assets/svges/audi-alt.svg +3 -0
- package/assets/svges/audi.svg +3 -0
- package/assets/svges/aws.svg +3 -0
- package/assets/svges/azure.svg +3 -0
- package/assets/svges/badge-decagram-percent.svg +6 -0
- package/assets/svges/balloons.svg +3 -0
- package/assets/svges/ban-2.svg +3 -0
- package/assets/svges/bar-chart-4.svg +6 -0
- package/assets/svges/bar-chart-dollar.svg +6 -0
- package/assets/svges/basket-shopping-3.svg +5 -0
- package/assets/svges/beat.svg +3 -0
- package/assets/svges/behance.svg +5 -0
- package/assets/svges/bell-1.svg +3 -0
- package/assets/svges/bike.svg +6 -0
- package/assets/svges/bing.svg +5 -0
- package/assets/svges/bitbucket.svg +5 -0
- package/assets/svges/bitcoin.svg +5 -0
- package/assets/svges/bittorrent.svg +6 -0
- package/assets/svges/blogger-alt.svg +3 -0
- package/assets/svges/blogger.svg +3 -0
- package/assets/svges/bluetooth-logo.svg +3 -0
- package/assets/svges/bluetooth.svg +3 -0
- package/assets/svges/bmw.svg +7 -0
- package/assets/svges/board-writing-3.svg +3 -0
- package/assets/svges/bold.svg +3 -0
- package/assets/svges/bolt-2.svg +3 -0
- package/assets/svges/bolt-3.svg +3 -0
- package/assets/svges/book-1.svg +4 -0
- package/assets/svges/bookmark-1.svg +3 -0
- package/assets/svges/bookmark-circle.svg +4 -0
- package/assets/svges/books-2.svg +3 -0
- package/assets/svges/bootstrap-5-square.svg +3 -0
- package/assets/svges/bootstrap-5.svg +3 -0
- package/assets/svges/box-archive-1.svg +4 -0
- package/assets/svges/box-closed.svg +3 -0
- package/assets/svges/box-gift-1.svg +3 -0
- package/assets/svges/brave.svg +3 -0
- package/assets/svges/bricks.svg +3 -0
- package/assets/svges/bridge-3.svg +3 -0
- package/assets/svges/briefcase-1.svg +3 -0
- package/assets/svges/briefcase-2.svg +3 -0
- package/assets/svges/briefcase-plus-1.svg +4 -0
- package/assets/svges/brush-1-rotated.svg +3 -0
- package/assets/svges/brush-2.svg +3 -0
- package/assets/svges/btc.svg +3 -0
- package/assets/svges/bug-1.svg +3 -0
- package/assets/svges/buildings-1.svg +5 -0
- package/assets/svges/bulb-2.svg +3 -0
- package/assets/svges/bulb-4.svg +9 -0
- package/assets/svges/burger-1.svg +3 -0
- package/assets/svges/burger-drink.svg +4 -0
- package/assets/svges/bus-1.svg +5 -0
- package/assets/svges/busket-ball.svg +3 -0
- package/assets/svges/cake-1.svg +3 -0
- package/assets/svges/calculator-1.svg +8 -0
- package/assets/svges/calculator-2.svg +13 -0
- package/assets/svges/calendar-days.svg +9 -0
- package/assets/svges/camera-1.svg +4 -0
- package/assets/svges/camera-movie-1.svg +3 -0
- package/assets/svges/candy-cane-2.svg +3 -0
- package/assets/svges/candy-round-1.svg +3 -0
- package/assets/svges/canva.svg +3 -0
- package/assets/svges/capsule-1.svg +3 -0
- package/assets/svges/car-2.svg +5 -0
- package/assets/svges/car-4.svg +3 -0
- package/assets/svges/car-6.svg +5 -0
- package/assets/svges/caravan-1.svg +3 -0
- package/assets/svges/cart-1.svg +5 -0
- package/assets/svges/cart-2.svg +5 -0
- package/assets/svges/cash-app.svg +3 -0
- package/assets/svges/certificate-badge-1.svg +6 -0
- package/assets/svges/chat-bubble-2.svg +5 -0
- package/assets/svges/check-circle-1.svg +4 -0
- package/assets/svges/check-square-2.svg +4 -0
- package/assets/svges/check.svg +3 -0
- package/assets/svges/chevron-down-circle.svg +4 -0
- package/assets/svges/chevron-down.svg +3 -0
- package/assets/svges/chevron-left-circle.svg +4 -0
- package/assets/svges/chevron-left.svg +3 -0
- package/assets/svges/chevron-right-circle.svg +4 -0
- package/assets/svges/chevron-up-circle.svg +4 -0
- package/assets/svges/chevron-up.svg +3 -0
- package/assets/svges/chrome.svg +6 -0
- package/assets/svges/chromecast.svg +3 -0
- package/assets/svges/cisco.svg +3 -0
- package/assets/svges/claude.svg +3 -0
- package/assets/svges/clickup.svg +4 -0
- package/assets/svges/clipboard.svg +3 -0
- package/assets/svges/cloud-2.svg +3 -0
- package/assets/svges/cloud-bolt-1.svg +4 -0
- package/assets/svges/cloud-bolt-2.svg +4 -0
- package/assets/svges/cloud-check-circle.svg +5 -0
- package/assets/svges/cloud-download.svg +5 -0
- package/assets/svges/cloud-iot-2.svg +3 -0
- package/assets/svges/cloud-rain.svg +6 -0
- package/assets/svges/cloud-refresh-clockwise.svg +5 -0
- package/assets/svges/cloud-sun.svg +9 -0
- package/assets/svges/cloud-upload.svg +5 -0
- package/assets/svges/cloudflare.svg +3 -0
- package/assets/svges/code-1.svg +5 -0
- package/assets/svges/code-s.svg +5 -0
- package/assets/svges/codepen.svg +3 -0
- package/assets/svges/coffee-cup-2.svg +6 -0
- package/assets/svges/coinbase.svg +10 -0
- package/assets/svges/colour-palette-3.svg +7 -0
- package/assets/svges/comment-1-share.svg +4 -0
- package/assets/svges/comment-1-text.svg +5 -0
- package/assets/svges/comment-1.svg +3 -0
- package/assets/svges/compass-drafting-2.svg +3 -0
- package/assets/svges/connectdevelop.svg +3 -0
- package/assets/svges/copilot.svg +8 -0
- package/assets/svges/coral.svg +3 -0
- package/assets/svges/cpanel.svg +3 -0
- package/assets/svges/crane-4.svg +3 -0
- package/assets/svges/creative-commons.svg +4 -0
- package/assets/svges/credit-card-multiple.svg +3 -0
- package/assets/svges/crop-2.svg +3 -0
- package/assets/svges/crown-3.svg +3 -0
- package/assets/svges/css3.svg +3 -0
- package/assets/svges/dashboard-square-1.svg +6 -0
- package/assets/svges/database-2.svg +3 -0
- package/assets/svges/deno.svg +4 -0
- package/assets/svges/dev.svg +3 -0
- package/assets/svges/dialogflow.svg +4 -0
- package/assets/svges/diamonds-1.svg +3 -0
- package/assets/svges/diamonds-2.svg +3 -0
- package/assets/svges/digitalocean.svg +3 -0
- package/assets/svges/diners-club.svg +38 -0
- package/assets/svges/direction-ltr.svg +4 -0
- package/assets/svges/direction-rtl.svg +4 -0
- package/assets/svges/discord-chat.svg +5 -0
- package/assets/svges/discord.svg +3 -0
- package/assets/svges/discover.svg +3 -0
- package/assets/svges/docker.svg +3 -0
- package/assets/svges/dollar-circle.svg +4 -0
- package/assets/svges/dollar.svg +3 -0
- package/assets/svges/double-quotes-end-1.svg +4 -0
- package/assets/svges/download-1.svg +4 -0
- package/assets/svges/download-circle-1.svg +4 -0
- package/assets/svges/dribbble-symbol.svg +3 -0
- package/assets/svges/dribbble.svg +3 -0
- package/assets/svges/drizzle.svg +6 -0
- package/assets/svges/dropbox.svg +7 -0
- package/assets/svges/drupal.svg +3 -0
- package/assets/svges/dumbbell-1.svg +3 -0
- package/assets/svges/edge.svg +3 -0
- package/assets/svges/emoji-expressionless-flat-eyes.svg +6 -0
- package/assets/svges/emoji-expressionless.svg +6 -0
- package/assets/svges/emoji-grin.svg +6 -0
- package/assets/svges/emoji-sad.svg +6 -0
- package/assets/svges/emoji-smile-side.svg +6 -0
- package/assets/svges/emoji-smile-sunglass.svg +5 -0
- package/assets/svges/emoji-smile-tongue.svg +3 -0
- package/assets/svges/emoji-smile.svg +6 -0
- package/assets/svges/enter-down.svg +4 -0
- package/assets/svges/enter.svg +4 -0
- package/assets/svges/envato.svg +4 -0
- package/assets/svges/envelope-1.svg +3 -0
- package/assets/svges/eraser-1.svg +4 -0
- package/assets/svges/ethereum-logo.svg +4 -0
- package/assets/svges/euro.svg +3 -0
- package/assets/svges/exit-up.svg +4 -0
- package/assets/svges/exit.svg +4 -0
- package/assets/svges/expand-arrow-1.svg +3 -0
- package/assets/svges/expand-square-4.svg +6 -0
- package/assets/svges/expressjs.svg +4 -0
- package/assets/svges/eye.svg +4 -0
- package/assets/svges/facebook-messenger.svg +3 -0
- package/assets/svges/facebook-rounded.svg +4 -0
- package/assets/svges/facebook-square.svg +3 -0
- package/assets/svges/facebook.svg +3 -0
- package/assets/svges/facetime.svg +3 -0
- package/assets/svges/figma.svg +3 -0
- package/assets/svges/file-format-zip.svg +4 -0
- package/assets/svges/file-multiple.svg +4 -0
- package/assets/svges/file-pencil.svg +4 -0
- package/assets/svges/file-plus-circle.svg +5 -0
- package/assets/svges/file-question.svg +5 -0
- package/assets/svges/file-xmark.svg +4 -0
- package/assets/svges/firebase.svg +3 -0
- package/assets/svges/firefox.svg +3 -0
- package/assets/svges/firework-rocket-4.svg +3 -0
- package/assets/svges/fitbit.svg +3 -0
- package/assets/svges/flag-1.svg +3 -0
- package/assets/svges/flag-2.svg +3 -0
- package/assets/svges/flickr.svg +4 -0
- package/assets/svges/floppy-disk-1.svg +3 -0
- package/assets/svges/flower-2.svg +3 -0
- package/assets/svges/flutter.svg +3 -0
- package/assets/svges/folder-1.svg +3 -0
- package/assets/svges/ford.svg +3 -0
- package/assets/svges/framer.svg +3 -0
- package/assets/svges/funnel-1.svg +3 -0
- package/assets/svges/gallery.svg +4 -0
- package/assets/svges/game-pad-modern-1.svg +6 -0
- package/assets/svges/gatsby.svg +3 -0
- package/assets/svges/gauge-1.svg +5 -0
- package/assets/svges/gear-1.svg +4 -0
- package/assets/svges/gears-3.svg +6 -0
- package/assets/svges/gemini.svg +3 -0
- package/assets/svges/git.svg +3 -0
- package/assets/svges/github.svg +3 -0
- package/assets/svges/glass-juice-1.svg +3 -0
- package/assets/svges/globe-1.svg +3 -0
- package/assets/svges/globe-stand.svg +4 -0
- package/assets/svges/go.svg +7 -0
- package/assets/svges/goodreads.svg +3 -0
- package/assets/svges/google-cloud.svg +3 -0
- package/assets/svges/google-drive.svg +3 -0
- package/assets/svges/google-meet.svg +3 -0
- package/assets/svges/google-pay.svg +3 -0
- package/assets/svges/google-wallet.svg +3 -0
- package/assets/svges/google.svg +3 -0
- package/assets/svges/graduation-cap-1.svg +3 -0
- package/assets/svges/grammarly.svg +3 -0
- package/assets/svges/hacker-news.svg +3 -0
- package/assets/svges/hammer-1.svg +3 -0
- package/assets/svges/hammer-2.svg +3 -0
- package/assets/svges/hand-mic.svg +3 -0
- package/assets/svges/hand-shake.svg +3 -0
- package/assets/svges/hand-stop.svg +3 -0
- package/assets/svges/hand-taking-dollar.svg +4 -0
- package/assets/svges/hand-taking-leaf-1.svg +5 -0
- package/assets/svges/hand-taking-user.svg +5 -0
- package/assets/svges/hashnode.svg +3 -0
- package/assets/svges/hat-chef-3.svg +3 -0
- package/assets/svges/headphone-1.svg +3 -0
- package/assets/svges/heart.svg +3 -0
- package/assets/svges/helicopter-2.svg +4 -0
- package/assets/svges/helmet-safety-1.svg +3 -0
- package/assets/svges/hierarchy-1.svg +9 -0
- package/assets/svges/highlighter-1.svg +3 -0
- package/assets/svges/highlighter-2.svg +3 -0
- package/assets/svges/home-2.svg +3 -0
- package/assets/svges/hospital-2.svg +4 -0
- package/assets/svges/hourglass.svg +3 -0
- package/assets/svges/html5.svg +4 -0
- package/assets/svges/ibm.svg +3 -0
- package/assets/svges/id-card.svg +7 -0
- package/assets/svges/imdb.svg +7 -0
- package/assets/svges/indent.svg +8 -0
- package/assets/svges/info.svg +4 -0
- package/assets/svges/injection-1.svg +3 -0
- package/assets/svges/instagram-logotype.svg +3 -0
- package/assets/svges/instagram.svg +4 -0
- package/assets/svges/intel.svg +4 -0
- package/assets/svges/ios.svg +3 -0
- package/assets/svges/island-2.svg +4 -0
- package/assets/svges/jaguar.svg +3 -0
- package/assets/svges/jamstack.svg +3 -0
- package/assets/svges/java.svg +3 -0
- package/assets/svges/javascript.svg +3 -0
- package/assets/svges/jcb.svg +3 -0
- package/assets/svges/joomla.svg +6 -0
- package/assets/svges/jsfiddle.svg +4 -0
- package/assets/svges/key-1.svg +3 -0
- package/assets/svges/keyboard.svg +12 -0
- package/assets/svges/knife-fork-1.svg +5 -0
- package/assets/svges/kubernetes.svg +11 -0
- package/assets/svges/label-dollar-2.svg +4 -0
- package/assets/svges/laptop-2.svg +3 -0
- package/assets/svges/laptop-phone.svg +5 -0
- package/assets/svges/laravel.svg +3 -0
- package/assets/svges/layers-1.svg +4 -0
- package/assets/svges/layout-26.svg +3 -0
- package/assets/svges/layout-9.svg +3 -0
- package/assets/svges/leaf-1.svg +3 -0
- package/assets/svges/leaf-6.svg +4 -0
- package/assets/svges/lemon-squeezy.svg +6 -0
- package/assets/svges/life-guard-tube-1.svg +3 -0
- package/assets/svges/line-dashed.svg +5 -0
- package/assets/svges/line-dotted.svg +8 -0
- package/assets/svges/line-height.svg +7 -0
- package/assets/svges/line.svg +3 -0
- package/assets/svges/lineicons.svg +6 -0
- package/assets/svges/link-2-angular-right.svg +3 -0
- package/assets/svges/linkedin.svg +3 -0
- package/assets/svges/location-arrow-right.svg +3 -0
- package/assets/svges/locked-1.svg +4 -0
- package/assets/svges/locked-2.svg +4 -0
- package/assets/svges/loom.svg +3 -0
- package/assets/svges/magento.svg +4 -0
- package/assets/svges/magnet.svg +3 -0
- package/assets/svges/mailchimp.svg +3 -0
- package/assets/svges/map-marker-1.svg +6 -0
- package/assets/svges/map-marker-5.svg +4 -0
- package/assets/svges/map-pin-5.svg +3 -0
- package/assets/svges/markdown.svg +5 -0
- package/assets/svges/mastercard.svg +7 -0
- package/assets/svges/medium-alt.svg +3 -0
- package/assets/svges/medium.svg +3 -0
- package/assets/svges/megaphone-1.svg +3 -0
- package/assets/svges/menu-cheesburger.svg +8 -0
- package/assets/svges/menu-hamburger-1.svg +5 -0
- package/assets/svges/menu-meatballs-1.svg +5 -0
- package/assets/svges/menu-meatballs-2.svg +5 -0
- package/assets/svges/mercedes.svg +3 -0
- package/assets/svges/message-2-question.svg +5 -0
- package/assets/svges/message-2.svg +3 -0
- package/assets/svges/message-3-text.svg +5 -0
- package/assets/svges/meta-alt.svg +3 -0
- package/assets/svges/meta.svg +7 -0
- package/assets/svges/microphone-1.svg +4 -0
- package/assets/svges/microscope.svg +3 -0
- package/assets/svges/microsoft-edge.svg +5 -0
- package/assets/svges/microsoft-teams.svg +6 -0
- package/assets/svges/microsoft.svg +6 -0
- package/assets/svges/minus-circle.svg +4 -0
- package/assets/svges/minus.svg +3 -0
- package/assets/svges/mongodb.svg +3 -0
- package/assets/svges/monitor-code.svg +5 -0
- package/assets/svges/monitor-mac.svg +3 -0
- package/assets/svges/monitor.svg +3 -0
- package/assets/svges/moon-half-right-5.svg +3 -0
- package/assets/svges/mountains-2.svg +3 -0
- package/assets/svges/mouse-2.svg +3 -0
- package/assets/svges/mushroom-1.svg +3 -0
- package/assets/svges/mushroom-5.svg +6 -0
- package/assets/svges/music.svg +3 -0
- package/assets/svges/mysql.svg +3 -0
- package/assets/svges/nasa.svg +3 -0
- package/assets/svges/netflix.svg +3 -0
- package/assets/svges/netlify.svg +3 -0
- package/assets/svges/next-step-2.svg +3 -0
- package/assets/svges/nextjs.svg +3 -0
- package/assets/svges/nike.svg +3 -0
- package/assets/svges/nissan.svg +3 -0
- package/assets/svges/nodejs-alt.svg +3 -0
- package/assets/svges/nodejs.svg +3 -0
- package/assets/svges/notebook-1.svg +3 -0
- package/assets/svges/notion.svg +3 -0
- package/assets/svges/npm.svg +3 -0
- package/assets/svges/nuxt.svg +3 -0
- package/assets/svges/nvidia.svg +3 -0
- package/assets/svges/oculus.svg +4 -0
- package/assets/svges/open-ai.svg +3 -0
- package/assets/svges/opera-mini.svg +3 -0
- package/assets/svges/oracle.svg +3 -0
- package/assets/svges/outdent.svg +8 -0
- package/assets/svges/paddle.svg +3 -0
- package/assets/svges/page-break-1.svg +7 -0
- package/assets/svges/pagination.svg +7 -0
- package/assets/svges/paint-bucket.svg +3 -0
- package/assets/svges/paint-roller-1.svg +3 -0
- package/assets/svges/paperclip-1.svg +3 -0
- package/assets/svges/party-flags.svg +3 -0
- package/assets/svges/party-spray.svg +3 -0
- package/assets/svges/patreon.svg +3 -0
- package/assets/svges/pause.svg +4 -0
- package/assets/svges/payoneer.svg +4 -0
- package/assets/svges/paypal.svg +4 -0
- package/assets/svges/pen-to-square.svg +4 -0
- package/assets/svges/pencil-1.svg +3 -0
- package/assets/svges/pepsi.svg +4 -0
- package/assets/svges/phone.svg +4 -0
- package/assets/svges/photos.svg +4 -0
- package/assets/svges/php.svg +3 -0
- package/assets/svges/pie-chart-2.svg +3 -0
- package/assets/svges/pilcrow.svg +3 -0
- package/assets/svges/pimjo-logo.svg +9 -0
- package/assets/svges/pimjo-symbol.svg +3 -0
- package/assets/svges/pinterest.svg +3 -0
- package/assets/svges/pizza-2.svg +6 -0
- package/assets/svges/placeholder-dollar.svg +4 -0
- package/assets/svges/plantscale.svg +3 -0
- package/assets/svges/play-store.svg +3 -0
- package/assets/svges/play.svg +3 -0
- package/assets/svges/playstation.svg +5 -0
- package/assets/svges/plug-1.svg +3 -0
- package/assets/svges/plus-circle.svg +4 -0
- package/assets/svges/plus.svg +3 -0
- package/assets/svges/pnpm.svg +10 -0
- package/assets/svges/postgresql.svg +3 -0
- package/assets/svges/postman.svg +3 -0
- package/assets/svges/pound.svg +3 -0
- package/assets/svges/power-button.svg +4 -0
- package/assets/svges/previous-step-2.svg +3 -0
- package/assets/svges/printer.svg +3 -0
- package/assets/svges/prisma.svg +3 -0
- package/assets/svges/producthunt.svg +4 -0
- package/assets/svges/proton-mail-logo.svg +3 -0
- package/assets/svges/proton-mail-symbol.svg +3 -0
- package/assets/svges/python.svg +3 -0
- package/assets/svges/question-mark-circle.svg +5 -0
- package/assets/svges/question-mark.svg +4 -0
- package/assets/svges/quora.svg +4 -0
- package/assets/svges/radis.svg +3 -0
- package/assets/svges/react.svg +3 -0
- package/assets/svges/reddit.svg +6 -0
- package/assets/svges/refresh-circle-1-clockwise.svg +4 -0
- package/assets/svges/refresh-dollar-1.svg +5 -0
- package/assets/svges/refresh-user-1.svg +6 -0
- package/assets/svges/remix-js.svg +4 -0
- package/assets/svges/road-1.svg +6 -0
- package/assets/svges/rocket-5.svg +5 -0
- package/assets/svges/route-1.svg +7 -0
- package/assets/svges/rss-right.svg +6 -0
- package/assets/svges/ruler-1.svg +3 -0
- package/assets/svges/ruler-pen.svg +4 -0
- package/assets/svges/rupee.svg +3 -0
- package/assets/svges/safari.svg +35 -0
- package/assets/svges/sanity.svg +20 -0
- package/assets/svges/school-bench-1.svg +4 -0
- package/assets/svges/school-bench-2.svg +4 -0
- package/assets/svges/scissors-1-vertical.svg +4 -0
- package/assets/svges/scoter.svg +8 -0
- package/assets/svges/scroll-down-2.svg +6 -0
- package/assets/svges/search-1.svg +3 -0
- package/assets/svges/search-2.svg +4 -0
- package/assets/svges/search-minus.svg +4 -0
- package/assets/svges/search-plus.svg +4 -0
- package/assets/svges/search-text.svg +5 -0
- package/assets/svges/select-cursor-1.svg +10 -0
- package/assets/svges/seo-monitor.svg +6 -0
- package/assets/svges/service-bell-1.svg +3 -0
- package/assets/svges/share-1-circle.svg +4 -0
- package/assets/svges/share-1.svg +3 -0
- package/assets/svges/share-2.svg +4 -0
- package/assets/svges/shield-2-check.svg +4 -0
- package/assets/svges/shield-2.svg +3 -0
- package/assets/svges/shield-dollar.svg +4 -0
- package/assets/svges/shift-left.svg +4 -0
- package/assets/svges/shift-right.svg +4 -0
- package/assets/svges/ship-1.svg +5 -0
- package/assets/svges/shirt-1.svg +3 -0
- package/assets/svges/shopify.svg +3 -0
- package/assets/svges/shovel.svg +3 -0
- package/assets/svges/shuffle.svg +3 -0
- package/assets/svges/sign-post-left.svg +3 -0
- package/assets/svges/signal-app.svg +3 -0
- package/assets/svges/signs-post-2.svg +3 -0
- package/assets/svges/sketch.svg +3 -0
- package/assets/svges/skype.svg +3 -0
- package/assets/svges/slack.svg +10 -0
- package/assets/svges/slice-2.svg +3 -0
- package/assets/svges/sliders-horizontal-square-2.svg +7 -0
- package/assets/svges/slideshare.svg +5 -0
- package/assets/svges/snapchat.svg +3 -0
- package/assets/svges/sort-alphabetical.svg +5 -0
- package/assets/svges/sort-high-to-low.svg +7 -0
- package/assets/svges/soundcloud.svg +3 -0
- package/assets/svges/spacex.svg +4 -0
- package/assets/svges/spellcheck.svg +4 -0
- package/assets/svges/spinner-2-sacle.svg +10 -0
- package/assets/svges/spinner-3.svg +3 -0
- package/assets/svges/sports.svg +3 -0
- package/assets/svges/spotify-alt.svg +6 -0
- package/assets/svges/spotify.svg +3 -0
- package/assets/svges/squarespace.svg +3 -0
- package/assets/svges/stackoverflow.svg +8 -0
- package/assets/svges/stamp.svg +3 -0
- package/assets/svges/star-fat-half-2.svg +4 -0
- package/assets/svges/star-fat.svg +3 -0
- package/assets/svges/star-sharp-disabled.svg +4 -0
- package/assets/svges/statista.svg +3 -0
- package/assets/svges/steam.svg +5 -0
- package/assets/svges/stethoscope-1.svg +3 -0
- package/assets/svges/stopwatch.svg +5 -0
- package/assets/svges/storage-hdd-2.svg +4 -0
- package/assets/svges/strikethrough-1.svg +5 -0
- package/assets/svges/stripe.svg +9 -0
- package/assets/svges/stumbleupon.svg +3 -0
- package/assets/svges/sun-1.svg +11 -0
- package/assets/svges/supabase.svg +5 -0
- package/assets/svges/surfboard-2.svg +3 -0
- package/assets/svges/svelte.svg +3 -0
- package/assets/svges/swift.svg +3 -0
- package/assets/svges/tab.svg +4 -0
- package/assets/svges/tailwindcss.svg +3 -0
- package/assets/svges/target-user.svg +5 -0
- package/assets/svges/telegram.svg +3 -0
- package/assets/svges/telephone-1.svg +4 -0
- package/assets/svges/telephone-3.svg +5 -0
- package/assets/svges/tesla.svg +3 -0
- package/assets/svges/text-format-remove.svg +5 -0
- package/assets/svges/text-format.svg +5 -0
- package/assets/svges/text-paragraph.svg +6 -0
- package/assets/svges/thumbs-down-3.svg +3 -0
- package/assets/svges/thumbs-up-3.svg +3 -0
- package/assets/svges/ticket-1.svg +3 -0
- package/assets/svges/tickets-3.svg +7 -0
- package/assets/svges/tiktok-alt.svg +3 -0
- package/assets/svges/tiktok.svg +3 -0
- package/assets/svges/tower-broadcast-1.svg +7 -0
- package/assets/svges/toyota.svg +4 -0
- package/assets/svges/train-1.svg +4 -0
- package/assets/svges/train-3.svg +5 -0
- package/assets/svges/trash-3.svg +5 -0
- package/assets/svges/tree-2.svg +3 -0
- package/assets/svges/trees-3.svg +3 -0
- package/assets/svges/trello.svg +3 -0
- package/assets/svges/trend-down-1.svg +3 -0
- package/assets/svges/trend-up-1.svg +3 -0
- package/assets/svges/trophy-1.svg +3 -0
- package/assets/svges/trowel-1.svg +3 -0
- package/assets/svges/truck-delivery-1.svg +3 -0
- package/assets/svges/tumblr.svg +3 -0
- package/assets/svges/turborepo.svg +4 -0
- package/assets/svges/twitch.svg +3 -0
- package/assets/svges/twitter-old.svg +3 -0
- package/assets/svges/typescript.svg +3 -0
- package/assets/svges/uber-symbol.svg +3 -0
- package/assets/svges/uber.svg +3 -0
- package/assets/svges/ubuntu.svg +3 -0
- package/assets/svges/underline.svg +4 -0
- package/assets/svges/unlink-2-angular-eft.svg +8 -0
- package/assets/svges/unlocked-2.svg +4 -0
- package/assets/svges/unsplash.svg +4 -0
- package/assets/svges/upload-1.svg +4 -0
- package/assets/svges/upload-circle-1.svg +4 -0
- package/assets/svges/user-4.svg +4 -0
- package/assets/svges/user-multiple-4.svg +6 -0
- package/assets/svges/vector-nodes-6.svg +3 -0
- package/assets/svges/vector-nodes-7.svg +3 -0
- package/assets/svges/vercel.svg +3 -0
- package/assets/svges/vimeo.svg +3 -0
- package/assets/svges/visa.svg +3 -0
- package/assets/svges/vite.svg +6 -0
- package/assets/svges/vk.svg +3 -0
- package/assets/svges/vmware.svg +4 -0
- package/assets/svges/volkswagen.svg +8 -0
- package/assets/svges/volume-1.svg +5 -0
- package/assets/svges/volume-high.svg +6 -0
- package/assets/svges/volume-low.svg +4 -0
- package/assets/svges/volume-mute.svg +6 -0
- package/assets/svges/volume-off.svg +3 -0
- package/assets/svges/vs-code.svg +3 -0
- package/assets/svges/vuejs.svg +3 -0
- package/assets/svges/wallet-1.svg +3 -0
- package/assets/svges/watch-beat-1.svg +4 -0
- package/assets/svges/water-drop-1.svg +4 -0
- package/assets/svges/webflow.svg +3 -0
- package/assets/svges/webhooks.svg +3 -0
- package/assets/svges/wechat.svg +4 -0
- package/assets/svges/weight-machine-1.svg +4 -0
- package/assets/svges/whatsapp.svg +3 -0
- package/assets/svges/wheelbarrow-empty.svg +3 -0
- package/assets/svges/wheelchair-1.svg +3 -0
- package/assets/svges/windows.svg +6 -0
- package/assets/svges/wise.svg +3 -0
- package/assets/svges/wordpress.svg +3 -0
- package/assets/svges/www-cursor.svg +5 -0
- package/assets/svges/www.svg +4 -0
- package/assets/svges/x.svg +3 -0
- package/assets/svges/xampp.svg +5 -0
- package/assets/svges/xbox.svg +6 -0
- package/assets/svges/xmark-circle.svg +4 -0
- package/assets/svges/xmark.svg +3 -0
- package/assets/svges/xrp.svg +3 -0
- package/assets/svges/yahoo.svg +3 -0
- package/assets/svges/yarn.svg +4 -0
- package/assets/svges/ycombinator.svg +3 -0
- package/assets/svges/yen.svg +3 -0
- package/assets/svges/youtube-kids.svg +3 -0
- package/assets/svges/youtube-music.svg +4 -0
- package/assets/svges/youtube.svg +3 -0
- package/assets/svges/zapier.svg +3 -0
- package/assets/svges/zero-size.svg +6 -0
- package/assets/svges/zoom.svg +4 -0
- package/bin/test-svger.js +163 -0
- package/dist/__tests__/__mocks__/visual-diff.d.ts +7 -0
- package/dist/__tests__/__mocks__/visual-diff.js +13 -0
- package/dist/__tests__/fixtures.js +18 -18
- package/dist/cli.js +148 -2
- package/dist/config.js +4 -1
- package/dist/core/enhanced-plugin-manager.d.ts +107 -0
- package/dist/core/enhanced-plugin-manager.js +315 -0
- package/dist/core/error-handler.d.ts +1 -1
- package/dist/core/error-handler.js +14 -17
- package/dist/core/framework-templates.js +37 -47
- package/dist/core/logger.js +0 -1
- package/dist/core/performance-engine.js +10 -15
- package/dist/core/plugin-manager.js +4 -4
- package/dist/core/style-compiler.d.ts +0 -1
- package/dist/core/style-compiler.js +3 -6
- package/dist/core/template-manager.js +2 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/integrations/babel.d.ts +1 -1
- package/dist/integrations/babel.js +1 -1
- package/dist/integrations/jest-preset.js +1 -1
- package/dist/optimizers/advanced-stages.d.ts +40 -0
- package/dist/optimizers/advanced-stages.js +297 -0
- package/dist/optimizers/basic-cleaner.d.ts +72 -0
- package/dist/optimizers/basic-cleaner.js +240 -0
- package/dist/optimizers/collapse-useless-groups.d.ts +26 -0
- package/dist/optimizers/collapse-useless-groups.js +104 -0
- package/dist/optimizers/command-optimizer.d.ts +48 -0
- package/dist/optimizers/command-optimizer.js +299 -0
- package/dist/optimizers/index.d.ts +14 -0
- package/dist/optimizers/index.js +15 -0
- package/dist/optimizers/move-attrs-to-parent.d.ts +31 -0
- package/dist/optimizers/move-attrs-to-parent.js +115 -0
- package/dist/optimizers/numeric-optimizer.d.ts +43 -0
- package/dist/optimizers/numeric-optimizer.js +383 -0
- package/dist/optimizers/optimizer-pipeline.d.ts +39 -0
- package/dist/optimizers/optimizer-pipeline.js +81 -0
- package/dist/optimizers/path-deduplicator.d.ts +37 -0
- package/dist/optimizers/path-deduplicator.js +406 -0
- package/dist/optimizers/path-parser.d.ts +60 -0
- package/dist/optimizers/path-parser.js +428 -0
- package/dist/optimizers/path-shortener.d.ts +41 -0
- package/dist/optimizers/path-shortener.js +274 -0
- package/dist/optimizers/path-simplifier.d.ts +30 -0
- package/dist/optimizers/path-simplifier.js +326 -0
- package/dist/optimizers/remove-hidden-empty.d.ts +29 -0
- package/dist/optimizers/remove-hidden-empty.js +130 -0
- package/dist/optimizers/remove-unused-defs.d.ts +24 -0
- package/dist/optimizers/remove-unused-defs.js +132 -0
- package/dist/optimizers/shape-conversion.d.ts +74 -0
- package/dist/optimizers/shape-conversion.js +277 -0
- package/dist/optimizers/style-optimizer.d.ts +30 -0
- package/dist/optimizers/style-optimizer.js +324 -0
- package/dist/optimizers/svg-tree-parser.d.ts +55 -0
- package/dist/optimizers/svg-tree-parser.js +352 -0
- package/dist/optimizers/transform-collapsing.d.ts +38 -0
- package/dist/optimizers/transform-collapsing.js +444 -0
- package/dist/optimizers/transform-optimizer.d.ts +65 -0
- package/dist/optimizers/transform-optimizer.js +320 -0
- package/dist/optimizers/tree-serializer.d.ts +46 -0
- package/dist/optimizers/tree-serializer.js +190 -0
- package/dist/optimizers/tree-stages.d.ts +27 -0
- package/dist/optimizers/tree-stages.js +141 -0
- package/dist/optimizers/types.d.ts +207 -0
- package/dist/optimizers/types.js +122 -0
- package/dist/plugins/color-replacer.d.ts +39 -0
- package/dist/plugins/color-replacer.js +126 -0
- package/dist/plugins/gradient-optimizer.d.ts +33 -0
- package/dist/plugins/gradient-optimizer.js +197 -0
- package/dist/plugins/stroke-normalizer.d.ts +33 -0
- package/dist/plugins/stroke-normalizer.js +166 -0
- package/dist/plugins/watermark-remover.d.ts +32 -0
- package/dist/plugins/watermark-remover.js +133 -0
- package/dist/processors/svg-processor.d.ts +22 -2
- package/dist/processors/svg-processor.js +145 -35
- package/dist/services/config.d.ts +4 -0
- package/dist/services/config.js +62 -1
- package/dist/services/file-watcher.d.ts +1 -1
- package/dist/services/file-watcher.js +1 -1
- package/dist/services/svg-service.d.ts +4 -0
- package/dist/services/svg-service.js +41 -7
- package/dist/types/index.d.ts +1 -0
- package/dist/types/plugin-system.d.ts +153 -0
- package/dist/types/plugin-system.js +5 -0
- package/dist/utils/visual-diff.d.ts +154 -0
- package/dist/utils/visual-diff.js +278 -0
- package/dist/watch.js +0 -2
- package/docs/BUG-FIX-REACT-JSX.md +210 -0
- package/docs/COMPLETE-ACHIEVEMENT-SUMMARY.md +401 -0
- package/docs/MIGRATION-4.0.0.md +271 -0
- package/docs/OPTIONAL-DEPENDENCIES.md +161 -0
- package/docs/OPTIONAL-DEPS-FIX-V4.0.1.md +309 -0
- package/docs/PIPELINE-INTEGRATION.md +406 -0
- package/docs/PLUGIN-DEVELOPMENT-GUIDE.md +807 -0
- package/docs/QUICK-REFERENCE.md +176 -0
- package/docs/SAMPLE-SVGS-TESTING.md +276 -0
- package/docs/archive/PHASE-1-ARCHITECTURE.md +345 -0
- package/docs/archive/PHASE-1-IMPLEMENTATION.md +307 -0
- package/docs/archive/PHASE-1-SUMMARY.md +298 -0
- package/docs/archive/PHASE-2-COMPLETE.md +207 -0
- package/docs/archive/PHASE-3-SUMMARY.md +149 -0
- package/docs/archive/PHASE-4.3-COMMAND-OPTIMIZER.md +323 -0
- package/docs/archive/PHASE-4.4-PATH-SIMPLIFICATION.md +81 -0
- package/docs/archive/PHASE-4.5-PATH-DEDUPLICATION.md +449 -0
- package/docs/archive/PHASE-5.1-SUCCESS-REPORT.md +207 -0
- package/docs/archive/PHASE-5.1-TRANSFORM-COLLAPSING.md +362 -0
- package/docs/archive/PHASE-6.1-SHAPE-CONVERSION-DESIGN.md +518 -0
- package/docs/archive/PHASE-6.2-PLUGIN-SYSTEM-STATUS.md +403 -0
- package/docs/archive/PHASE-6.3-FINAL-STATUS.md +193 -0
- package/docs/archive/PHASE-6.3-VALIDATION-PROGRESS.md +345 -0
- package/docs/archive/PHASE-6.3-VISUAL-DIFF-DESIGN.md +553 -0
- package/docs/archive/PHASE-6.3-VISUAL-DIFF-SUMMARY.md +367 -0
- package/docs/archive/PHASE-6.3-XML-SERIALIZATION-FIX.md +210 -0
- package/docs/archive/RELEASE-NOTES-3.2.0.md +344 -0
- package/docs/archive/RELEASE-PREP-3.2.0.md +376 -0
- package/docs/performance/PERFORMANCE-RESULTS.md +31 -0
- package/docs/performance/REAL-WORLD-BENCHMARKS.md +159 -0
- package/package.json +18 -6
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 5: Transform Collapsing & Matrix Mastery
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* 1. Propagate transforms down the tree
|
|
6
|
+
* 2. Apply transforms to coordinates/paths (bake into d attribute)
|
|
7
|
+
* 3. Collapse nested transforms into single matrix per element
|
|
8
|
+
* 4. Remove identity/no-op transforms
|
|
9
|
+
* 5. Extract repeated transformed shapes to <defs> + <use>
|
|
10
|
+
*
|
|
11
|
+
* Superior to SVGO's cleanupTransforms - especially for Illustrator exports.
|
|
12
|
+
*/
|
|
13
|
+
import { parseTransformList, consolidateTransforms, isIdentityMatrix, decomposeMatrix, } from './transform-optimizer.js';
|
|
14
|
+
/**
|
|
15
|
+
* Identity matrix
|
|
16
|
+
*/
|
|
17
|
+
const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
|
|
18
|
+
/**
|
|
19
|
+
* Multiply two matrices: result = m1 × m2
|
|
20
|
+
*/
|
|
21
|
+
function multiplyMatrices(m1, m2) {
|
|
22
|
+
const [a1, b1, c1, d1, e1, f1] = m1;
|
|
23
|
+
const [a2, b2, c2, d2, e2, f2] = m2;
|
|
24
|
+
return [
|
|
25
|
+
a1 * a2 + c1 * b2,
|
|
26
|
+
b1 * a2 + d1 * b2,
|
|
27
|
+
a1 * c2 + c1 * d2,
|
|
28
|
+
b1 * c2 + d1 * d2,
|
|
29
|
+
a1 * e2 + c1 * f2 + e1,
|
|
30
|
+
b1 * e2 + d1 * f2 + f1,
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Apply matrix transformation to a point
|
|
35
|
+
*/
|
|
36
|
+
function transformPoint(matrix, x, y) {
|
|
37
|
+
const [a, b, c, d, e, f] = matrix;
|
|
38
|
+
return [a * x + c * y + e, b * x + d * y + f];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get transform matrix from node's transform attribute
|
|
42
|
+
*/
|
|
43
|
+
function getNodeTransform(node) {
|
|
44
|
+
const transformAttr = node.attrs.get('transform');
|
|
45
|
+
if (!transformAttr) {
|
|
46
|
+
return IDENTITY_MATRIX;
|
|
47
|
+
}
|
|
48
|
+
const transforms = parseTransformList(transformAttr);
|
|
49
|
+
return consolidateTransforms(transforms);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Check if node is a container that should have transforms propagated
|
|
53
|
+
*/
|
|
54
|
+
function isContainer(tag) {
|
|
55
|
+
return ['g', 'svg', 'symbol', 'defs', 'clipPath', 'mask'].includes(tag);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if node is a shape that can have transforms applied to coordinates
|
|
59
|
+
*/
|
|
60
|
+
function isShape(tag) {
|
|
61
|
+
return [
|
|
62
|
+
'rect',
|
|
63
|
+
'circle',
|
|
64
|
+
'ellipse',
|
|
65
|
+
'line',
|
|
66
|
+
'polygon',
|
|
67
|
+
'polyline',
|
|
68
|
+
'path',
|
|
69
|
+
].includes(tag);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Apply transform matrix to rect coordinates
|
|
73
|
+
*/
|
|
74
|
+
function applyTransformToRect(node, matrix) {
|
|
75
|
+
const x = parseFloat(node.attrs.get('x') || '0');
|
|
76
|
+
const y = parseFloat(node.attrs.get('y') || '0');
|
|
77
|
+
const width = parseFloat(node.attrs.get('width') || '0');
|
|
78
|
+
const height = parseFloat(node.attrs.get('height') || '0');
|
|
79
|
+
// Only handle simple translate transforms for now (no rotation/skew)
|
|
80
|
+
const [a, b, c, d] = matrix;
|
|
81
|
+
// Check if it's a simple translate + scale
|
|
82
|
+
if (Math.abs(b) < 1e-6 && Math.abs(c) < 1e-6) {
|
|
83
|
+
// Transform top-left corner
|
|
84
|
+
const [newX, newY] = transformPoint(matrix, x, y);
|
|
85
|
+
// Scale dimensions
|
|
86
|
+
const newWidth = width * a;
|
|
87
|
+
const newHeight = height * d;
|
|
88
|
+
// Update attributes
|
|
89
|
+
node.attrs.set('x', newX.toString());
|
|
90
|
+
node.attrs.set('y', newY.toString());
|
|
91
|
+
node.attrs.set('width', newWidth.toString());
|
|
92
|
+
node.attrs.set('height', newHeight.toString());
|
|
93
|
+
// Remove transform
|
|
94
|
+
node.attrs.delete('transform');
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Apply transform matrix to circle coordinates
|
|
101
|
+
*/
|
|
102
|
+
function applyTransformToCircle(node, matrix) {
|
|
103
|
+
const cx = parseFloat(node.attrs.get('cx') || '0');
|
|
104
|
+
const cy = parseFloat(node.attrs.get('cy') || '0');
|
|
105
|
+
const r = parseFloat(node.attrs.get('r') || '0');
|
|
106
|
+
// Only handle simple translate transforms (no scale/rotation that would make it ellipse)
|
|
107
|
+
const [a, b, c, d] = matrix;
|
|
108
|
+
// Check if it's uniform scale + translate (circle stays circle)
|
|
109
|
+
if (Math.abs(b) < 1e-6 &&
|
|
110
|
+
Math.abs(c) < 1e-6 &&
|
|
111
|
+
Math.abs(a - d) < 1e-6 &&
|
|
112
|
+
a > 0) {
|
|
113
|
+
// Transform center
|
|
114
|
+
const [newCx, newCy] = transformPoint(matrix, cx, cy);
|
|
115
|
+
// Scale radius
|
|
116
|
+
const newR = r * a;
|
|
117
|
+
// Update attributes
|
|
118
|
+
node.attrs.set('cx', newCx.toString());
|
|
119
|
+
node.attrs.set('cy', newCy.toString());
|
|
120
|
+
node.attrs.set('r', newR.toString());
|
|
121
|
+
// Remove transform
|
|
122
|
+
node.attrs.delete('transform');
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Apply transform matrix to line coordinates
|
|
129
|
+
*/
|
|
130
|
+
function applyTransformToLine(node, matrix) {
|
|
131
|
+
const x1 = parseFloat(node.attrs.get('x1') || '0');
|
|
132
|
+
const y1 = parseFloat(node.attrs.get('y1') || '0');
|
|
133
|
+
const x2 = parseFloat(node.attrs.get('x2') || '0');
|
|
134
|
+
const y2 = parseFloat(node.attrs.get('y2') || '0');
|
|
135
|
+
// Transform both points
|
|
136
|
+
const [newX1, newY1] = transformPoint(matrix, x1, y1);
|
|
137
|
+
const [newX2, newY2] = transformPoint(matrix, x2, y2);
|
|
138
|
+
// Update attributes
|
|
139
|
+
node.attrs.set('x1', newX1.toString());
|
|
140
|
+
node.attrs.set('y1', newY1.toString());
|
|
141
|
+
node.attrs.set('x2', newX2.toString());
|
|
142
|
+
node.attrs.set('y2', newY2.toString());
|
|
143
|
+
// Remove transform
|
|
144
|
+
node.attrs.delete('transform');
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Apply transform matrix to polygon/polyline points
|
|
149
|
+
*/
|
|
150
|
+
function applyTransformToPoints(node, matrix) {
|
|
151
|
+
const pointsAttr = node.attrs.get('points');
|
|
152
|
+
if (!pointsAttr)
|
|
153
|
+
return false;
|
|
154
|
+
// Parse points
|
|
155
|
+
const coords = pointsAttr
|
|
156
|
+
.trim()
|
|
157
|
+
.split(/[\s,]+/)
|
|
158
|
+
.map(v => parseFloat(v))
|
|
159
|
+
.filter(v => !isNaN(v));
|
|
160
|
+
if (coords.length < 2 || coords.length % 2 !== 0) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
// Transform each point
|
|
164
|
+
const transformedCoords = [];
|
|
165
|
+
for (let i = 0; i < coords.length; i += 2) {
|
|
166
|
+
const [newX, newY] = transformPoint(matrix, coords[i], coords[i + 1]);
|
|
167
|
+
transformedCoords.push(newX, newY);
|
|
168
|
+
}
|
|
169
|
+
// Update points attribute
|
|
170
|
+
const newPoints = transformedCoords.join(' ');
|
|
171
|
+
node.attrs.set('points', newPoints);
|
|
172
|
+
// Remove transform
|
|
173
|
+
node.attrs.delete('transform');
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Apply transform to path data (simplified - basic transforms only)
|
|
178
|
+
* Full path transformation would require parsing and transforming each command
|
|
179
|
+
*/
|
|
180
|
+
function applyTransformToPath(node, matrix) {
|
|
181
|
+
// For now, only handle simple translate transforms on absolute paths
|
|
182
|
+
// Full implementation would use path-parser.ts to transform all coordinates
|
|
183
|
+
const [a, b, c, d, e, f] = matrix;
|
|
184
|
+
// Only simple translate (no rotation/scale/skew)
|
|
185
|
+
if (Math.abs(a - 1) < 1e-6 &&
|
|
186
|
+
Math.abs(b) < 1e-6 &&
|
|
187
|
+
Math.abs(c) < 1e-6 &&
|
|
188
|
+
Math.abs(d - 1) < 1e-6) {
|
|
189
|
+
const pathData = node.attrs.get('d');
|
|
190
|
+
if (!pathData)
|
|
191
|
+
return false;
|
|
192
|
+
// Simple regex-based coordinate adjustment (basic implementation)
|
|
193
|
+
// TODO: Use path-parser.ts for full transformation
|
|
194
|
+
const hasOnlyAbsolute = !/[mlhvcsqta]/.test(pathData);
|
|
195
|
+
if (hasOnlyAbsolute && (Math.abs(e) > 1e-6 || Math.abs(f) > 1e-6)) {
|
|
196
|
+
// Very basic: add translate values to all coordinates
|
|
197
|
+
// This is a simplified approach - full implementation needs path-parser
|
|
198
|
+
const transformed = pathData.replace(/([MLHVCSQTA])\s*([\d.eE+-]+)(?:\s+([\d.eE+-]+))?/gi, (match, cmd, x, y) => {
|
|
199
|
+
const numX = parseFloat(x);
|
|
200
|
+
const numY = y ? parseFloat(y) : null;
|
|
201
|
+
if (cmd.toUpperCase() === 'H') {
|
|
202
|
+
return `${cmd}${numX + e}`;
|
|
203
|
+
}
|
|
204
|
+
else if (cmd.toUpperCase() === 'V') {
|
|
205
|
+
return `${cmd}${numY !== null ? numY + f : numX + f}`;
|
|
206
|
+
}
|
|
207
|
+
else if (numY !== null) {
|
|
208
|
+
return `${cmd}${numX + e} ${numY + f}`;
|
|
209
|
+
}
|
|
210
|
+
return match;
|
|
211
|
+
});
|
|
212
|
+
node.attrs.set('d', transformed);
|
|
213
|
+
node.attrs.delete('transform');
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Apply transform to shape coordinates
|
|
221
|
+
*/
|
|
222
|
+
function applyTransformToShape(node, matrix) {
|
|
223
|
+
switch (node.tag) {
|
|
224
|
+
case 'rect':
|
|
225
|
+
return applyTransformToRect(node, matrix);
|
|
226
|
+
case 'circle':
|
|
227
|
+
return applyTransformToCircle(node, matrix);
|
|
228
|
+
case 'line':
|
|
229
|
+
return applyTransformToLine(node, matrix);
|
|
230
|
+
case 'polygon':
|
|
231
|
+
case 'polyline':
|
|
232
|
+
return applyTransformToPoints(node, matrix);
|
|
233
|
+
case 'path':
|
|
234
|
+
return applyTransformToPath(node, matrix);
|
|
235
|
+
default:
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Collapse transforms by propagating down the tree
|
|
241
|
+
*/
|
|
242
|
+
export function collapseTransforms(root, _config) {
|
|
243
|
+
let collapsedGroups = 0;
|
|
244
|
+
let bakedTransforms = 0;
|
|
245
|
+
let removedIdentity = 0;
|
|
246
|
+
const traverse = (node, parentMatrix = IDENTITY_MATRIX) => {
|
|
247
|
+
if (!node)
|
|
248
|
+
return;
|
|
249
|
+
// Get this node's transform
|
|
250
|
+
const nodeMatrix = getNodeTransform(node);
|
|
251
|
+
// Combine with parent transform
|
|
252
|
+
const combinedMatrix = multiplyMatrices(parentMatrix, nodeMatrix);
|
|
253
|
+
// Check if combined matrix is identity
|
|
254
|
+
if (isIdentityMatrix(combinedMatrix)) {
|
|
255
|
+
if (node.attrs.has('transform')) {
|
|
256
|
+
node.attrs.delete('transform');
|
|
257
|
+
removedIdentity++;
|
|
258
|
+
}
|
|
259
|
+
// Continue with identity matrix
|
|
260
|
+
for (const child of node.children) {
|
|
261
|
+
if (child.type === 'element') {
|
|
262
|
+
traverse(child, IDENTITY_MATRIX);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
// If this is a shape, try to apply parent transform to it
|
|
268
|
+
if (isShape(node.tag) && !isIdentityMatrix(parentMatrix)) {
|
|
269
|
+
const nodeMatrix = getNodeTransform(node);
|
|
270
|
+
const finalMatrix = multiplyMatrices(parentMatrix, nodeMatrix);
|
|
271
|
+
if (applyTransformToShape(node, finalMatrix)) {
|
|
272
|
+
bakedTransforms++;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// If this is a container (g, svg, etc.)
|
|
276
|
+
if (isContainer(node.tag)) {
|
|
277
|
+
// If it's a group with only one child, try to collapse
|
|
278
|
+
if (node.tag === 'g' &&
|
|
279
|
+
node.children.length === 1 &&
|
|
280
|
+
node.children[0].type === 'element') {
|
|
281
|
+
const child = node.children[0];
|
|
282
|
+
// If child is also a container (nested groups), try to collapse them
|
|
283
|
+
if (isContainer(child.tag)) {
|
|
284
|
+
// Multiply transforms and apply to child
|
|
285
|
+
const childMatrix = getNodeTransform(child);
|
|
286
|
+
const finalMatrix = multiplyMatrices(combinedMatrix, childMatrix);
|
|
287
|
+
// Set the combined transform on child and remove parent's transform
|
|
288
|
+
if (!isIdentityMatrix(finalMatrix)) {
|
|
289
|
+
const transformStr = decomposeMatrix(finalMatrix);
|
|
290
|
+
if (transformStr) {
|
|
291
|
+
child.attrs.set('transform', transformStr);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
child.attrs.delete('transform');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
child.attrs.delete('transform');
|
|
299
|
+
}
|
|
300
|
+
node.attrs.delete('transform');
|
|
301
|
+
collapsedGroups++;
|
|
302
|
+
// Continue traversing children with identity (we moved transform down)
|
|
303
|
+
for (const c of node.children) {
|
|
304
|
+
if (c.type === 'element') {
|
|
305
|
+
traverse(c, IDENTITY_MATRIX);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
// If child is a shape, try to apply combined transform to it
|
|
311
|
+
if (isShape(child.tag)) {
|
|
312
|
+
const childMatrix = getNodeTransform(child);
|
|
313
|
+
const finalMatrix = multiplyMatrices(combinedMatrix, childMatrix);
|
|
314
|
+
if (applyTransformToShape(child, finalMatrix)) {
|
|
315
|
+
// Remove this group's transform since we baked it into child
|
|
316
|
+
node.attrs.delete('transform');
|
|
317
|
+
collapsedGroups++;
|
|
318
|
+
bakedTransforms++;
|
|
319
|
+
// Continue traversing children with identity
|
|
320
|
+
for (const c of node.children) {
|
|
321
|
+
if (c.type === 'element') {
|
|
322
|
+
traverse(c, IDENTITY_MATRIX);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// Otherwise, propagate combined transform to children
|
|
330
|
+
for (const child of node.children) {
|
|
331
|
+
if (child.type === 'element') {
|
|
332
|
+
traverse(child, combinedMatrix);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// After propagating, remove this node's transform if it was fully propagated
|
|
336
|
+
if (!isIdentityMatrix(combinedMatrix) && isIdentityMatrix(nodeMatrix)) {
|
|
337
|
+
node.attrs.delete('transform');
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
else if (isShape(node.tag)) {
|
|
341
|
+
// Try to apply combined transform to shape
|
|
342
|
+
if (applyTransformToShape(node, combinedMatrix)) {
|
|
343
|
+
bakedTransforms++;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
// Can't apply - set combined transform on node
|
|
347
|
+
if (!isIdentityMatrix(combinedMatrix)) {
|
|
348
|
+
const [a, b, c, d, e, f] = combinedMatrix;
|
|
349
|
+
node.attrs.set('transform', `matrix(${a} ${b} ${c} ${d} ${e} ${f})`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// Shapes don't have children to traverse
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
// Other elements - propagate to children
|
|
356
|
+
for (const child of node.children) {
|
|
357
|
+
if (child.type === 'element') {
|
|
358
|
+
traverse(child, combinedMatrix);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
traverse(root);
|
|
364
|
+
// Unwrap single-child groups with no attributes
|
|
365
|
+
const unwrapGroups = (node) => {
|
|
366
|
+
if (!node || !node.children)
|
|
367
|
+
return;
|
|
368
|
+
// First, recurse to unwrap nested structures
|
|
369
|
+
for (const child of node.children) {
|
|
370
|
+
if (child.type === 'element') {
|
|
371
|
+
unwrapGroups(child);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// Then unwrap single-child <g> elements with no attributes
|
|
375
|
+
const newChildren = [];
|
|
376
|
+
for (const child of node.children) {
|
|
377
|
+
if (child.type === 'element' &&
|
|
378
|
+
child.tag === 'g' &&
|
|
379
|
+
child.attrs.size === 0 &&
|
|
380
|
+
child.children.length === 1) {
|
|
381
|
+
// Unwrap: replace group with its child
|
|
382
|
+
newChildren.push(child.children[0]);
|
|
383
|
+
collapsedGroups++; // Count as additional collapse
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
newChildren.push(child);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
node.children = newChildren;
|
|
390
|
+
};
|
|
391
|
+
unwrapGroups(root);
|
|
392
|
+
return {
|
|
393
|
+
collapsedGroups,
|
|
394
|
+
bakedTransforms,
|
|
395
|
+
removedIdentity,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Find repeated shapes for <use> extraction
|
|
400
|
+
* Returns map of shape signature → nodes
|
|
401
|
+
* TODO: Reserved for future implementation when adding <defs> + <use> optimization
|
|
402
|
+
*/
|
|
403
|
+
/* Commented out for future use
|
|
404
|
+
function findRepeatedShapes(root: SVGNode): Map<string, SVGNode[]> {
|
|
405
|
+
const shapeMap = new Map<string, SVGNode[]>();
|
|
406
|
+
|
|
407
|
+
const traverse = (node: SVGNode) => {
|
|
408
|
+
if (!node) return;
|
|
409
|
+
if (isShape(node.tag)) {
|
|
410
|
+
let signature = node.tag;
|
|
411
|
+
const keyAttrs = ['d', 'points', 'r', 'width', 'height', 'x1', 'y1', 'x2', 'y2'];
|
|
412
|
+
for (const attr of keyAttrs) {
|
|
413
|
+
const value = node.attrs.get(attr);
|
|
414
|
+
if (value) signature += `|${attr}:${value}`;
|
|
415
|
+
}
|
|
416
|
+
const nodes = shapeMap.get(signature) || [];
|
|
417
|
+
nodes.push(node);
|
|
418
|
+
shapeMap.set(signature, nodes);
|
|
419
|
+
}
|
|
420
|
+
for (const child of node.children) {
|
|
421
|
+
if (child.type === 'element') traverse(child);
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
traverse(root);
|
|
426
|
+
const repeated = new Map<string, SVGNode[]>();
|
|
427
|
+
for (const [sig, nodes] of shapeMap) {
|
|
428
|
+
if (nodes.length >= 2) repeated.set(sig, nodes);
|
|
429
|
+
}
|
|
430
|
+
return repeated;
|
|
431
|
+
}
|
|
432
|
+
*/
|
|
433
|
+
/**
|
|
434
|
+
* Transform collapsing stage for pipeline
|
|
435
|
+
*/
|
|
436
|
+
export function transformCollapsingStage(root, config) {
|
|
437
|
+
const stats = collapseTransforms(root, config);
|
|
438
|
+
return {
|
|
439
|
+
modified: stats.collapsedGroups > 0 ||
|
|
440
|
+
stats.bakedTransforms > 0 ||
|
|
441
|
+
stats.removedIdentity > 0,
|
|
442
|
+
stats,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 3: Transform Optimizer
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* 1. Parse transform attribute lists (translate, rotate, scale, skew, matrix)
|
|
6
|
+
* 2. Consolidate multiple transforms into single matrix
|
|
7
|
+
* 3. Decompose matrix back to simpler transforms only if shorter
|
|
8
|
+
* 4. Round matrix/transform values to configured precision
|
|
9
|
+
*/
|
|
10
|
+
import type { SVGNode } from './svg-tree-parser.js';
|
|
11
|
+
import type { OptConfig } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* 2D transformation matrix [a, b, c, d, e, f]
|
|
14
|
+
* Represents: | a c e |
|
|
15
|
+
* | b d f |
|
|
16
|
+
* | 0 0 1 |
|
|
17
|
+
*/
|
|
18
|
+
type Matrix = [number, number, number, number, number, number];
|
|
19
|
+
/**
|
|
20
|
+
* Transform command types
|
|
21
|
+
*/
|
|
22
|
+
interface Transform {
|
|
23
|
+
type: 'translate' | 'rotate' | 'scale' | 'skewX' | 'skewY' | 'matrix';
|
|
24
|
+
values: number[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse transform attribute into list of commands
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseTransformList(transformStr: string): Transform[];
|
|
30
|
+
/**
|
|
31
|
+
* Consolidate transform list into single matrix
|
|
32
|
+
*/
|
|
33
|
+
export declare function consolidateTransforms(transforms: Transform[]): Matrix;
|
|
34
|
+
/**
|
|
35
|
+
* Check if matrix is identity
|
|
36
|
+
*/
|
|
37
|
+
export declare function isIdentityMatrix(m: Matrix): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Decompose matrix to simpler transforms if possible
|
|
40
|
+
* Returns shortest representation between:
|
|
41
|
+
* - matrix(a, b, c, d, e, f)
|
|
42
|
+
* - translate(tx, ty)
|
|
43
|
+
* - scale(sx, sy)
|
|
44
|
+
* - rotate(angle)
|
|
45
|
+
* - combinations
|
|
46
|
+
*/
|
|
47
|
+
export declare function decomposeMatrix(m: Matrix, precision?: number): string;
|
|
48
|
+
/**
|
|
49
|
+
* Optimize transforms in the tree
|
|
50
|
+
*/
|
|
51
|
+
export declare function optimizeTransforms(root: SVGNode, config: OptConfig): {
|
|
52
|
+
optimizedTransforms: number;
|
|
53
|
+
removedIdentity: number;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Transform optimization stage for pipeline
|
|
57
|
+
*/
|
|
58
|
+
export declare function transformOptimizationStage(root: SVGNode, config: OptConfig): {
|
|
59
|
+
modified: boolean;
|
|
60
|
+
stats: {
|
|
61
|
+
optimizedTransforms: number;
|
|
62
|
+
removedIdentity: number;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
export {};
|