svger-cli 3.1.0 → 4.0.0

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.
Files changed (729) hide show
  1. package/CHANGELOG.md +399 -0
  2. package/README.md +448 -37
  3. package/SECURITY.md +3 -3
  4. package/assets/svges/500px.svg +3 -0
  5. package/assets/svges/adobe.svg +3 -0
  6. package/assets/svges/adonis.svg +3 -0
  7. package/assets/svges/aeroplane-1.svg +3 -0
  8. package/assets/svges/agenda.svg +3 -0
  9. package/assets/svges/airbnb.svg +3 -0
  10. package/assets/svges/airtable.svg +3 -0
  11. package/assets/svges/alarm-1.svg +7 -0
  12. package/assets/svges/align-text-center.svg +6 -0
  13. package/assets/svges/align-text-left.svg +6 -0
  14. package/assets/svges/align-text-right.svg +6 -0
  15. package/assets/svges/alpinejs.svg +4 -0
  16. package/assets/svges/amazon-original.svg +5 -0
  17. package/assets/svges/amazon-pay.svg +7 -0
  18. package/assets/svges/amazon.svg +10 -0
  19. package/assets/svges/ambulance-1.svg +4 -0
  20. package/assets/svges/amd.svg +3 -0
  21. package/assets/svges/amex.svg +4 -0
  22. package/assets/svges/anchor.svg +3 -0
  23. package/assets/svges/android-old.svg +3 -0
  24. package/assets/svges/android.svg +3 -0
  25. package/assets/svges/angellist.svg +3 -0
  26. package/assets/svges/angle-double-down.svg +4 -0
  27. package/assets/svges/angle-double-left.svg +4 -0
  28. package/assets/svges/angle-double-right.svg +4 -0
  29. package/assets/svges/angle-double-up.svg +4 -0
  30. package/assets/svges/angular.svg +3 -0
  31. package/assets/svges/app-store.svg +3 -0
  32. package/assets/svges/apple-brand.svg +3 -0
  33. package/assets/svges/apple-music-alt.svg +3 -0
  34. package/assets/svges/apple-music.svg +3 -0
  35. package/assets/svges/apple-pay.svg +3 -0
  36. package/assets/svges/arc-browser.svg +6 -0
  37. package/assets/svges/arrow-all-direction.svg +6 -0
  38. package/assets/svges/arrow-angular-top-left.svg +3 -0
  39. package/assets/svges/arrow-angular-top-right.svg +3 -0
  40. package/assets/svges/arrow-both-direction-horizontal-1.svg +3 -0
  41. package/assets/svges/arrow-both-direction-vertical-1.svg +3 -0
  42. package/assets/svges/arrow-downward.svg +3 -0
  43. package/assets/svges/arrow-left-circle.svg +4 -0
  44. package/assets/svges/arrow-left.svg +3 -0
  45. package/assets/svges/arrow-right-circle.svg +4 -0
  46. package/assets/svges/arrow-right.svg +3 -0
  47. package/assets/svges/arrow-upward.svg +3 -0
  48. package/assets/svges/asana.svg +3 -0
  49. package/assets/svges/astro.svg +4 -0
  50. package/assets/svges/atlassian.svg +3 -0
  51. package/assets/svges/audi-alt.svg +3 -0
  52. package/assets/svges/audi.svg +3 -0
  53. package/assets/svges/aws.svg +3 -0
  54. package/assets/svges/azure.svg +3 -0
  55. package/assets/svges/badge-decagram-percent.svg +6 -0
  56. package/assets/svges/balloons.svg +3 -0
  57. package/assets/svges/ban-2.svg +3 -0
  58. package/assets/svges/bar-chart-4.svg +6 -0
  59. package/assets/svges/bar-chart-dollar.svg +6 -0
  60. package/assets/svges/basket-shopping-3.svg +5 -0
  61. package/assets/svges/beat.svg +3 -0
  62. package/assets/svges/behance.svg +5 -0
  63. package/assets/svges/bell-1.svg +3 -0
  64. package/assets/svges/bike.svg +6 -0
  65. package/assets/svges/bing.svg +5 -0
  66. package/assets/svges/bitbucket.svg +5 -0
  67. package/assets/svges/bitcoin.svg +5 -0
  68. package/assets/svges/bittorrent.svg +6 -0
  69. package/assets/svges/blogger-alt.svg +3 -0
  70. package/assets/svges/blogger.svg +3 -0
  71. package/assets/svges/bluetooth-logo.svg +3 -0
  72. package/assets/svges/bluetooth.svg +3 -0
  73. package/assets/svges/bmw.svg +7 -0
  74. package/assets/svges/board-writing-3.svg +3 -0
  75. package/assets/svges/bold.svg +3 -0
  76. package/assets/svges/bolt-2.svg +3 -0
  77. package/assets/svges/bolt-3.svg +3 -0
  78. package/assets/svges/book-1.svg +4 -0
  79. package/assets/svges/bookmark-1.svg +3 -0
  80. package/assets/svges/bookmark-circle.svg +4 -0
  81. package/assets/svges/books-2.svg +3 -0
  82. package/assets/svges/bootstrap-5-square.svg +3 -0
  83. package/assets/svges/bootstrap-5.svg +3 -0
  84. package/assets/svges/box-archive-1.svg +4 -0
  85. package/assets/svges/box-closed.svg +3 -0
  86. package/assets/svges/box-gift-1.svg +3 -0
  87. package/assets/svges/brave.svg +3 -0
  88. package/assets/svges/bricks.svg +3 -0
  89. package/assets/svges/bridge-3.svg +3 -0
  90. package/assets/svges/briefcase-1.svg +3 -0
  91. package/assets/svges/briefcase-2.svg +3 -0
  92. package/assets/svges/briefcase-plus-1.svg +4 -0
  93. package/assets/svges/brush-1-rotated.svg +3 -0
  94. package/assets/svges/brush-2.svg +3 -0
  95. package/assets/svges/btc.svg +3 -0
  96. package/assets/svges/bug-1.svg +3 -0
  97. package/assets/svges/buildings-1.svg +5 -0
  98. package/assets/svges/bulb-2.svg +3 -0
  99. package/assets/svges/bulb-4.svg +9 -0
  100. package/assets/svges/burger-1.svg +3 -0
  101. package/assets/svges/burger-drink.svg +4 -0
  102. package/assets/svges/bus-1.svg +5 -0
  103. package/assets/svges/busket-ball.svg +3 -0
  104. package/assets/svges/cake-1.svg +3 -0
  105. package/assets/svges/calculator-1.svg +8 -0
  106. package/assets/svges/calculator-2.svg +13 -0
  107. package/assets/svges/calendar-days.svg +9 -0
  108. package/assets/svges/camera-1.svg +4 -0
  109. package/assets/svges/camera-movie-1.svg +3 -0
  110. package/assets/svges/candy-cane-2.svg +3 -0
  111. package/assets/svges/candy-round-1.svg +3 -0
  112. package/assets/svges/canva.svg +3 -0
  113. package/assets/svges/capsule-1.svg +3 -0
  114. package/assets/svges/car-2.svg +5 -0
  115. package/assets/svges/car-4.svg +3 -0
  116. package/assets/svges/car-6.svg +5 -0
  117. package/assets/svges/caravan-1.svg +3 -0
  118. package/assets/svges/cart-1.svg +5 -0
  119. package/assets/svges/cart-2.svg +5 -0
  120. package/assets/svges/cash-app.svg +3 -0
  121. package/assets/svges/certificate-badge-1.svg +6 -0
  122. package/assets/svges/chat-bubble-2.svg +5 -0
  123. package/assets/svges/check-circle-1.svg +4 -0
  124. package/assets/svges/check-square-2.svg +4 -0
  125. package/assets/svges/check.svg +3 -0
  126. package/assets/svges/chevron-down-circle.svg +4 -0
  127. package/assets/svges/chevron-down.svg +3 -0
  128. package/assets/svges/chevron-left-circle.svg +4 -0
  129. package/assets/svges/chevron-left.svg +3 -0
  130. package/assets/svges/chevron-right-circle.svg +4 -0
  131. package/assets/svges/chevron-up-circle.svg +4 -0
  132. package/assets/svges/chevron-up.svg +3 -0
  133. package/assets/svges/chrome.svg +6 -0
  134. package/assets/svges/chromecast.svg +3 -0
  135. package/assets/svges/cisco.svg +3 -0
  136. package/assets/svges/claude.svg +3 -0
  137. package/assets/svges/clickup.svg +4 -0
  138. package/assets/svges/clipboard.svg +3 -0
  139. package/assets/svges/cloud-2.svg +3 -0
  140. package/assets/svges/cloud-bolt-1.svg +4 -0
  141. package/assets/svges/cloud-bolt-2.svg +4 -0
  142. package/assets/svges/cloud-check-circle.svg +5 -0
  143. package/assets/svges/cloud-download.svg +5 -0
  144. package/assets/svges/cloud-iot-2.svg +3 -0
  145. package/assets/svges/cloud-rain.svg +6 -0
  146. package/assets/svges/cloud-refresh-clockwise.svg +5 -0
  147. package/assets/svges/cloud-sun.svg +9 -0
  148. package/assets/svges/cloud-upload.svg +5 -0
  149. package/assets/svges/cloudflare.svg +3 -0
  150. package/assets/svges/code-1.svg +5 -0
  151. package/assets/svges/code-s.svg +5 -0
  152. package/assets/svges/codepen.svg +3 -0
  153. package/assets/svges/coffee-cup-2.svg +6 -0
  154. package/assets/svges/coinbase.svg +10 -0
  155. package/assets/svges/colour-palette-3.svg +7 -0
  156. package/assets/svges/comment-1-share.svg +4 -0
  157. package/assets/svges/comment-1-text.svg +5 -0
  158. package/assets/svges/comment-1.svg +3 -0
  159. package/assets/svges/compass-drafting-2.svg +3 -0
  160. package/assets/svges/connectdevelop.svg +3 -0
  161. package/assets/svges/copilot.svg +8 -0
  162. package/assets/svges/coral.svg +3 -0
  163. package/assets/svges/cpanel.svg +3 -0
  164. package/assets/svges/crane-4.svg +3 -0
  165. package/assets/svges/creative-commons.svg +4 -0
  166. package/assets/svges/credit-card-multiple.svg +3 -0
  167. package/assets/svges/crop-2.svg +3 -0
  168. package/assets/svges/crown-3.svg +3 -0
  169. package/assets/svges/css3.svg +3 -0
  170. package/assets/svges/dashboard-square-1.svg +6 -0
  171. package/assets/svges/database-2.svg +3 -0
  172. package/assets/svges/deno.svg +4 -0
  173. package/assets/svges/dev.svg +3 -0
  174. package/assets/svges/dialogflow.svg +4 -0
  175. package/assets/svges/diamonds-1.svg +3 -0
  176. package/assets/svges/diamonds-2.svg +3 -0
  177. package/assets/svges/digitalocean.svg +3 -0
  178. package/assets/svges/diners-club.svg +38 -0
  179. package/assets/svges/direction-ltr.svg +4 -0
  180. package/assets/svges/direction-rtl.svg +4 -0
  181. package/assets/svges/discord-chat.svg +5 -0
  182. package/assets/svges/discord.svg +3 -0
  183. package/assets/svges/discover.svg +3 -0
  184. package/assets/svges/docker.svg +3 -0
  185. package/assets/svges/dollar-circle.svg +4 -0
  186. package/assets/svges/dollar.svg +3 -0
  187. package/assets/svges/double-quotes-end-1.svg +4 -0
  188. package/assets/svges/download-1.svg +4 -0
  189. package/assets/svges/download-circle-1.svg +4 -0
  190. package/assets/svges/dribbble-symbol.svg +3 -0
  191. package/assets/svges/dribbble.svg +3 -0
  192. package/assets/svges/drizzle.svg +6 -0
  193. package/assets/svges/dropbox.svg +7 -0
  194. package/assets/svges/drupal.svg +3 -0
  195. package/assets/svges/dumbbell-1.svg +3 -0
  196. package/assets/svges/edge.svg +3 -0
  197. package/assets/svges/emoji-expressionless-flat-eyes.svg +6 -0
  198. package/assets/svges/emoji-expressionless.svg +6 -0
  199. package/assets/svges/emoji-grin.svg +6 -0
  200. package/assets/svges/emoji-sad.svg +6 -0
  201. package/assets/svges/emoji-smile-side.svg +6 -0
  202. package/assets/svges/emoji-smile-sunglass.svg +5 -0
  203. package/assets/svges/emoji-smile-tongue.svg +3 -0
  204. package/assets/svges/emoji-smile.svg +6 -0
  205. package/assets/svges/enter-down.svg +4 -0
  206. package/assets/svges/enter.svg +4 -0
  207. package/assets/svges/envato.svg +4 -0
  208. package/assets/svges/envelope-1.svg +3 -0
  209. package/assets/svges/eraser-1.svg +4 -0
  210. package/assets/svges/ethereum-logo.svg +4 -0
  211. package/assets/svges/euro.svg +3 -0
  212. package/assets/svges/exit-up.svg +4 -0
  213. package/assets/svges/exit.svg +4 -0
  214. package/assets/svges/expand-arrow-1.svg +3 -0
  215. package/assets/svges/expand-square-4.svg +6 -0
  216. package/assets/svges/expressjs.svg +4 -0
  217. package/assets/svges/eye.svg +4 -0
  218. package/assets/svges/facebook-messenger.svg +3 -0
  219. package/assets/svges/facebook-rounded.svg +4 -0
  220. package/assets/svges/facebook-square.svg +3 -0
  221. package/assets/svges/facebook.svg +3 -0
  222. package/assets/svges/facetime.svg +3 -0
  223. package/assets/svges/figma.svg +3 -0
  224. package/assets/svges/file-format-zip.svg +4 -0
  225. package/assets/svges/file-multiple.svg +4 -0
  226. package/assets/svges/file-pencil.svg +4 -0
  227. package/assets/svges/file-plus-circle.svg +5 -0
  228. package/assets/svges/file-question.svg +5 -0
  229. package/assets/svges/file-xmark.svg +4 -0
  230. package/assets/svges/firebase.svg +3 -0
  231. package/assets/svges/firefox.svg +3 -0
  232. package/assets/svges/firework-rocket-4.svg +3 -0
  233. package/assets/svges/fitbit.svg +3 -0
  234. package/assets/svges/flag-1.svg +3 -0
  235. package/assets/svges/flag-2.svg +3 -0
  236. package/assets/svges/flickr.svg +4 -0
  237. package/assets/svges/floppy-disk-1.svg +3 -0
  238. package/assets/svges/flower-2.svg +3 -0
  239. package/assets/svges/flutter.svg +3 -0
  240. package/assets/svges/folder-1.svg +3 -0
  241. package/assets/svges/ford.svg +3 -0
  242. package/assets/svges/framer.svg +3 -0
  243. package/assets/svges/funnel-1.svg +3 -0
  244. package/assets/svges/gallery.svg +4 -0
  245. package/assets/svges/game-pad-modern-1.svg +6 -0
  246. package/assets/svges/gatsby.svg +3 -0
  247. package/assets/svges/gauge-1.svg +5 -0
  248. package/assets/svges/gear-1.svg +4 -0
  249. package/assets/svges/gears-3.svg +6 -0
  250. package/assets/svges/gemini.svg +3 -0
  251. package/assets/svges/git.svg +3 -0
  252. package/assets/svges/github.svg +3 -0
  253. package/assets/svges/glass-juice-1.svg +3 -0
  254. package/assets/svges/globe-1.svg +3 -0
  255. package/assets/svges/globe-stand.svg +4 -0
  256. package/assets/svges/go.svg +7 -0
  257. package/assets/svges/goodreads.svg +3 -0
  258. package/assets/svges/google-cloud.svg +3 -0
  259. package/assets/svges/google-drive.svg +3 -0
  260. package/assets/svges/google-meet.svg +3 -0
  261. package/assets/svges/google-pay.svg +3 -0
  262. package/assets/svges/google-wallet.svg +3 -0
  263. package/assets/svges/google.svg +3 -0
  264. package/assets/svges/graduation-cap-1.svg +3 -0
  265. package/assets/svges/grammarly.svg +3 -0
  266. package/assets/svges/hacker-news.svg +3 -0
  267. package/assets/svges/hammer-1.svg +3 -0
  268. package/assets/svges/hammer-2.svg +3 -0
  269. package/assets/svges/hand-mic.svg +3 -0
  270. package/assets/svges/hand-shake.svg +3 -0
  271. package/assets/svges/hand-stop.svg +3 -0
  272. package/assets/svges/hand-taking-dollar.svg +4 -0
  273. package/assets/svges/hand-taking-leaf-1.svg +5 -0
  274. package/assets/svges/hand-taking-user.svg +5 -0
  275. package/assets/svges/hashnode.svg +3 -0
  276. package/assets/svges/hat-chef-3.svg +3 -0
  277. package/assets/svges/headphone-1.svg +3 -0
  278. package/assets/svges/heart.svg +3 -0
  279. package/assets/svges/helicopter-2.svg +4 -0
  280. package/assets/svges/helmet-safety-1.svg +3 -0
  281. package/assets/svges/hierarchy-1.svg +9 -0
  282. package/assets/svges/highlighter-1.svg +3 -0
  283. package/assets/svges/highlighter-2.svg +3 -0
  284. package/assets/svges/home-2.svg +3 -0
  285. package/assets/svges/hospital-2.svg +4 -0
  286. package/assets/svges/hourglass.svg +3 -0
  287. package/assets/svges/html5.svg +4 -0
  288. package/assets/svges/ibm.svg +3 -0
  289. package/assets/svges/id-card.svg +7 -0
  290. package/assets/svges/imdb.svg +7 -0
  291. package/assets/svges/indent.svg +8 -0
  292. package/assets/svges/info.svg +4 -0
  293. package/assets/svges/injection-1.svg +3 -0
  294. package/assets/svges/instagram-logotype.svg +3 -0
  295. package/assets/svges/instagram.svg +4 -0
  296. package/assets/svges/intel.svg +4 -0
  297. package/assets/svges/ios.svg +3 -0
  298. package/assets/svges/island-2.svg +4 -0
  299. package/assets/svges/jaguar.svg +3 -0
  300. package/assets/svges/jamstack.svg +3 -0
  301. package/assets/svges/java.svg +3 -0
  302. package/assets/svges/javascript.svg +3 -0
  303. package/assets/svges/jcb.svg +3 -0
  304. package/assets/svges/joomla.svg +6 -0
  305. package/assets/svges/jsfiddle.svg +4 -0
  306. package/assets/svges/key-1.svg +3 -0
  307. package/assets/svges/keyboard.svg +12 -0
  308. package/assets/svges/knife-fork-1.svg +5 -0
  309. package/assets/svges/kubernetes.svg +11 -0
  310. package/assets/svges/label-dollar-2.svg +4 -0
  311. package/assets/svges/laptop-2.svg +3 -0
  312. package/assets/svges/laptop-phone.svg +5 -0
  313. package/assets/svges/laravel.svg +3 -0
  314. package/assets/svges/layers-1.svg +4 -0
  315. package/assets/svges/layout-26.svg +3 -0
  316. package/assets/svges/layout-9.svg +3 -0
  317. package/assets/svges/leaf-1.svg +3 -0
  318. package/assets/svges/leaf-6.svg +4 -0
  319. package/assets/svges/lemon-squeezy.svg +6 -0
  320. package/assets/svges/life-guard-tube-1.svg +3 -0
  321. package/assets/svges/line-dashed.svg +5 -0
  322. package/assets/svges/line-dotted.svg +8 -0
  323. package/assets/svges/line-height.svg +7 -0
  324. package/assets/svges/line.svg +3 -0
  325. package/assets/svges/lineicons.svg +6 -0
  326. package/assets/svges/link-2-angular-right.svg +3 -0
  327. package/assets/svges/linkedin.svg +3 -0
  328. package/assets/svges/location-arrow-right.svg +3 -0
  329. package/assets/svges/locked-1.svg +4 -0
  330. package/assets/svges/locked-2.svg +4 -0
  331. package/assets/svges/loom.svg +3 -0
  332. package/assets/svges/magento.svg +4 -0
  333. package/assets/svges/magnet.svg +3 -0
  334. package/assets/svges/mailchimp.svg +3 -0
  335. package/assets/svges/map-marker-1.svg +6 -0
  336. package/assets/svges/map-marker-5.svg +4 -0
  337. package/assets/svges/map-pin-5.svg +3 -0
  338. package/assets/svges/markdown.svg +5 -0
  339. package/assets/svges/mastercard.svg +7 -0
  340. package/assets/svges/medium-alt.svg +3 -0
  341. package/assets/svges/medium.svg +3 -0
  342. package/assets/svges/megaphone-1.svg +3 -0
  343. package/assets/svges/menu-cheesburger.svg +8 -0
  344. package/assets/svges/menu-hamburger-1.svg +5 -0
  345. package/assets/svges/menu-meatballs-1.svg +5 -0
  346. package/assets/svges/menu-meatballs-2.svg +5 -0
  347. package/assets/svges/mercedes.svg +3 -0
  348. package/assets/svges/message-2-question.svg +5 -0
  349. package/assets/svges/message-2.svg +3 -0
  350. package/assets/svges/message-3-text.svg +5 -0
  351. package/assets/svges/meta-alt.svg +3 -0
  352. package/assets/svges/meta.svg +7 -0
  353. package/assets/svges/microphone-1.svg +4 -0
  354. package/assets/svges/microscope.svg +3 -0
  355. package/assets/svges/microsoft-edge.svg +5 -0
  356. package/assets/svges/microsoft-teams.svg +6 -0
  357. package/assets/svges/microsoft.svg +6 -0
  358. package/assets/svges/minus-circle.svg +4 -0
  359. package/assets/svges/minus.svg +3 -0
  360. package/assets/svges/mongodb.svg +3 -0
  361. package/assets/svges/monitor-code.svg +5 -0
  362. package/assets/svges/monitor-mac.svg +3 -0
  363. package/assets/svges/monitor.svg +3 -0
  364. package/assets/svges/moon-half-right-5.svg +3 -0
  365. package/assets/svges/mountains-2.svg +3 -0
  366. package/assets/svges/mouse-2.svg +3 -0
  367. package/assets/svges/mushroom-1.svg +3 -0
  368. package/assets/svges/mushroom-5.svg +6 -0
  369. package/assets/svges/music.svg +3 -0
  370. package/assets/svges/mysql.svg +3 -0
  371. package/assets/svges/nasa.svg +3 -0
  372. package/assets/svges/netflix.svg +3 -0
  373. package/assets/svges/netlify.svg +3 -0
  374. package/assets/svges/next-step-2.svg +3 -0
  375. package/assets/svges/nextjs.svg +3 -0
  376. package/assets/svges/nike.svg +3 -0
  377. package/assets/svges/nissan.svg +3 -0
  378. package/assets/svges/nodejs-alt.svg +3 -0
  379. package/assets/svges/nodejs.svg +3 -0
  380. package/assets/svges/notebook-1.svg +3 -0
  381. package/assets/svges/notion.svg +3 -0
  382. package/assets/svges/npm.svg +3 -0
  383. package/assets/svges/nuxt.svg +3 -0
  384. package/assets/svges/nvidia.svg +3 -0
  385. package/assets/svges/oculus.svg +4 -0
  386. package/assets/svges/open-ai.svg +3 -0
  387. package/assets/svges/opera-mini.svg +3 -0
  388. package/assets/svges/oracle.svg +3 -0
  389. package/assets/svges/outdent.svg +8 -0
  390. package/assets/svges/paddle.svg +3 -0
  391. package/assets/svges/page-break-1.svg +7 -0
  392. package/assets/svges/pagination.svg +7 -0
  393. package/assets/svges/paint-bucket.svg +3 -0
  394. package/assets/svges/paint-roller-1.svg +3 -0
  395. package/assets/svges/paperclip-1.svg +3 -0
  396. package/assets/svges/party-flags.svg +3 -0
  397. package/assets/svges/party-spray.svg +3 -0
  398. package/assets/svges/patreon.svg +3 -0
  399. package/assets/svges/pause.svg +4 -0
  400. package/assets/svges/payoneer.svg +4 -0
  401. package/assets/svges/paypal.svg +4 -0
  402. package/assets/svges/pen-to-square.svg +4 -0
  403. package/assets/svges/pencil-1.svg +3 -0
  404. package/assets/svges/pepsi.svg +4 -0
  405. package/assets/svges/phone.svg +4 -0
  406. package/assets/svges/photos.svg +4 -0
  407. package/assets/svges/php.svg +3 -0
  408. package/assets/svges/pie-chart-2.svg +3 -0
  409. package/assets/svges/pilcrow.svg +3 -0
  410. package/assets/svges/pimjo-logo.svg +9 -0
  411. package/assets/svges/pimjo-symbol.svg +3 -0
  412. package/assets/svges/pinterest.svg +3 -0
  413. package/assets/svges/pizza-2.svg +6 -0
  414. package/assets/svges/placeholder-dollar.svg +4 -0
  415. package/assets/svges/plantscale.svg +3 -0
  416. package/assets/svges/play-store.svg +3 -0
  417. package/assets/svges/play.svg +3 -0
  418. package/assets/svges/playstation.svg +5 -0
  419. package/assets/svges/plug-1.svg +3 -0
  420. package/assets/svges/plus-circle.svg +4 -0
  421. package/assets/svges/plus.svg +3 -0
  422. package/assets/svges/pnpm.svg +10 -0
  423. package/assets/svges/postgresql.svg +3 -0
  424. package/assets/svges/postman.svg +3 -0
  425. package/assets/svges/pound.svg +3 -0
  426. package/assets/svges/power-button.svg +4 -0
  427. package/assets/svges/previous-step-2.svg +3 -0
  428. package/assets/svges/printer.svg +3 -0
  429. package/assets/svges/prisma.svg +3 -0
  430. package/assets/svges/producthunt.svg +4 -0
  431. package/assets/svges/proton-mail-logo.svg +3 -0
  432. package/assets/svges/proton-mail-symbol.svg +3 -0
  433. package/assets/svges/python.svg +3 -0
  434. package/assets/svges/question-mark-circle.svg +5 -0
  435. package/assets/svges/question-mark.svg +4 -0
  436. package/assets/svges/quora.svg +4 -0
  437. package/assets/svges/radis.svg +3 -0
  438. package/assets/svges/react.svg +3 -0
  439. package/assets/svges/reddit.svg +6 -0
  440. package/assets/svges/refresh-circle-1-clockwise.svg +4 -0
  441. package/assets/svges/refresh-dollar-1.svg +5 -0
  442. package/assets/svges/refresh-user-1.svg +6 -0
  443. package/assets/svges/remix-js.svg +4 -0
  444. package/assets/svges/road-1.svg +6 -0
  445. package/assets/svges/rocket-5.svg +5 -0
  446. package/assets/svges/route-1.svg +7 -0
  447. package/assets/svges/rss-right.svg +6 -0
  448. package/assets/svges/ruler-1.svg +3 -0
  449. package/assets/svges/ruler-pen.svg +4 -0
  450. package/assets/svges/rupee.svg +3 -0
  451. package/assets/svges/safari.svg +35 -0
  452. package/assets/svges/sanity.svg +20 -0
  453. package/assets/svges/school-bench-1.svg +4 -0
  454. package/assets/svges/school-bench-2.svg +4 -0
  455. package/assets/svges/scissors-1-vertical.svg +4 -0
  456. package/assets/svges/scoter.svg +8 -0
  457. package/assets/svges/scroll-down-2.svg +6 -0
  458. package/assets/svges/search-1.svg +3 -0
  459. package/assets/svges/search-2.svg +4 -0
  460. package/assets/svges/search-minus.svg +4 -0
  461. package/assets/svges/search-plus.svg +4 -0
  462. package/assets/svges/search-text.svg +5 -0
  463. package/assets/svges/select-cursor-1.svg +10 -0
  464. package/assets/svges/seo-monitor.svg +6 -0
  465. package/assets/svges/service-bell-1.svg +3 -0
  466. package/assets/svges/share-1-circle.svg +4 -0
  467. package/assets/svges/share-1.svg +3 -0
  468. package/assets/svges/share-2.svg +4 -0
  469. package/assets/svges/shield-2-check.svg +4 -0
  470. package/assets/svges/shield-2.svg +3 -0
  471. package/assets/svges/shield-dollar.svg +4 -0
  472. package/assets/svges/shift-left.svg +4 -0
  473. package/assets/svges/shift-right.svg +4 -0
  474. package/assets/svges/ship-1.svg +5 -0
  475. package/assets/svges/shirt-1.svg +3 -0
  476. package/assets/svges/shopify.svg +3 -0
  477. package/assets/svges/shovel.svg +3 -0
  478. package/assets/svges/shuffle.svg +3 -0
  479. package/assets/svges/sign-post-left.svg +3 -0
  480. package/assets/svges/signal-app.svg +3 -0
  481. package/assets/svges/signs-post-2.svg +3 -0
  482. package/assets/svges/sketch.svg +3 -0
  483. package/assets/svges/skype.svg +3 -0
  484. package/assets/svges/slack.svg +10 -0
  485. package/assets/svges/slice-2.svg +3 -0
  486. package/assets/svges/sliders-horizontal-square-2.svg +7 -0
  487. package/assets/svges/slideshare.svg +5 -0
  488. package/assets/svges/snapchat.svg +3 -0
  489. package/assets/svges/sort-alphabetical.svg +5 -0
  490. package/assets/svges/sort-high-to-low.svg +7 -0
  491. package/assets/svges/soundcloud.svg +3 -0
  492. package/assets/svges/spacex.svg +4 -0
  493. package/assets/svges/spellcheck.svg +4 -0
  494. package/assets/svges/spinner-2-sacle.svg +10 -0
  495. package/assets/svges/spinner-3.svg +3 -0
  496. package/assets/svges/sports.svg +3 -0
  497. package/assets/svges/spotify-alt.svg +6 -0
  498. package/assets/svges/spotify.svg +3 -0
  499. package/assets/svges/squarespace.svg +3 -0
  500. package/assets/svges/stackoverflow.svg +8 -0
  501. package/assets/svges/stamp.svg +3 -0
  502. package/assets/svges/star-fat-half-2.svg +4 -0
  503. package/assets/svges/star-fat.svg +3 -0
  504. package/assets/svges/star-sharp-disabled.svg +4 -0
  505. package/assets/svges/statista.svg +3 -0
  506. package/assets/svges/steam.svg +5 -0
  507. package/assets/svges/stethoscope-1.svg +3 -0
  508. package/assets/svges/stopwatch.svg +5 -0
  509. package/assets/svges/storage-hdd-2.svg +4 -0
  510. package/assets/svges/strikethrough-1.svg +5 -0
  511. package/assets/svges/stripe.svg +9 -0
  512. package/assets/svges/stumbleupon.svg +3 -0
  513. package/assets/svges/sun-1.svg +11 -0
  514. package/assets/svges/supabase.svg +5 -0
  515. package/assets/svges/surfboard-2.svg +3 -0
  516. package/assets/svges/svelte.svg +3 -0
  517. package/assets/svges/swift.svg +3 -0
  518. package/assets/svges/tab.svg +4 -0
  519. package/assets/svges/tailwindcss.svg +3 -0
  520. package/assets/svges/target-user.svg +5 -0
  521. package/assets/svges/telegram.svg +3 -0
  522. package/assets/svges/telephone-1.svg +4 -0
  523. package/assets/svges/telephone-3.svg +5 -0
  524. package/assets/svges/tesla.svg +3 -0
  525. package/assets/svges/text-format-remove.svg +5 -0
  526. package/assets/svges/text-format.svg +5 -0
  527. package/assets/svges/text-paragraph.svg +6 -0
  528. package/assets/svges/thumbs-down-3.svg +3 -0
  529. package/assets/svges/thumbs-up-3.svg +3 -0
  530. package/assets/svges/ticket-1.svg +3 -0
  531. package/assets/svges/tickets-3.svg +7 -0
  532. package/assets/svges/tiktok-alt.svg +3 -0
  533. package/assets/svges/tiktok.svg +3 -0
  534. package/assets/svges/tower-broadcast-1.svg +7 -0
  535. package/assets/svges/toyota.svg +4 -0
  536. package/assets/svges/train-1.svg +4 -0
  537. package/assets/svges/train-3.svg +5 -0
  538. package/assets/svges/trash-3.svg +5 -0
  539. package/assets/svges/tree-2.svg +3 -0
  540. package/assets/svges/trees-3.svg +3 -0
  541. package/assets/svges/trello.svg +3 -0
  542. package/assets/svges/trend-down-1.svg +3 -0
  543. package/assets/svges/trend-up-1.svg +3 -0
  544. package/assets/svges/trophy-1.svg +3 -0
  545. package/assets/svges/trowel-1.svg +3 -0
  546. package/assets/svges/truck-delivery-1.svg +3 -0
  547. package/assets/svges/tumblr.svg +3 -0
  548. package/assets/svges/turborepo.svg +4 -0
  549. package/assets/svges/twitch.svg +3 -0
  550. package/assets/svges/twitter-old.svg +3 -0
  551. package/assets/svges/typescript.svg +3 -0
  552. package/assets/svges/uber-symbol.svg +3 -0
  553. package/assets/svges/uber.svg +3 -0
  554. package/assets/svges/ubuntu.svg +3 -0
  555. package/assets/svges/underline.svg +4 -0
  556. package/assets/svges/unlink-2-angular-eft.svg +8 -0
  557. package/assets/svges/unlocked-2.svg +4 -0
  558. package/assets/svges/unsplash.svg +4 -0
  559. package/assets/svges/upload-1.svg +4 -0
  560. package/assets/svges/upload-circle-1.svg +4 -0
  561. package/assets/svges/user-4.svg +4 -0
  562. package/assets/svges/user-multiple-4.svg +6 -0
  563. package/assets/svges/vector-nodes-6.svg +3 -0
  564. package/assets/svges/vector-nodes-7.svg +3 -0
  565. package/assets/svges/vercel.svg +3 -0
  566. package/assets/svges/vimeo.svg +3 -0
  567. package/assets/svges/visa.svg +3 -0
  568. package/assets/svges/vite.svg +6 -0
  569. package/assets/svges/vk.svg +3 -0
  570. package/assets/svges/vmware.svg +4 -0
  571. package/assets/svges/volkswagen.svg +8 -0
  572. package/assets/svges/volume-1.svg +5 -0
  573. package/assets/svges/volume-high.svg +6 -0
  574. package/assets/svges/volume-low.svg +4 -0
  575. package/assets/svges/volume-mute.svg +6 -0
  576. package/assets/svges/volume-off.svg +3 -0
  577. package/assets/svges/vs-code.svg +3 -0
  578. package/assets/svges/vuejs.svg +3 -0
  579. package/assets/svges/wallet-1.svg +3 -0
  580. package/assets/svges/watch-beat-1.svg +4 -0
  581. package/assets/svges/water-drop-1.svg +4 -0
  582. package/assets/svges/webflow.svg +3 -0
  583. package/assets/svges/webhooks.svg +3 -0
  584. package/assets/svges/wechat.svg +4 -0
  585. package/assets/svges/weight-machine-1.svg +4 -0
  586. package/assets/svges/whatsapp.svg +3 -0
  587. package/assets/svges/wheelbarrow-empty.svg +3 -0
  588. package/assets/svges/wheelchair-1.svg +3 -0
  589. package/assets/svges/windows.svg +6 -0
  590. package/assets/svges/wise.svg +3 -0
  591. package/assets/svges/wordpress.svg +3 -0
  592. package/assets/svges/www-cursor.svg +5 -0
  593. package/assets/svges/www.svg +4 -0
  594. package/assets/svges/x.svg +3 -0
  595. package/assets/svges/xampp.svg +5 -0
  596. package/assets/svges/xbox.svg +6 -0
  597. package/assets/svges/xmark-circle.svg +4 -0
  598. package/assets/svges/xmark.svg +3 -0
  599. package/assets/svges/xrp.svg +3 -0
  600. package/assets/svges/yahoo.svg +3 -0
  601. package/assets/svges/yarn.svg +4 -0
  602. package/assets/svges/ycombinator.svg +3 -0
  603. package/assets/svges/yen.svg +3 -0
  604. package/assets/svges/youtube-kids.svg +3 -0
  605. package/assets/svges/youtube-music.svg +4 -0
  606. package/assets/svges/youtube.svg +3 -0
  607. package/assets/svges/zapier.svg +3 -0
  608. package/assets/svges/zero-size.svg +6 -0
  609. package/assets/svges/zoom.svg +4 -0
  610. package/bin/test-svger.js +163 -0
  611. package/dist/__tests__/__mocks__/visual-diff.d.ts +7 -0
  612. package/dist/__tests__/__mocks__/visual-diff.js +13 -0
  613. package/dist/__tests__/fixtures.js +18 -18
  614. package/dist/cli.js +148 -2
  615. package/dist/config.js +4 -1
  616. package/dist/core/enhanced-plugin-manager.d.ts +107 -0
  617. package/dist/core/enhanced-plugin-manager.js +315 -0
  618. package/dist/core/error-handler.d.ts +1 -1
  619. package/dist/core/error-handler.js +14 -17
  620. package/dist/core/framework-templates.js +37 -47
  621. package/dist/core/logger.js +0 -1
  622. package/dist/core/performance-engine.js +10 -15
  623. package/dist/core/plugin-manager.js +4 -4
  624. package/dist/core/style-compiler.d.ts +0 -1
  625. package/dist/core/style-compiler.js +3 -6
  626. package/dist/index.d.ts +4 -0
  627. package/dist/index.js +4 -0
  628. package/dist/integrations/babel.d.ts +1 -1
  629. package/dist/integrations/babel.js +31 -12
  630. package/dist/integrations/jest-preset.js +1 -1
  631. package/dist/integrations/rollup.js +29 -10
  632. package/dist/integrations/vite.js +29 -14
  633. package/dist/integrations/webpack.d.ts +1 -0
  634. package/dist/integrations/webpack.js +29 -10
  635. package/dist/optimizers/advanced-stages.d.ts +40 -0
  636. package/dist/optimizers/advanced-stages.js +297 -0
  637. package/dist/optimizers/basic-cleaner.d.ts +68 -0
  638. package/dist/optimizers/basic-cleaner.js +198 -0
  639. package/dist/optimizers/collapse-useless-groups.d.ts +26 -0
  640. package/dist/optimizers/collapse-useless-groups.js +104 -0
  641. package/dist/optimizers/command-optimizer.d.ts +48 -0
  642. package/dist/optimizers/command-optimizer.js +299 -0
  643. package/dist/optimizers/index.d.ts +14 -0
  644. package/dist/optimizers/index.js +15 -0
  645. package/dist/optimizers/move-attrs-to-parent.d.ts +31 -0
  646. package/dist/optimizers/move-attrs-to-parent.js +115 -0
  647. package/dist/optimizers/numeric-optimizer.d.ts +43 -0
  648. package/dist/optimizers/numeric-optimizer.js +383 -0
  649. package/dist/optimizers/optimizer-pipeline.d.ts +39 -0
  650. package/dist/optimizers/optimizer-pipeline.js +81 -0
  651. package/dist/optimizers/path-deduplicator.d.ts +37 -0
  652. package/dist/optimizers/path-deduplicator.js +406 -0
  653. package/dist/optimizers/path-parser.d.ts +60 -0
  654. package/dist/optimizers/path-parser.js +428 -0
  655. package/dist/optimizers/path-shortener.d.ts +41 -0
  656. package/dist/optimizers/path-shortener.js +274 -0
  657. package/dist/optimizers/path-simplifier.d.ts +30 -0
  658. package/dist/optimizers/path-simplifier.js +326 -0
  659. package/dist/optimizers/remove-hidden-empty.d.ts +29 -0
  660. package/dist/optimizers/remove-hidden-empty.js +130 -0
  661. package/dist/optimizers/remove-unused-defs.d.ts +24 -0
  662. package/dist/optimizers/remove-unused-defs.js +132 -0
  663. package/dist/optimizers/shape-conversion.d.ts +74 -0
  664. package/dist/optimizers/shape-conversion.js +277 -0
  665. package/dist/optimizers/style-optimizer.d.ts +30 -0
  666. package/dist/optimizers/style-optimizer.js +324 -0
  667. package/dist/optimizers/svg-tree-parser.d.ts +55 -0
  668. package/dist/optimizers/svg-tree-parser.js +352 -0
  669. package/dist/optimizers/transform-collapsing.d.ts +38 -0
  670. package/dist/optimizers/transform-collapsing.js +444 -0
  671. package/dist/optimizers/transform-optimizer.d.ts +65 -0
  672. package/dist/optimizers/transform-optimizer.js +320 -0
  673. package/dist/optimizers/tree-serializer.d.ts +46 -0
  674. package/dist/optimizers/tree-serializer.js +190 -0
  675. package/dist/optimizers/tree-stages.d.ts +27 -0
  676. package/dist/optimizers/tree-stages.js +141 -0
  677. package/dist/optimizers/types.d.ts +207 -0
  678. package/dist/optimizers/types.js +122 -0
  679. package/dist/plugins/color-replacer.d.ts +39 -0
  680. package/dist/plugins/color-replacer.js +126 -0
  681. package/dist/plugins/gradient-optimizer.d.ts +33 -0
  682. package/dist/plugins/gradient-optimizer.js +197 -0
  683. package/dist/plugins/stroke-normalizer.d.ts +33 -0
  684. package/dist/plugins/stroke-normalizer.js +166 -0
  685. package/dist/plugins/watermark-remover.d.ts +32 -0
  686. package/dist/plugins/watermark-remover.js +133 -0
  687. package/dist/processors/svg-processor.d.ts +17 -2
  688. package/dist/processors/svg-processor.js +108 -32
  689. package/dist/services/config.d.ts +4 -0
  690. package/dist/services/config.js +62 -1
  691. package/dist/services/file-watcher.d.ts +1 -1
  692. package/dist/services/file-watcher.js +1 -1
  693. package/dist/services/svg-service.d.ts +6 -0
  694. package/dist/services/svg-service.js +66 -16
  695. package/dist/types/index.d.ts +1 -0
  696. package/dist/types/plugin-system.d.ts +153 -0
  697. package/dist/types/plugin-system.js +5 -0
  698. package/dist/utils/visual-diff.d.ts +150 -0
  699. package/dist/utils/visual-diff.js +247 -0
  700. package/dist/watch.js +0 -2
  701. package/docs/COMPLETE-ACHIEVEMENT-SUMMARY.md +401 -0
  702. package/docs/MIGRATION-4.0.0.md +271 -0
  703. package/docs/PIPELINE-INTEGRATION.md +406 -0
  704. package/docs/PLUGIN-DEVELOPMENT-GUIDE.md +807 -0
  705. package/docs/QUICK-REFERENCE.md +176 -0
  706. package/docs/SAMPLE-SVGS-TESTING.md +276 -0
  707. package/docs/archive/PHASE-1-ARCHITECTURE.md +345 -0
  708. package/docs/archive/PHASE-1-IMPLEMENTATION.md +307 -0
  709. package/docs/archive/PHASE-1-SUMMARY.md +298 -0
  710. package/docs/archive/PHASE-2-COMPLETE.md +207 -0
  711. package/docs/archive/PHASE-3-SUMMARY.md +149 -0
  712. package/docs/archive/PHASE-4.3-COMMAND-OPTIMIZER.md +323 -0
  713. package/docs/archive/PHASE-4.4-PATH-SIMPLIFICATION.md +81 -0
  714. package/docs/archive/PHASE-4.5-PATH-DEDUPLICATION.md +449 -0
  715. package/docs/archive/PHASE-5.1-SUCCESS-REPORT.md +207 -0
  716. package/docs/archive/PHASE-5.1-TRANSFORM-COLLAPSING.md +362 -0
  717. package/docs/archive/PHASE-6.1-SHAPE-CONVERSION-DESIGN.md +518 -0
  718. package/docs/archive/PHASE-6.2-PLUGIN-SYSTEM-STATUS.md +403 -0
  719. package/docs/archive/PHASE-6.3-FINAL-STATUS.md +193 -0
  720. package/docs/archive/PHASE-6.3-VALIDATION-PROGRESS.md +345 -0
  721. package/docs/archive/PHASE-6.3-VISUAL-DIFF-DESIGN.md +553 -0
  722. package/docs/archive/PHASE-6.3-VISUAL-DIFF-SUMMARY.md +367 -0
  723. package/docs/archive/PHASE-6.3-XML-SERIALIZATION-FIX.md +210 -0
  724. package/docs/archive/RELEASE-NOTES-3.2.0.md +344 -0
  725. package/docs/archive/RELEASE-PREP-3.2.0.md +376 -0
  726. package/docs/performance/PERFORMANCE-RESULTS.md +31 -0
  727. package/docs/performance/REAL-WORLD-BENCHMARKS.md +159 -0
  728. package/package.json +16 -6
  729. package/DEVELOPMENT.md +0 -353
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Phase 4.2: Path Shortener
3
+ *
4
+ * Responsibilities:
5
+ * 1. Merge consecutive same commands (e.g., L10 20 L30 40 → L10 20 30 40)
6
+ * 2. Convert relative ↔ absolute if shorter (smart size comparison)
7
+ * 3. Replace L with H/V where possible (horizontal/vertical lines)
8
+ * 4. Optimize command sequence for minimal byte size
9
+ */
10
+ import { serializePath, toAbsolute, toRelative, compareAbsoluteRelativeSize, } from './path-parser.js';
11
+ /**
12
+ * Check if two commands can be merged (same type and both absolute or both relative)
13
+ */
14
+ function canMergeCommands(cmd1, cmd2) {
15
+ // Must be same type
16
+ if (cmd1.type !== cmd2.type) {
17
+ return false;
18
+ }
19
+ // Can't merge Z
20
+ if (cmd1.type === 'Z' || cmd1.type === 'z') {
21
+ return false;
22
+ }
23
+ // Only merge commands that support multiple coordinate sets
24
+ const mergeable = ['L', 'l', 'C', 'c', 'S', 's', 'Q', 'q', 'T', 't'];
25
+ return mergeable.includes(cmd1.type);
26
+ }
27
+ /**
28
+ * Merge consecutive commands of the same type
29
+ */
30
+ export function mergeConsecutiveCommands(commands) {
31
+ if (commands.length === 0)
32
+ return commands;
33
+ const merged = [];
34
+ let currentCmd = null;
35
+ for (const cmd of commands) {
36
+ if (!currentCmd) {
37
+ currentCmd = { ...cmd, values: [...cmd.values] };
38
+ continue;
39
+ }
40
+ // Try to merge with current
41
+ if (canMergeCommands(currentCmd, cmd)) {
42
+ // Merge values
43
+ currentCmd.values.push(...cmd.values);
44
+ currentCmd.absolutePosition = cmd.absolutePosition;
45
+ }
46
+ else {
47
+ // Push current and start new
48
+ merged.push(currentCmd);
49
+ currentCmd = { ...cmd, values: [...cmd.values] };
50
+ }
51
+ }
52
+ if (currentCmd) {
53
+ merged.push(currentCmd);
54
+ }
55
+ return merged;
56
+ }
57
+ /**
58
+ * Convert L commands to H/V where beneficial
59
+ * L10 20 → H10 V20 (if horizontal or vertical movement)
60
+ */
61
+ export function convertLtoHV(commands, precision = 3) {
62
+ const optimized = [];
63
+ let prevX = 0;
64
+ let prevY = 0;
65
+ for (const cmd of commands) {
66
+ // Only optimize single-coordinate L/l commands
67
+ if ((cmd.type === 'L' || cmd.type === 'l') && cmd.values.length === 2) {
68
+ const [x, y] = cmd.values;
69
+ if (cmd.type === 'L') {
70
+ // Absolute
71
+ const isHorizontal = Math.abs(y - prevY) < 1e-6;
72
+ const isVertical = Math.abs(x - prevX) < 1e-6;
73
+ if (isHorizontal) {
74
+ // Convert to H
75
+ const hCmd = {
76
+ type: 'H',
77
+ values: [x],
78
+ absolutePosition: cmd.absolutePosition,
79
+ };
80
+ const lSize = serializePath([cmd], precision).length;
81
+ const hSize = serializePath([hCmd], precision).length;
82
+ if (hSize < lSize) {
83
+ optimized.push(hCmd);
84
+ prevX = x;
85
+ prevY = y;
86
+ continue;
87
+ }
88
+ }
89
+ else if (isVertical) {
90
+ // Convert to V
91
+ const vCmd = {
92
+ type: 'V',
93
+ values: [y],
94
+ absolutePosition: cmd.absolutePosition,
95
+ };
96
+ const lSize = serializePath([cmd], precision).length;
97
+ const vSize = serializePath([vCmd], precision).length;
98
+ if (vSize < lSize) {
99
+ optimized.push(vCmd);
100
+ prevX = x;
101
+ prevY = y;
102
+ continue;
103
+ }
104
+ }
105
+ }
106
+ else {
107
+ // Relative l
108
+ const isHorizontal = Math.abs(y) < 1e-6;
109
+ const isVertical = Math.abs(x) < 1e-6;
110
+ if (isHorizontal && x !== 0) {
111
+ // Convert to h
112
+ const hCmd = {
113
+ type: 'h',
114
+ values: [x],
115
+ absolutePosition: cmd.absolutePosition,
116
+ };
117
+ const lSize = serializePath([cmd], precision).length;
118
+ const hSize = serializePath([hCmd], precision).length;
119
+ if (hSize < lSize) {
120
+ optimized.push(hCmd);
121
+ prevX = cmd.absolutePosition.x;
122
+ prevY = cmd.absolutePosition.y;
123
+ continue;
124
+ }
125
+ }
126
+ else if (isVertical && y !== 0) {
127
+ // Convert to v
128
+ const vCmd = {
129
+ type: 'v',
130
+ values: [y],
131
+ absolutePosition: cmd.absolutePosition,
132
+ };
133
+ const lSize = serializePath([cmd], precision).length;
134
+ const vSize = serializePath([vCmd], precision).length;
135
+ if (vSize < lSize) {
136
+ optimized.push(vCmd);
137
+ prevX = cmd.absolutePosition.x;
138
+ prevY = cmd.absolutePosition.y;
139
+ continue;
140
+ }
141
+ }
142
+ }
143
+ }
144
+ // Keep original command
145
+ optimized.push(cmd);
146
+ if (cmd.absolutePosition) {
147
+ prevX = cmd.absolutePosition.x;
148
+ prevY = cmd.absolutePosition.y;
149
+ }
150
+ }
151
+ return optimized;
152
+ }
153
+ /**
154
+ * Convert commands to absolute or relative based on size
155
+ */
156
+ export function optimizeAbsoluteRelative(commands, precision = 3) {
157
+ const optimized = [];
158
+ let prevX = 0;
159
+ let prevY = 0;
160
+ for (const cmd of commands) {
161
+ // M command: first should be absolute, rest can be optimized as L
162
+ if (cmd.type === 'M' || cmd.type === 'm') {
163
+ // First M should typically be absolute
164
+ if (optimized.length === 0) {
165
+ const absCmd = toAbsolute(cmd, prevX, prevY);
166
+ optimized.push(absCmd);
167
+ prevX = absCmd.absolutePosition.x;
168
+ prevY = absCmd.absolutePosition.y;
169
+ continue;
170
+ }
171
+ }
172
+ // Compare sizes
173
+ const diff = compareAbsoluteRelativeSize(cmd, prevX, prevY, precision);
174
+ if (diff > 0) {
175
+ // Relative is shorter
176
+ const relCmd = toRelative(cmd, prevX, prevY);
177
+ optimized.push(relCmd);
178
+ }
179
+ else if (diff < 0) {
180
+ // Absolute is shorter
181
+ const absCmd = toAbsolute(cmd, prevX, prevY);
182
+ optimized.push(absCmd);
183
+ }
184
+ else {
185
+ // Same size, keep original
186
+ optimized.push(cmd);
187
+ }
188
+ // Update position
189
+ if (cmd.absolutePosition) {
190
+ prevX = cmd.absolutePosition.x;
191
+ prevY = cmd.absolutePosition.y;
192
+ }
193
+ }
194
+ return optimized;
195
+ }
196
+ /**
197
+ * Remove redundant commands
198
+ * - Remove M commands that move to current position
199
+ * - Remove L commands with distance 0
200
+ */
201
+ export function removeRedundantCommands(commands) {
202
+ const filtered = [];
203
+ let prevX = 0;
204
+ let prevY = 0;
205
+ for (const cmd of commands) {
206
+ let isRedundant = false;
207
+ // Check for redundant M/m (move to same position)
208
+ if (cmd.type === 'M' && cmd.values.length === 2) {
209
+ const [x, y] = cmd.values;
210
+ if (Math.abs(x - prevX) < 1e-6 && Math.abs(y - prevY) < 1e-6) {
211
+ isRedundant = true;
212
+ }
213
+ }
214
+ else if (cmd.type === 'm' && cmd.values.length === 2) {
215
+ const [dx, dy] = cmd.values;
216
+ if (Math.abs(dx) < 1e-6 && Math.abs(dy) < 1e-6) {
217
+ isRedundant = true;
218
+ }
219
+ }
220
+ // Check for redundant L/l (zero-length line)
221
+ if (cmd.type === 'L' && cmd.values.length === 2) {
222
+ const [x, y] = cmd.values;
223
+ if (Math.abs(x - prevX) < 1e-6 && Math.abs(y - prevY) < 1e-6) {
224
+ isRedundant = true;
225
+ }
226
+ }
227
+ else if (cmd.type === 'l' && cmd.values.length === 2) {
228
+ const [dx, dy] = cmd.values;
229
+ if (Math.abs(dx) < 1e-6 && Math.abs(dy) < 1e-6) {
230
+ isRedundant = true;
231
+ }
232
+ }
233
+ if (!isRedundant) {
234
+ filtered.push(cmd);
235
+ if (cmd.absolutePosition) {
236
+ prevX = cmd.absolutePosition.x;
237
+ prevY = cmd.absolutePosition.y;
238
+ }
239
+ }
240
+ }
241
+ return filtered;
242
+ }
243
+ /**
244
+ * Comprehensive path shortening pipeline
245
+ */
246
+ export function shortenPath(commands, precision = 3) {
247
+ const originalCount = commands.length;
248
+ // Step 1: Remove redundant commands
249
+ let optimized = removeRedundantCommands(commands);
250
+ const removedRedundant = originalCount - optimized.length;
251
+ // Step 2: Merge consecutive same commands
252
+ const beforeMerge = optimized.length;
253
+ optimized = mergeConsecutiveCommands(optimized);
254
+ const mergedCommands = beforeMerge - optimized.length;
255
+ // Step 3: Convert L to H/V where beneficial
256
+ const beforeHV = serializePath(optimized, precision).length;
257
+ optimized = convertLtoHV(optimized, precision);
258
+ const afterHV = serializePath(optimized, precision).length;
259
+ const convertedToHV = beforeHV - afterHV;
260
+ // Step 4: Optimize absolute/relative
261
+ const beforeAbsRel = serializePath(optimized, precision).length;
262
+ optimized = optimizeAbsoluteRelative(optimized, precision);
263
+ const afterAbsRel = serializePath(optimized, precision).length;
264
+ const convertedAbsRel = beforeAbsRel - afterAbsRel;
265
+ return {
266
+ commands: optimized,
267
+ stats: {
268
+ mergedCommands,
269
+ convertedToHV,
270
+ convertedAbsRel,
271
+ removedRedundant,
272
+ },
273
+ };
274
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Phase 4.4: Path Simplification
3
+ *
4
+ * Implements Douglas-Peucker and Visvalingam-Whyatt algorithms for intelligent
5
+ * polyline and polygon simplification. Reduces point count while preserving
6
+ * visual fidelity.
7
+ *
8
+ * Target: 5-15% additional reduction on complex/hand-drawn paths
9
+ *
10
+ * Features:
11
+ * - Douglas-Peucker: Recursive subdivision algorithm (great for angular paths)
12
+ * - Visvalingam-Whyatt: Area-based triangulation (great for smooth curves)
13
+ * - Tolerance-based: Configurable precision vs size tradeoff
14
+ * - Curve-aware: Only simplifies L/H/V commands, preserves C/Q/S/T/A
15
+ */
16
+ import type { OptConfig } from './types.js';
17
+ /**
18
+ * Simplify a path by reducing the number of linear points
19
+ */
20
+ export declare function simplifyPath(pathData: string, config: OptConfig, algorithm?: 'douglas-peucker' | 'visvalingam'): {
21
+ simplified: string;
22
+ pointsRemoved: number;
23
+ };
24
+ /**
25
+ * Optimization stage for path simplification
26
+ */
27
+ export declare function pathSimplificationStage(config: OptConfig): {
28
+ name: string;
29
+ transform(svgContent: string): Promise<string>;
30
+ };
@@ -0,0 +1,326 @@
1
+ /**
2
+ * Phase 4.4: Path Simplification
3
+ *
4
+ * Implements Douglas-Peucker and Visvalingam-Whyatt algorithms for intelligent
5
+ * polyline and polygon simplification. Reduces point count while preserving
6
+ * visual fidelity.
7
+ *
8
+ * Target: 5-15% additional reduction on complex/hand-drawn paths
9
+ *
10
+ * Features:
11
+ * - Douglas-Peucker: Recursive subdivision algorithm (great for angular paths)
12
+ * - Visvalingam-Whyatt: Area-based triangulation (great for smooth curves)
13
+ * - Tolerance-based: Configurable precision vs size tradeoff
14
+ * - Curve-aware: Only simplifies L/H/V commands, preserves C/Q/S/T/A
15
+ */
16
+ import { parsePath, serializePath } from './path-parser.js';
17
+ import { OptLevel } from './types.js';
18
+ /**
19
+ * Calculate perpendicular distance from point to line segment
20
+ */
21
+ function perpendicularDistance(point, lineStart, lineEnd) {
22
+ const dx = lineEnd.x - lineStart.x;
23
+ const dy = lineEnd.y - lineStart.y;
24
+ // Magnitude
25
+ const mag = Math.sqrt(dx * dx + dy * dy);
26
+ if (mag === 0) {
27
+ return Math.sqrt(Math.pow(point.x - lineStart.x, 2) + Math.pow(point.y - lineStart.y, 2));
28
+ }
29
+ // Perpendicular distance
30
+ const u = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (mag * mag);
31
+ if (u < 0) {
32
+ // Closest to start
33
+ return Math.sqrt(Math.pow(point.x - lineStart.x, 2) + Math.pow(point.y - lineStart.y, 2));
34
+ }
35
+ else if (u > 1) {
36
+ // Closest to end
37
+ return Math.sqrt(Math.pow(point.x - lineEnd.x, 2) + Math.pow(point.y - lineEnd.y, 2));
38
+ }
39
+ // Perpendicular point
40
+ const px = lineStart.x + u * dx;
41
+ const py = lineStart.y + u * dy;
42
+ return Math.sqrt(Math.pow(point.x - px, 2) + Math.pow(point.y - py, 2));
43
+ }
44
+ /**
45
+ * Douglas-Peucker algorithm for polyline simplification
46
+ *
47
+ * Recursive subdivision algorithm that finds the point with maximum distance
48
+ * from the line segment and splits there if it exceeds tolerance.
49
+ *
50
+ * Best for: Angular paths, architectural drawings, logos
51
+ * Time: O(n log n) average, O(n²) worst
52
+ */
53
+ function douglasPeucker(points, tolerance) {
54
+ if (points.length <= 2) {
55
+ return points;
56
+ }
57
+ // Find point with maximum distance
58
+ let maxDist = 0;
59
+ let maxIndex = 0;
60
+ const start = points[0];
61
+ const end = points[points.length - 1];
62
+ for (let i = 1; i < points.length - 1; i++) {
63
+ const dist = perpendicularDistance(points[i], start, end);
64
+ if (dist > maxDist) {
65
+ maxDist = dist;
66
+ maxIndex = i;
67
+ }
68
+ }
69
+ // If max distance is greater than tolerance, recursively simplify
70
+ if (maxDist > tolerance) {
71
+ const left = douglasPeucker(points.slice(0, maxIndex + 1), tolerance);
72
+ const right = douglasPeucker(points.slice(maxIndex), tolerance);
73
+ // Combine results (remove duplicate middle point)
74
+ return [...left.slice(0, -1), ...right];
75
+ }
76
+ // All points between start and end can be removed
77
+ return [start, end];
78
+ }
79
+ /**
80
+ * Calculate area of triangle formed by three points
81
+ */
82
+ function triangleArea(p1, p2, p3) {
83
+ return Math.abs((p1.x * (p2.y - p3.y) + p2.x * (p3.y - p1.y) + p3.x * (p1.y - p2.y)) / 2);
84
+ }
85
+ /**
86
+ * Visvalingam-Whyatt algorithm for polyline simplification
87
+ *
88
+ * Progressive removal of points with smallest triangular area. More
89
+ * consistent results than Douglas-Peucker for smooth curves.
90
+ *
91
+ * Best for: Hand-drawn paths, organic shapes, smooth curves
92
+ * Time: O(n log n) with heap, O(n²) with simple implementation
93
+ */
94
+ function visvalingamWhyatt(points, tolerance) {
95
+ if (points.length <= 2) {
96
+ return points;
97
+ }
98
+ // Build initial triangle list
99
+ const triangles = new Array(points.length).fill(null);
100
+ // Calculate areas for all triangles
101
+ for (let i = 1; i < points.length - 1; i++) {
102
+ triangles[i] = {
103
+ index: i,
104
+ area: triangleArea(points[i - 1], points[i], points[i + 1]),
105
+ prev: triangles[i - 1],
106
+ next: null,
107
+ };
108
+ if (triangles[i - 1]) {
109
+ triangles[i - 1].next = triangles[i];
110
+ }
111
+ }
112
+ // Convert tolerance to minimum area threshold
113
+ // Higher tolerance = larger minimum area = more aggressive simplification
114
+ const minArea = tolerance * tolerance;
115
+ // Remove points with smallest area below threshold
116
+ let removed = true;
117
+ while (removed) {
118
+ removed = false;
119
+ let minTriangle = null;
120
+ let minIdx = -1;
121
+ // Find triangle with smallest area
122
+ for (let i = 1; i < points.length - 1; i++) {
123
+ if (triangles[i] && triangles[i].area < minArea) {
124
+ if (!minTriangle || triangles[i].area < minTriangle.area) {
125
+ minTriangle = triangles[i];
126
+ minIdx = i;
127
+ }
128
+ }
129
+ }
130
+ if (minTriangle) {
131
+ // Remove the point
132
+ triangles[minIdx] = null;
133
+ removed = true;
134
+ // Update adjacent triangles
135
+ const prevIdx = minIdx - 1;
136
+ const nextIdx = minIdx + 1;
137
+ // Find previous and next non-null triangles
138
+ let prevNonNull = prevIdx;
139
+ while (prevNonNull >= 0 && !triangles[prevNonNull]) {
140
+ prevNonNull--;
141
+ }
142
+ let nextNonNull = nextIdx;
143
+ while (nextNonNull < triangles.length && !triangles[nextNonNull]) {
144
+ nextNonNull++;
145
+ }
146
+ // Update previous triangle
147
+ if (prevNonNull >= 1 && nextNonNull < points.length) {
148
+ let prevPrevIdx = prevNonNull - 1;
149
+ while (prevPrevIdx >= 0 && !triangles[prevPrevIdx]) {
150
+ prevPrevIdx--;
151
+ }
152
+ if (prevPrevIdx >= 0) {
153
+ triangles[prevNonNull].area = triangleArea(points[prevPrevIdx], points[prevNonNull], points[nextNonNull]);
154
+ }
155
+ }
156
+ // Update next triangle
157
+ if (nextNonNull < points.length - 1) {
158
+ let nextNextIdx = nextNonNull + 1;
159
+ while (nextNextIdx < points.length && !triangles[nextNextIdx]) {
160
+ nextNextIdx++;
161
+ }
162
+ if (nextNextIdx < points.length) {
163
+ triangles[nextNonNull].area = triangleArea(points[prevNonNull], points[nextNonNull], points[nextNextIdx]);
164
+ }
165
+ }
166
+ }
167
+ }
168
+ // Collect remaining points
169
+ return points.filter((_, i) => i === 0 || i === points.length - 1 || triangles[i] !== null);
170
+ }
171
+ /**
172
+ * Convert path commands to point array (only L/H/V commands)
173
+ */
174
+ function extractLinearPoints(commands, startX, startY) {
175
+ const points = [{ x: startX, y: startY, cmdIndex: 0 }];
176
+ const indices = [0];
177
+ let currentX = startX;
178
+ let currentY = startY;
179
+ for (let i = 0; i < commands.length; i++) {
180
+ const cmd = commands[i];
181
+ const isRelative = cmd.type === cmd.type.toLowerCase();
182
+ switch (cmd.type.toUpperCase()) {
183
+ case 'L': {
184
+ const x = isRelative ? currentX + cmd.values[0] : cmd.values[0];
185
+ const y = isRelative ? currentY + cmd.values[1] : cmd.values[1];
186
+ points.push({ x, y, cmdIndex: i + 1 });
187
+ indices.push(i + 1);
188
+ currentX = x;
189
+ currentY = y;
190
+ break;
191
+ }
192
+ case 'H': {
193
+ const x = isRelative ? currentX + cmd.values[0] : cmd.values[0];
194
+ points.push({ x, y: currentY, cmdIndex: i + 1 });
195
+ indices.push(i + 1);
196
+ currentX = x;
197
+ break;
198
+ }
199
+ case 'V': {
200
+ const y = isRelative ? currentY + cmd.values[0] : cmd.values[0];
201
+ points.push({ x: currentX, y, cmdIndex: i + 1 });
202
+ indices.push(i + 1);
203
+ currentY = y;
204
+ break;
205
+ }
206
+ default:
207
+ // Update position for other commands but don't add to points
208
+ if (cmd.type.toUpperCase() === 'M') {
209
+ currentX = isRelative ? currentX + cmd.values[0] : cmd.values[0];
210
+ currentY = isRelative ? currentY + cmd.values[1] : cmd.values[1];
211
+ }
212
+ else if (cmd.type.toUpperCase() === 'C') {
213
+ currentX = isRelative ? currentX + cmd.values[4] : cmd.values[4];
214
+ currentY = isRelative ? currentY + cmd.values[5] : cmd.values[5];
215
+ }
216
+ else if (cmd.type.toUpperCase() === 'Q') {
217
+ currentX = isRelative ? currentX + cmd.values[2] : cmd.values[2];
218
+ currentY = isRelative ? currentY + cmd.values[3] : cmd.values[3];
219
+ }
220
+ break;
221
+ }
222
+ }
223
+ return { points, indices };
224
+ }
225
+ /**
226
+ * Simplify a path by reducing the number of linear points
227
+ */
228
+ export function simplifyPath(pathData, config, algorithm = 'douglas-peucker') {
229
+ const parsed = parsePath(pathData);
230
+ const commands = parsed.commands;
231
+ if (commands.length === 0) {
232
+ return { simplified: pathData, pointsRemoved: 0 };
233
+ }
234
+ // Get tolerance from config
235
+ const tolerance = config.pathTolerance || 0.5;
236
+ let totalPointsRemoved = 0;
237
+ const result = [];
238
+ let i = 0;
239
+ while (i < commands.length) {
240
+ const cmd = commands[i];
241
+ // Always keep M commands
242
+ if (cmd.type.toUpperCase() === 'M') {
243
+ result.push(cmd);
244
+ i++;
245
+ // Find the next M or end of path
246
+ const segmentStart = i;
247
+ let segmentEnd = i;
248
+ while (segmentEnd < commands.length &&
249
+ commands[segmentEnd].type.toUpperCase() !== 'M') {
250
+ segmentEnd++;
251
+ }
252
+ // Extract linear segment
253
+ const segment = commands.slice(segmentStart, segmentEnd);
254
+ const { points } = extractLinearPoints(segment, cmd.values[0], cmd.values[1]);
255
+ // Only simplify if we have enough points
256
+ if (points.length > 2) {
257
+ // Choose algorithm
258
+ const simplified = algorithm === 'visvalingam'
259
+ ? visvalingamWhyatt(points, tolerance)
260
+ : douglasPeucker(points, tolerance);
261
+ totalPointsRemoved += points.length - simplified.length;
262
+ // Convert back to commands (skip first point, it's the M)
263
+ for (let j = 1; j < simplified.length; j++) {
264
+ result.push({
265
+ type: 'L',
266
+ values: [simplified[j].x, simplified[j].y],
267
+ });
268
+ }
269
+ // Add any non-linear commands that were in the segment
270
+ for (let j = 0; j < segment.length; j++) {
271
+ const c = segment[j];
272
+ if (c.type.toUpperCase() !== 'L' &&
273
+ c.type.toUpperCase() !== 'H' &&
274
+ c.type.toUpperCase() !== 'V') {
275
+ result.push(c);
276
+ }
277
+ }
278
+ }
279
+ else {
280
+ // Too few points, keep as-is
281
+ result.push(...segment);
282
+ }
283
+ i = segmentEnd;
284
+ }
285
+ else {
286
+ result.push(cmd);
287
+ i++;
288
+ }
289
+ }
290
+ return {
291
+ simplified: serializePath(result, 2),
292
+ pointsRemoved: totalPointsRemoved,
293
+ };
294
+ }
295
+ /**
296
+ * Optimization stage for path simplification
297
+ */
298
+ export function pathSimplificationStage(config) {
299
+ return {
300
+ name: 'path-simplification',
301
+ async transform(svgContent) {
302
+ if (!config.enablePathSimplification) {
303
+ return svgContent;
304
+ }
305
+ let modified = false;
306
+ let totalPointsRemoved = 0;
307
+ // Choose algorithm based on optimization level
308
+ const algorithm = config.optimizationLevel === OptLevel.MAXIMUM
309
+ ? 'visvalingam'
310
+ : 'douglas-peucker';
311
+ const result = svgContent.replace(/<path[^>]*\sd="([^"]+)"[^>]*>/g, (match, pathData) => {
312
+ const { simplified, pointsRemoved } = simplifyPath(pathData, config, algorithm);
313
+ if (pointsRemoved > 0) {
314
+ modified = true;
315
+ totalPointsRemoved += pointsRemoved;
316
+ return match.replace(`d="${pathData}"`, `d="${simplified}"`);
317
+ }
318
+ return match;
319
+ });
320
+ if (modified) {
321
+ console.log(`[path-simplification] Removed ${totalPointsRemoved} points using ${algorithm}`);
322
+ }
323
+ return result;
324
+ },
325
+ };
326
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Remove Hidden and Empty Elements
3
+ * Drop empty <text>, invisible elements (display:none, visibility:hidden, opacity=0)
4
+ * Recursively check children before removing
5
+ */
6
+ import type { SVGNode } from './svg-tree-parser.js';
7
+ /**
8
+ * Remove hidden and empty elements from tree
9
+ */
10
+ export declare function removeHiddenAndEmptyElements(root: SVGNode): {
11
+ removedCount: number;
12
+ removedNodes: Array<{
13
+ tag: string;
14
+ reason: string;
15
+ }>;
16
+ };
17
+ /**
18
+ * Remove hidden and empty elements stage
19
+ */
20
+ export declare function removeHiddenAndEmptyElementsStage(root: SVGNode): {
21
+ modified: boolean;
22
+ stats: {
23
+ removedCount: number;
24
+ removedNodes: Array<{
25
+ tag: string;
26
+ reason: string;
27
+ }>;
28
+ };
29
+ };