zensical 0.0.12__cp310-abi3-musllinux_1_2_i686.whl → 0.0.17__cp310-abi3-musllinux_1_2_i686.whl

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.

Potentially problematic release.


This version of zensical might be problematic. Click here for more details.

Files changed (307) hide show
  1. zensical/__init__.py +2 -2
  2. zensical/__main__.py +2 -2
  3. zensical/bootstrap/zensical.toml +3 -3
  4. zensical/config.py +111 -34
  5. zensical/extensions/__init__.py +2 -2
  6. zensical/extensions/emoji.py +2 -2
  7. zensical/extensions/links.py +2 -2
  8. zensical/extensions/preview.py +2 -2
  9. zensical/extensions/search.py +3 -3
  10. zensical/extensions/utilities/__init__.py +2 -2
  11. zensical/extensions/utilities/filter.py +2 -2
  12. zensical/main.py +3 -3
  13. zensical/markdown.py +64 -4
  14. zensical/templates/.icons/lucide/LICENSE +39 -0
  15. zensical/templates/.icons/lucide/ampersand.svg +1 -1
  16. zensical/templates/.icons/lucide/anchor.svg +1 -1
  17. zensical/templates/.icons/lucide/balloon.svg +1 -0
  18. zensical/templates/.icons/lucide/birdhouse.svg +1 -0
  19. zensical/templates/.icons/lucide/book-search.svg +1 -0
  20. zensical/templates/.icons/lucide/brush-cleaning.svg +1 -1
  21. zensical/templates/.icons/lucide/bubbles.svg +1 -1
  22. zensical/templates/.icons/lucide/calendar-fold.svg +1 -1
  23. zensical/templates/.icons/lucide/calendars.svg +1 -0
  24. zensical/templates/.icons/lucide/cannabis-off.svg +1 -0
  25. zensical/templates/.icons/lucide/chess-bishop.svg +1 -0
  26. zensical/templates/.icons/lucide/chess-king.svg +1 -0
  27. zensical/templates/.icons/lucide/chess-knight.svg +1 -0
  28. zensical/templates/.icons/lucide/chess-pawn.svg +1 -0
  29. zensical/templates/.icons/lucide/chess-queen.svg +1 -0
  30. zensical/templates/.icons/lucide/chess-rook.svg +1 -0
  31. zensical/templates/.icons/lucide/circle-pile.svg +1 -0
  32. zensical/templates/.icons/lucide/clock-check.svg +1 -0
  33. zensical/templates/.icons/lucide/cloud-backup.svg +1 -0
  34. zensical/templates/.icons/lucide/cloud-sync.svg +1 -0
  35. zensical/templates/.icons/lucide/file-archive.svg +1 -1
  36. zensical/templates/.icons/lucide/file-audio-2.svg +1 -1
  37. zensical/templates/.icons/lucide/file-audio.svg +1 -1
  38. zensical/templates/.icons/lucide/file-axis-3-d.svg +1 -1
  39. zensical/templates/.icons/lucide/file-axis-3d.svg +1 -1
  40. zensical/templates/.icons/lucide/file-badge-2.svg +1 -1
  41. zensical/templates/.icons/lucide/file-badge.svg +1 -1
  42. zensical/templates/.icons/lucide/file-bar-chart-2.svg +1 -1
  43. zensical/templates/.icons/lucide/file-bar-chart.svg +1 -1
  44. zensical/templates/.icons/lucide/file-box.svg +1 -1
  45. zensical/templates/.icons/lucide/file-braces-corner.svg +1 -0
  46. zensical/templates/.icons/lucide/file-braces.svg +1 -0
  47. zensical/templates/.icons/lucide/file-chart-column-increasing.svg +1 -1
  48. zensical/templates/.icons/lucide/file-chart-column.svg +1 -1
  49. zensical/templates/.icons/lucide/file-chart-line.svg +1 -1
  50. zensical/templates/.icons/lucide/file-chart-pie.svg +1 -1
  51. zensical/templates/.icons/lucide/file-check-2.svg +1 -1
  52. zensical/templates/.icons/lucide/file-check-corner.svg +1 -0
  53. zensical/templates/.icons/lucide/file-check.svg +1 -1
  54. zensical/templates/.icons/lucide/file-clock.svg +1 -1
  55. zensical/templates/.icons/lucide/file-code-2.svg +1 -1
  56. zensical/templates/.icons/lucide/file-code-corner.svg +1 -0
  57. zensical/templates/.icons/lucide/file-code.svg +1 -1
  58. zensical/templates/.icons/lucide/file-cog-2.svg +1 -1
  59. zensical/templates/.icons/lucide/file-cog.svg +1 -1
  60. zensical/templates/.icons/lucide/file-diff.svg +1 -1
  61. zensical/templates/.icons/lucide/file-digit.svg +1 -1
  62. zensical/templates/.icons/lucide/file-down.svg +1 -1
  63. zensical/templates/.icons/lucide/file-edit.svg +1 -1
  64. zensical/templates/.icons/lucide/file-exclamation-point.svg +1 -0
  65. zensical/templates/.icons/lucide/file-headphone.svg +1 -0
  66. zensical/templates/.icons/lucide/file-heart.svg +1 -1
  67. zensical/templates/.icons/lucide/file-image.svg +1 -1
  68. zensical/templates/.icons/lucide/file-input.svg +1 -1
  69. zensical/templates/.icons/lucide/file-json-2.svg +1 -1
  70. zensical/templates/.icons/lucide/file-json.svg +1 -1
  71. zensical/templates/.icons/lucide/file-key-2.svg +1 -1
  72. zensical/templates/.icons/lucide/file-key.svg +1 -1
  73. zensical/templates/.icons/lucide/file-line-chart.svg +1 -1
  74. zensical/templates/.icons/lucide/file-lock-2.svg +1 -1
  75. zensical/templates/.icons/lucide/file-lock.svg +1 -1
  76. zensical/templates/.icons/lucide/file-minus-2.svg +1 -1
  77. zensical/templates/.icons/lucide/file-minus-corner.svg +1 -0
  78. zensical/templates/.icons/lucide/file-minus.svg +1 -1
  79. zensical/templates/.icons/lucide/file-music.svg +1 -1
  80. zensical/templates/.icons/lucide/file-output.svg +1 -1
  81. zensical/templates/.icons/lucide/file-pen-line.svg +1 -1
  82. zensical/templates/.icons/lucide/file-pen.svg +1 -1
  83. zensical/templates/.icons/lucide/file-pie-chart.svg +1 -1
  84. zensical/templates/.icons/lucide/file-play.svg +1 -1
  85. zensical/templates/.icons/lucide/file-plus-2.svg +1 -1
  86. zensical/templates/.icons/lucide/file-plus-corner.svg +1 -0
  87. zensical/templates/.icons/lucide/file-plus.svg +1 -1
  88. zensical/templates/.icons/lucide/file-question-mark.svg +1 -1
  89. zensical/templates/.icons/lucide/file-question.svg +1 -1
  90. zensical/templates/.icons/lucide/file-scan.svg +1 -1
  91. zensical/templates/.icons/lucide/file-search-2.svg +1 -1
  92. zensical/templates/.icons/lucide/file-search-corner.svg +1 -0
  93. zensical/templates/.icons/lucide/file-search.svg +1 -1
  94. zensical/templates/.icons/lucide/file-signal.svg +1 -0
  95. zensical/templates/.icons/lucide/file-signature.svg +1 -1
  96. zensical/templates/.icons/lucide/file-sliders.svg +1 -1
  97. zensical/templates/.icons/lucide/file-spreadsheet.svg +1 -1
  98. zensical/templates/.icons/lucide/file-symlink.svg +1 -1
  99. zensical/templates/.icons/lucide/file-terminal.svg +1 -1
  100. zensical/templates/.icons/lucide/file-text.svg +1 -1
  101. zensical/templates/.icons/lucide/file-type-2.svg +1 -1
  102. zensical/templates/.icons/lucide/file-type-corner.svg +1 -0
  103. zensical/templates/.icons/lucide/file-type.svg +1 -1
  104. zensical/templates/.icons/lucide/file-up.svg +1 -1
  105. zensical/templates/.icons/lucide/file-user.svg +1 -1
  106. zensical/templates/.icons/lucide/file-video-2.svg +1 -1
  107. zensical/templates/.icons/lucide/file-video-camera.svg +1 -1
  108. zensical/templates/.icons/lucide/file-video.svg +1 -1
  109. zensical/templates/.icons/lucide/file-volume-2.svg +1 -1
  110. zensical/templates/.icons/lucide/file-volume.svg +1 -1
  111. zensical/templates/.icons/lucide/file-warning.svg +1 -1
  112. zensical/templates/.icons/lucide/file-x-2.svg +1 -1
  113. zensical/templates/.icons/lucide/file-x-corner.svg +1 -0
  114. zensical/templates/.icons/lucide/file-x.svg +1 -1
  115. zensical/templates/.icons/lucide/file.svg +1 -1
  116. zensical/templates/.icons/lucide/files.svg +1 -1
  117. zensical/templates/.icons/lucide/fingerprint-pattern.svg +1 -0
  118. zensical/templates/.icons/lucide/fishing-hook.svg +1 -0
  119. zensical/templates/.icons/lucide/flashlight-off.svg +1 -1
  120. zensical/templates/.icons/lucide/flashlight.svg +1 -1
  121. zensical/templates/.icons/lucide/folder-git-2.svg +1 -1
  122. zensical/templates/.icons/lucide/form.svg +1 -0
  123. zensical/templates/.icons/lucide/gamepad-directional.svg +1 -0
  124. zensical/templates/.icons/lucide/git-branch-minus.svg +1 -0
  125. zensical/templates/.icons/lucide/hd.svg +1 -0
  126. zensical/templates/.icons/lucide/helicopter.svg +1 -0
  127. zensical/templates/.icons/lucide/layers-plus.svg +1 -0
  128. zensical/templates/.icons/lucide/memory-stick.svg +1 -1
  129. zensical/templates/.icons/lucide/microchip.svg +1 -1
  130. zensical/templates/.icons/lucide/mouse-pointer-2-off.svg +1 -0
  131. zensical/templates/.icons/lucide/paint-bucket.svg +1 -1
  132. zensical/templates/.icons/lucide/plug.svg +1 -1
  133. zensical/templates/.icons/lucide/ruler-dimension-line.svg +1 -1
  134. zensical/templates/.icons/lucide/scale.svg +1 -1
  135. zensical/templates/.icons/lucide/scissors-square-dashed-bottom.svg +1 -1
  136. zensical/templates/.icons/lucide/scissors-square.svg +1 -1
  137. zensical/templates/.icons/lucide/scooter.svg +1 -0
  138. zensical/templates/.icons/lucide/search-alert.svg +1 -0
  139. zensical/templates/.icons/lucide/shredder.svg +1 -1
  140. zensical/templates/.icons/lucide/solar-panel.svg +1 -0
  141. zensical/templates/.icons/lucide/square-bottom-dashed-scissors.svg +1 -1
  142. zensical/templates/.icons/lucide/square-scissors.svg +1 -1
  143. zensical/templates/.icons/lucide/sticker.svg +1 -1
  144. zensical/templates/.icons/lucide/sticky-note.svg +1 -1
  145. zensical/templates/.icons/lucide/stone.svg +1 -0
  146. zensical/templates/.icons/lucide/thermometer-sun.svg +1 -1
  147. zensical/templates/.icons/lucide/thumbs-down.svg +1 -1
  148. zensical/templates/.icons/lucide/thumbs-up.svg +1 -1
  149. zensical/templates/.icons/lucide/tickets-plane.svg +1 -1
  150. zensical/templates/.icons/lucide/tickets.svg +1 -1
  151. zensical/templates/.icons/lucide/toolbox.svg +1 -0
  152. zensical/templates/.icons/lucide/van.svg +1 -0
  153. zensical/templates/.icons/lucide/waves-arrow-down.svg +1 -0
  154. zensical/templates/.icons/lucide/waves-arrow-up.svg +1 -0
  155. zensical/templates/.icons/lucide/weight-tilde.svg +1 -0
  156. zensical/templates/.icons/octicons/boolean-off-16.svg +1 -0
  157. zensical/templates/.icons/octicons/boolean-off-24.svg +1 -0
  158. zensical/templates/.icons/octicons/boolean-on-16.svg +1 -0
  159. zensical/templates/.icons/octicons/boolean-on-24.svg +1 -0
  160. zensical/templates/.icons/octicons/compose-16.svg +1 -0
  161. zensical/templates/.icons/octicons/compose-24.svg +1 -0
  162. zensical/templates/.icons/octicons/crosshairs-16.svg +1 -0
  163. zensical/templates/.icons/octicons/crosshairs-24.svg +1 -0
  164. zensical/templates/.icons/octicons/dice-16.svg +1 -0
  165. zensical/templates/.icons/octicons/dice-24.svg +1 -0
  166. zensical/templates/.icons/octicons/exclamation-16.svg +1 -0
  167. zensical/templates/.icons/octicons/exclamation-24.svg +1 -0
  168. zensical/templates/.icons/octicons/file-check-16.svg +1 -0
  169. zensical/templates/.icons/octicons/file-check-24.svg +1 -0
  170. zensical/templates/.icons/octicons/flowchart-16.svg +1 -0
  171. zensical/templates/.icons/octicons/flowchart-24.svg +1 -0
  172. zensical/templates/.icons/octicons/focus-center-16.svg +1 -0
  173. zensical/templates/.icons/octicons/focus-center-24.svg +1 -0
  174. zensical/templates/.icons/octicons/git-branch-check-16.svg +1 -0
  175. zensical/templates/.icons/octicons/git-branch-check-24.svg +1 -0
  176. zensical/templates/.icons/octicons/graph-bar-horizontal-16.svg +1 -0
  177. zensical/templates/.icons/octicons/graph-bar-horizontal-24.svg +1 -0
  178. zensical/templates/.icons/octicons/graph-bar-vertical-16.svg +1 -0
  179. zensical/templates/.icons/octicons/graph-bar-vertical-24.svg +1 -0
  180. zensical/templates/.icons/octicons/inbox-fill-16.svg +1 -0
  181. zensical/templates/.icons/octicons/inbox-fill-24.svg +1 -0
  182. zensical/templates/.icons/octicons/node-16.svg +1 -0
  183. zensical/templates/.icons/octicons/node-24.svg +1 -0
  184. zensical/templates/.icons/octicons/pencil-ai-16.svg +1 -0
  185. zensical/templates/.icons/octicons/pencil-ai-24.svg +1 -0
  186. zensical/templates/.icons/octicons/smiley-frown-16.svg +1 -0
  187. zensical/templates/.icons/octicons/smiley-frown-24.svg +1 -0
  188. zensical/templates/.icons/octicons/smiley-frustrated-16.svg +1 -0
  189. zensical/templates/.icons/octicons/smiley-frustrated-24.svg +1 -0
  190. zensical/templates/.icons/octicons/smiley-grin-16.svg +1 -0
  191. zensical/templates/.icons/octicons/smiley-grin-24.svg +1 -0
  192. zensical/templates/.icons/octicons/smiley-neutral-16.svg +1 -0
  193. zensical/templates/.icons/octicons/smiley-neutral-24.svg +1 -0
  194. zensical/templates/.icons/octicons/spacing-large-16.svg +1 -0
  195. zensical/templates/.icons/octicons/spacing-large-24.svg +1 -0
  196. zensical/templates/.icons/octicons/spacing-medium-16.svg +1 -0
  197. zensical/templates/.icons/octicons/spacing-medium-24.svg +1 -0
  198. zensical/templates/.icons/octicons/spacing-small-16.svg +1 -0
  199. zensical/templates/.icons/octicons/spacing-small-24.svg +1 -0
  200. zensical/templates/.icons/octicons/split-view-16.svg +1 -0
  201. zensical/templates/.icons/octicons/split-view-24.svg +1 -0
  202. zensical/templates/.icons/octicons/unwrap-16.svg +1 -0
  203. zensical/templates/.icons/octicons/unwrap-24.svg +1 -0
  204. zensical/templates/.icons/octicons/vscode-16.svg +1 -1
  205. zensical/templates/.icons/octicons/vscode-32.svg +1 -1
  206. zensical/templates/.icons/octicons/vscode-48.svg +1 -1
  207. zensical/templates/.icons/octicons/wrap-16.svg +1 -0
  208. zensical/templates/.icons/octicons/wrap-24.svg +1 -0
  209. zensical/templates/.icons/simple/acode.svg +1 -0
  210. zensical/templates/.icons/simple/apacheavro.svg +1 -0
  211. zensical/templates/.icons/simple/appimage.svg +1 -0
  212. zensical/templates/.icons/simple/appmanager.svg +1 -0
  213. zensical/templates/.icons/simple/autentique.svg +1 -0
  214. zensical/templates/.icons/simple/b4x.svg +1 -0
  215. zensical/templates/.icons/simple/bioconductor.svg +1 -0
  216. zensical/templates/.icons/simple/coolify.svg +1 -0
  217. zensical/templates/.icons/simple/cursor.svg +1 -0
  218. zensical/templates/.icons/simple/dash0.svg +1 -0
  219. zensical/templates/.icons/simple/dodopayments.svg +1 -0
  220. zensical/templates/.icons/simple/elk.svg +1 -0
  221. zensical/templates/.icons/simple/fishaudio.svg +1 -0
  222. zensical/templates/.icons/simple/ghostty.svg +1 -0
  223. zensical/templates/.icons/simple/glance.svg +1 -0
  224. zensical/templates/.icons/simple/hashcat.svg +1 -0
  225. zensical/templates/.icons/simple/kando.svg +1 -0
  226. zensical/templates/.icons/simple/labex.svg +1 -0
  227. zensical/templates/.icons/simple/listenhub.svg +1 -0
  228. zensical/templates/.icons/simple/luanti.svg +1 -0
  229. zensical/templates/.icons/simple/maas.svg +1 -1
  230. zensical/templates/.icons/simple/mailbox.svg +1 -0
  231. zensical/templates/.icons/simple/mangacollec.svg +1 -0
  232. zensical/templates/.icons/simple/mdblist.svg +1 -0
  233. zensical/templates/.icons/simple/minimax.svg +1 -0
  234. zensical/templates/.icons/simple/newgrounds.svg +1 -0
  235. zensical/templates/.icons/simple/nodegui.svg +1 -0
  236. zensical/templates/.icons/simple/openrouter.svg +1 -0
  237. zensical/templates/.icons/simple/passbolt.svg +1 -0
  238. zensical/templates/.icons/simple/plane.svg +1 -0
  239. zensical/templates/.icons/simple/postiz.svg +1 -0
  240. zensical/templates/.icons/simple/qlty.svg +1 -0
  241. zensical/templates/.icons/simple/rekaui.svg +1 -0
  242. zensical/templates/.icons/simple/retroachievements.svg +1 -0
  243. zensical/templates/.icons/simple/root.svg +1 -0
  244. zensical/templates/.icons/simple/setuptools.svg +1 -0
  245. zensical/templates/.icons/simple/tanstack.svg +1 -0
  246. zensical/templates/.icons/simple/textual.svg +1 -0
  247. zensical/templates/assets/javascripts/LICENSE +29 -0
  248. zensical/templates/assets/javascripts/bundle.8ffeb9c9.min.js +3 -0
  249. zensical/templates/assets/javascripts/workers/search.e2d2d235.min.js +1 -0
  250. zensical/templates/assets/stylesheets/classic/main.9a39631f.min.css +1 -0
  251. zensical/templates/assets/stylesheets/modern/main.d4922b3c.min.css +1 -0
  252. zensical/templates/base.html +4 -4
  253. zensical/zensical.abi3.so +0 -0
  254. zensical/zensical.pyi +2 -2
  255. {zensical-0.0.12.dist-info → zensical-0.0.17.dist-info}/METADATA +4 -4
  256. {zensical-0.0.12.dist-info → zensical-0.0.17.dist-info}/RECORD +261 -171
  257. {zensical-0.0.12.dist-info → zensical-0.0.17.dist-info}/WHEEL +1 -1
  258. {zensical-0.0.12.dist-info → zensical-0.0.17.dist-info}/licenses/LICENSE.md +1 -1
  259. zensical/templates/.icons/simple/aerlingus.svg +0 -1
  260. zensical/templates/.icons/simple/aerospike.svg +0 -1
  261. zensical/templates/.icons/simple/aew.svg +0 -1
  262. zensical/templates/.icons/simple/affinity.svg +0 -1
  263. zensical/templates/.icons/simple/affinitydesigner.svg +0 -1
  264. zensical/templates/.icons/simple/affinityphoto.svg +0 -1
  265. zensical/templates/.icons/simple/affinitypublisher.svg +0 -1
  266. zensical/templates/.icons/simple/alfaromeo.svg +0 -1
  267. zensical/templates/.icons/simple/allocine.svg +0 -1
  268. zensical/templates/.icons/simple/alteryx.svg +0 -1
  269. zensical/templates/.icons/simple/altiumdesigner.svg +0 -1
  270. zensical/templates/.icons/simple/alx.svg +0 -1
  271. zensical/templates/.icons/simple/authy.svg +0 -1
  272. zensical/templates/.icons/simple/canva.svg +0 -1
  273. zensical/templates/.icons/simple/codepen.svg +0 -1
  274. zensical/templates/.icons/simple/cognizant.svg +0 -1
  275. zensical/templates/.icons/simple/dbt.svg +0 -1
  276. zensical/templates/.icons/simple/flipkart.svg +0 -1
  277. zensical/templates/.icons/simple/googlefit.svg +0 -1
  278. zensical/templates/.icons/simple/heroku.svg +0 -1
  279. zensical/templates/.icons/simple/informatica.svg +0 -1
  280. zensical/templates/.icons/simple/invision.svg +0 -1
  281. zensical/templates/.icons/simple/jaguar.svg +0 -1
  282. zensical/templates/.icons/simple/landrover.svg +0 -1
  283. zensical/templates/.icons/simple/logitech.svg +0 -1
  284. zensical/templates/.icons/simple/logitechg.svg +0 -1
  285. zensical/templates/.icons/simple/mailboxdotorg.svg +0 -1
  286. zensical/templates/.icons/simple/minetest.svg +0 -1
  287. zensical/templates/.icons/simple/mulesoft.svg +0 -1
  288. zensical/templates/.icons/simple/musescore.svg +0 -1
  289. zensical/templates/.icons/simple/nexusmods.svg +0 -1
  290. zensical/templates/.icons/simple/openai.svg +0 -1
  291. zensical/templates/.icons/simple/pocket.svg +0 -1
  292. zensical/templates/.icons/simple/quip.svg +0 -1
  293. zensical/templates/.icons/simple/salesforce.svg +0 -1
  294. zensical/templates/.icons/simple/scribd.svg +0 -1
  295. zensical/templates/.icons/simple/sendgrid.svg +0 -1
  296. zensical/templates/.icons/simple/shutterstock.svg +0 -1
  297. zensical/templates/.icons/simple/slack.svg +0 -1
  298. zensical/templates/.icons/simple/tunein.svg +0 -1
  299. zensical/templates/.icons/simple/twilio.svg +0 -1
  300. zensical/templates/.icons/simple/walmart.svg +0 -1
  301. zensical/templates/.icons/simple/warnerbros.svg +0 -1
  302. zensical/templates/.icons/simple/westerndigital.svg +0 -1
  303. zensical/templates/assets/javascripts/bundle.21aa498e.min.js +0 -3
  304. zensical/templates/assets/javascripts/workers/search.5df7522c.min.js +0 -1
  305. zensical/templates/assets/stylesheets/classic/main.6f483be1.min.css +0 -1
  306. zensical/templates/assets/stylesheets/modern/main.09f707be.min.css +0 -1
  307. {zensical-0.0.12.dist-info → zensical-0.0.17.dist-info}/entry_points.txt +0 -0
zensical/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
zensical/__main__.py CHANGED
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -34,7 +34,7 @@ site_author = "<your name here>"
34
34
  #
35
35
  # Read more: https://zensical.org/docs/setup/basics/#copyright
36
36
  copyright = """
37
- Copyright &copy; 2025 The authors
37
+ Copyright &copy; 2026 The authors
38
38
  """
39
39
 
40
40
  # Zensical supports both implicit navigation and explicitly defined navigation.
@@ -118,13 +118,13 @@ features = [
118
118
  # https://zensical.org/docs/setup/header/#announcement-bar
119
119
  "announce.dismiss",
120
120
 
121
- # If you have a repository configured and turn feature this on, Zensical
121
+ # If you have a repository configured and turn on this feature, Zensical
122
122
  # will generate an edit button for the page. This works for common
123
123
  # repository hosting services.
124
124
  # https://zensical.org/docs/setup/repository/#code-actions
125
125
  #"content.action.edit",
126
126
 
127
- # If you have a repository configured and turn feature this on, Zensical
127
+ # If you have a repository configured and turn on this feature, Zensical
128
128
  # will generate a button that allows the user to view the Markdown
129
129
  # code for the current page.
130
130
  # https://zensical.org/docs/setup/repository/#code-actions
zensical/config.py CHANGED
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -26,6 +26,7 @@ from __future__ import annotations
26
26
  import hashlib
27
27
  import importlib
28
28
  import os
29
+ from pathlib import Path
29
30
  import pickle
30
31
  from typing import IO, Any
31
32
  from urllib.parse import urlparse
@@ -118,6 +119,16 @@ def get_theme_dir() -> str:
118
119
  return os.path.join(path, "templates")
119
120
 
120
121
 
122
+ def get_custom_theme_dir(config: dict) -> str | None:
123
+ """Return the custom theme directory."""
124
+ path = os.path.dirname(os.path.abspath(__file__))
125
+ if config["theme"].get("custom_dir"):
126
+ return os.path.join(path, config["theme"].get("custom_dir"))
127
+
128
+ # Otherwise, return no path
129
+ return None
130
+
131
+
121
132
  def _apply_defaults(config: dict, path: str) -> dict:
122
133
  """Apply default settings in configuration.
123
134
 
@@ -161,20 +172,21 @@ def _apply_defaults(config: dict, path: str) -> dict:
161
172
  repo_names = {
162
173
  "github.com": "GitHub",
163
174
  "gitlab.com": "Gitlab",
164
- "bitbucket.org": "Bitbucket"
175
+ "bitbucket.org": "Bitbucket",
165
176
  }
166
177
  edit_uris = {
167
178
  "github.com": f"edit/master/{docs_dir}",
168
179
  "gitlab.com": f"edit/master/{docs_dir}",
169
- "bitbucket.org": f"src/default/{docs_dir}"
180
+ "bitbucket.org": f"src/default/{docs_dir}",
170
181
  }
171
182
  repo_url = config.get("repo_url")
172
183
  if repo_url:
173
184
  host = urlparse(repo_url).hostname or ""
174
- if not config.get("repo_name") and host in repo_names:
175
- set_default(config, "repo_name", repo_names[host], str)
176
- elif host:
177
- config["repo_name"] = host.split(".")[0].title()
185
+ if not config.get("repo_name"):
186
+ if host in repo_names:
187
+ set_default(config, "repo_name", repo_names[host], str)
188
+ elif host:
189
+ config["repo_name"] = host.split(".")[0].title()
178
190
  if host in edit_uris:
179
191
  set_default(config, "edit_uri", edit_uris[host], str)
180
192
 
@@ -251,18 +263,12 @@ def _apply_defaults(config: dict, path: str) -> dict:
251
263
 
252
264
  # Set defaults for theme admonition icons
253
265
  admonition = set_default(icon, "admonition", {}, dict)
254
- set_default(admonition, "note", None, str)
255
- set_default(admonition, "abstract", None, str)
256
- set_default(admonition, "info", None, str)
257
- set_default(admonition, "tip", None, str)
258
- set_default(admonition, "success", None, str)
259
- set_default(admonition, "question", None, str)
260
- set_default(admonition, "warning", None, str)
261
- set_default(admonition, "failure", None, str)
262
- set_default(admonition, "danger", None, str)
263
- set_default(admonition, "bug", None, str)
264
- set_default(admonition, "example", None, str)
265
- set_default(admonition, "quote", None, str)
266
+ if isinstance(admonition, dict):
267
+ icon["admonition"] = {
268
+ str(key): str(value)
269
+ for key, value in admonition.items()
270
+ if value is not None
271
+ }
266
272
 
267
273
  # Set defaults for theme palette settings and normalize to list
268
274
  palette = theme.setdefault("palette", [])
@@ -286,11 +292,15 @@ def _apply_defaults(config: dict, path: str) -> dict:
286
292
 
287
293
  # Set defaults for extra settings
288
294
  if "extra" in config and not isinstance(config["extra"], dict):
289
- raise ConfigurationError("The 'extra' setting must be a mapping/dictionary.")
295
+ raise ConfigurationError(
296
+ "The 'extra' setting must be a mapping/dictionary."
297
+ )
290
298
  extra = set_default(config, "extra", {}, dict)
291
299
 
292
300
  if "polyfills" in extra and not isinstance(extra["polyfills"], list):
293
- raise ConfigurationError("The 'extra.polyfills' setting must be a list.")
301
+ raise ConfigurationError(
302
+ "The 'extra.polyfills' setting must be a list."
303
+ )
294
304
  set_default(extra, "polyfills", [], list)
295
305
 
296
306
  # Ensure all non-existent values are all empty strings (for now)
@@ -368,7 +378,9 @@ def _apply_defaults(config: dict, path: str) -> dict:
368
378
  tabbed = config["mdx_configs"].get("pymdownx.tabbed", {})
369
379
  if isinstance(tabbed.get("slugify"), dict):
370
380
  object = tabbed["slugify"].get("object", "pymdownx.slugs.slugify")
371
- tabbed["slugify"] = _resolve(object)(**tabbed["slugify"].get("kwds", {}))
381
+ tabbed["slugify"] = _resolve(object)(
382
+ **tabbed["slugify"].get("kwds", {})
383
+ )
372
384
 
373
385
  # Table of contents extension configuration - resolve slugification function
374
386
  toc = config["mdx_configs"]["toc"]
@@ -382,14 +394,22 @@ def _apply_defaults(config: dict, path: str) -> dict:
382
394
  if isinstance(fence.get("format"), str):
383
395
  fence["format"] = _resolve(fence.get("format"))
384
396
  elif isinstance(fence.get("format"), dict):
385
- object = fence["format"].get("object", "pymdownx.superfences.fence_code_format")
386
- fence["format"] = _resolve(object)(**fence["format"].get("kwds", {}))
397
+ object = fence["format"].get(
398
+ "object", "pymdownx.superfences.fence_code_format"
399
+ )
400
+ fence["format"] = _resolve(object)(
401
+ **fence["format"].get("kwds", {})
402
+ )
387
403
  if isinstance(fence.get("validator"), str):
388
404
  fence["validator"] = _resolve(fence.get("validator"))
389
405
  elif isinstance(fence.get("validator"), dict):
390
406
  object = fence["validator"].get("object")
391
- callable_object = _resolve(object) if object else lambda *args, **kwargs: True
392
- fence["validator"] = callable_object(**fence["validator"].get("kwds", {}))
407
+ callable_object = (
408
+ _resolve(object) if object else lambda *args, **kwargs: True
409
+ )
410
+ fence["validator"] = callable_object(
411
+ **fence["validator"].get("kwds", {})
412
+ )
393
413
 
394
414
  # Ensure the table of contents title is initialized, as it's used inside
395
415
  # the template, and the table of contents extension is always defined
@@ -399,7 +419,7 @@ def _apply_defaults(config: dict, path: str) -> dict:
399
419
  # Convert plugins configuration
400
420
  config["plugins"] = _convert_plugins(config.get("plugins", []), config)
401
421
 
402
- # mkdocstrings configuration
422
+ # Set up mkdocstrings, which touches plugins and Markdown extensions
403
423
  if "mkdocstrings" in config["plugins"]:
404
424
  mkdocstrings_config = config["plugins"]["mkdocstrings"]["config"]
405
425
  if mkdocstrings_config.pop("enabled", True):
@@ -409,13 +429,21 @@ def _apply_defaults(config: dict, path: str) -> dict:
409
429
  config["markdown_extensions"].append("mkdocstrings")
410
430
  config["mdx_configs"]["mkdocstrings"] = mkdocstrings_config
411
431
 
432
+ # List all source files for mkdocstrings
433
+ config["source_files"] = _list_sources(config, path)
434
+
435
+ # Hash all templates, so we rebuild if something changes
436
+ config["template_hash"] = _hash(_list_templates(config))
412
437
  return config
413
438
 
414
439
 
415
440
  def set_default(
416
441
  entry: dict, key: str, default: Any, data_type: type | None = None
417
442
  ) -> Any:
418
- """Set a key to a default value if it isn't set, and optionally cast it to the specified data type."""
443
+ """Set a key to a default value if it isn't set.
444
+
445
+ Optionally cast it to the specified data type.
446
+ """
419
447
  if key in entry and entry[key] is None:
420
448
  del entry[key]
421
449
 
@@ -441,8 +469,56 @@ def _hash(data: Any) -> int:
441
469
  return int(hash.hexdigest(), 16) % (2**64)
442
470
 
443
471
 
472
+ def _list_sources(config: dict, config_file: str) -> list[tuple[str, int]]:
473
+ """List all absolute links to source files for mkdocstrings."""
474
+ python_paths = (
475
+ config["plugins"]
476
+ .get("mkdocstrings", {})
477
+ .get("config", {})
478
+ .get("handlers", {})
479
+ .get("python", {})
480
+ .get("paths", ())
481
+ )
482
+ roots_with_hash = []
483
+ for python_path in python_paths:
484
+ path = Path(config_file).parent.joinpath(python_path).resolve()
485
+
486
+ # Collect all files under this root with modification times to detect
487
+ # changes. We'll replace this with proper dependency tracking later.
488
+ files = [(path, int(os.path.getmtime(path)))]
489
+ if path.is_dir():
490
+ for subpath in path.rglob("*"):
491
+ files.extend([(subpath, int(os.path.getmtime(subpath)))])
492
+ roots_with_hash.append((str(path), _hash(files)))
493
+
494
+ return sorted(roots_with_hash)
495
+
496
+
497
+ def _list_templates(config: dict) -> list[tuple[str, int]]:
498
+ """List all template files in the theme directories."""
499
+ dirs = [get_theme_dir()]
500
+ if "custom_dir" in config["theme"]:
501
+ custom_dir = get_custom_theme_dir(config)
502
+ if custom_dir is not None:
503
+ dirs.append(custom_dir)
504
+
505
+ # Collect file paths and their mtimes
506
+ files_with_mtime = []
507
+ for directory in dirs:
508
+ for path, _, files in os.walk(directory):
509
+ if ".icons" in path:
510
+ continue
511
+ for file in files:
512
+ file_path = os.path.join(path, file)
513
+ mtime = int(os.path.getmtime(file_path))
514
+ files_with_mtime.append((file_path, mtime))
515
+
516
+ # Sort by file path for deterministic order
517
+ return sorted(files_with_mtime)
518
+
519
+
444
520
  def _convert_extra(data: dict | list) -> dict | list:
445
- """Recursively convert all None values in a dictionary or list to empty strings."""
521
+ """Recursively convert None values in a dictionary/list to empty strings."""
446
522
  if isinstance(data, dict):
447
523
  # Process each key-value pair in the dictionary
448
524
  return {
@@ -478,7 +554,7 @@ def _convert_nav(nav: list) -> list:
478
554
 
479
555
 
480
556
  def _convert_nav_item(item: str | dict | list) -> dict | list:
481
- """Convert MkDocs shorthand navigation structure into something more manageable.
557
+ """Convert MkDocs shorthand navigation structure into something manageable.
482
558
 
483
559
  We need to annotate each item with a title, URL, icon, and children.
484
560
  """
@@ -559,7 +635,7 @@ def _convert_extra_javascript(value: list) -> list:
559
635
 
560
636
 
561
637
  def _convert_markdown_extensions(value: Any) -> tuple[list[str], dict]:
562
- """Convert Markdown extensions configuration to what Python Markdown expects."""
638
+ """Convert Markdown extensions to what Python Markdown expects."""
563
639
  markdown_extensions = ["toc", "tables"]
564
640
  mdx_configs: dict[str, dict[str, Any]] = {"toc": {}, "tables": {}}
565
641
 
@@ -674,7 +750,7 @@ def _convert_plugins(value: Any, config: dict) -> dict:
674
750
  def _yaml_load(
675
751
  source: IO, loader: type[BaseLoader] | None = None
676
752
  ) -> dict[str, Any]:
677
- """Load configuration file and resolve environment variables and parent files.
753
+ """Load configuration file, resolve environment variables and parent files.
678
754
 
679
755
  Note that INHERIT is only a bandaid that was introduced to allow for some
680
756
  degree of modularity, but with serious shortcomings. Zensical will use a
@@ -706,7 +782,8 @@ def _yaml_load(
706
782
  )
707
783
  if not os.path.exists(abspath):
708
784
  raise ConfigurationError(
709
- f"Inherited config file '{relpath}' doesn't exist at '{abspath}'."
785
+ f"Inherited config file '{relpath}' "
786
+ f"doesn't exist at '{abspath}'."
710
787
  )
711
788
  with open(abspath, encoding="utf-8") as fd:
712
789
  parent = _yaml_load(fd, loader)
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -34,7 +34,7 @@ from markdown.postprocessors import Postprocessor
34
34
 
35
35
 
36
36
  class SearchProcessor(Postprocessor):
37
- """Post processor that extracts searchable content from the rendered HTML."""
37
+ """Post processor to extract searchable content from the rendered HTML."""
38
38
 
39
39
  def __init__(self, md: Markdown) -> None:
40
40
  super().__init__(md)
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
zensical/main.py CHANGED
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -135,7 +135,7 @@ def execute_serve(config_file: str | None, **kwargs: Any) -> None:
135
135
  required=False,
136
136
  )
137
137
  def new_project(directory: str | None, **kwargs: Any) -> None: # noqa: ARG001
138
- """Create a new template project in the current directory or in the given directory.
138
+ """Create a new template project in the current or given directory.
139
139
 
140
140
  Raises:
141
141
  ClickException: if the directory already contains a zensical.toml or a
zensical/markdown.py CHANGED
@@ -1,7 +1,7 @@
1
- # Copyright (c) 2025 Zensical and contributors
1
+ # Copyright (c) 2025-2026 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under DCO
4
+ # All contributions are certified under the DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -28,7 +28,9 @@ from datetime import date, datetime
28
28
  from typing import TYPE_CHECKING, Any
29
29
 
30
30
  import yaml
31
+ from markdown import Extension as MarkdownExtension
31
32
  from markdown import Markdown
33
+ from markdown.preprocessors import Preprocessor
32
34
  from yaml import SafeLoader
33
35
 
34
36
  from zensical.config import get_config
@@ -51,12 +53,46 @@ FRONT_MATTER_RE = re.compile(
51
53
  Regex pattern to extract front matter.
52
54
  """
53
55
 
56
+
57
+ # ----------------------------------------------------------------------------
58
+ # Classes
59
+ # ----------------------------------------------------------------------------
60
+
61
+
62
+ class CurrentPageData(Preprocessor):
63
+ """Preprocessor to store current page URL and path."""
64
+
65
+ def __init__(self, md: Markdown, url: str, path: str):
66
+ super().__init__(md)
67
+ self.url = url
68
+ self.path = path
69
+
70
+ def run(self, lines: list[str]) -> list[str]:
71
+ return lines
72
+
73
+
74
+ class CurrentPageExtension(MarkdownExtension):
75
+ """Markdown extension to store current page URL and path."""
76
+
77
+ def __init__(self, url: str, path: str):
78
+ super().__init__()
79
+ self.url = url
80
+ self.path = path
81
+
82
+ def extendMarkdown(self, md: Markdown) -> None: # noqa: N802
83
+ md.preprocessors.register(
84
+ CurrentPageData(md, self.url, self.path),
85
+ "zensical_current_page",
86
+ 0,
87
+ )
88
+
89
+
54
90
  # ----------------------------------------------------------------------------
55
91
  # Functions
56
92
  # ----------------------------------------------------------------------------
57
93
 
58
94
 
59
- def render(content: str, path: str) -> dict:
95
+ def render(content: str, path: str, url: str) -> dict:
60
96
  """Render Markdown and return HTML.
61
97
 
62
98
  This function returns rendered HTML as well as the table of contents and
@@ -66,9 +102,14 @@ def render(content: str, path: str) -> dict:
66
102
  """
67
103
  config = get_config()
68
104
 
105
+ # Insert current page extension at the beginning
106
+ extensions = [CurrentPageExtension(url, path)] + config[
107
+ "markdown_extensions"
108
+ ]
109
+
69
110
  # Initialize Markdown parser
70
111
  md = Markdown(
71
- extensions=config["markdown_extensions"],
112
+ extensions=extensions,
72
113
  extension_configs=config["mdx_configs"],
73
114
  )
74
115
 
@@ -113,6 +154,24 @@ def render(content: str, path: str) -> dict:
113
154
  if meta.get("search", {}).get("exclude", False):
114
155
  search_processor.data = []
115
156
 
157
+ # Extract URL map from extension if available
158
+ for extension in md.registeredExtensions:
159
+ if type(extension).__qualname__ == "MkdocstringsExtension":
160
+ autorefs = {
161
+ "primary": extension._autorefs._primary_url_map, # type: ignore[attr-defined]
162
+ "secondary": extension._autorefs._secondary_url_map, # type: ignore[attr-defined]
163
+ "inventory": extension._autorefs._abs_url_map, # type: ignore[attr-defined]
164
+ "titles": extension._autorefs._title_map, # type: ignore[attr-defined]
165
+ }
166
+ break
167
+ else:
168
+ autorefs = {
169
+ "primary": {},
170
+ "secondary": {},
171
+ "inventory": {},
172
+ "titles": {},
173
+ }
174
+
116
175
  # Return Markdown with metadata
117
176
  return {
118
177
  "meta": meta,
@@ -120,6 +179,7 @@ def render(content: str, path: str) -> dict:
120
179
  "search": search_processor.data,
121
180
  "title": "",
122
181
  "toc": [_convert_toc(item) for item in getattr(md, "toc_tokens", [])],
182
+ "autorefs": autorefs,
123
183
  }
124
184
 
125
185
 
@@ -0,0 +1,39 @@
1
+ ISC License
2
+
3
+ Copyright (c) for portions of Lucide are held by Cole Bemis 2013-2023 as part of Feather (MIT). All other copyright (c) for Lucide are held by Lucide Contributors 2025.
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+
17
+ ---
18
+
19
+ The MIT License (MIT) (for portions derived from Feather)
20
+
21
+ Copyright (c) 2013-2023 Cole Bemis
22
+
23
+ Permission is hereby granted, free of charge, to any person obtaining a copy
24
+ of this software and associated documentation files (the "Software"), to deal
25
+ in the Software without restriction, including without limitation the rights
26
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27
+ copies of the Software, and to permit persons to whom the Software is
28
+ furnished to do so, subject to the following conditions:
29
+
30
+ The above copyright notice and this permission notice shall be included in all
31
+ copies or substantial portions of the Software.
32
+
33
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39
+ SOFTWARE.
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-ampersand" viewBox="0 0 24 24"><path d="M17.5 12c0 4.4-3.6 8-8 8A4.5 4.5 0 0 1 5 15.5c0-6 8-4 8-8.5a3 3 0 1 0-6 0c0 3 2.5 8.5 12 13M16 12h3"/></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-ampersand" viewBox="0 0 24 24"><path d="M16 12h3M17.5 12a8 8 0 0 1-8 8A4.5 4.5 0 0 1 5 15.5c0-6 8-4 8-8.5a3 3 0 1 0-6 0c0 3 2.5 8.5 12 13"/></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-anchor" viewBox="0 0 24 24"><path d="M12 22V8M5 12H2a10 10 0 0 0 20 0h-3"/><circle cx="12" cy="5" r="3"/></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-anchor" viewBox="0 0 24 24"><path d="M12 6v16M19 13l2-1a9 9 0 0 1-18 0l2 1M9 11h6"/><circle cx="12" cy="4" r="2"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-balloon" viewBox="0 0 24 24"><path d="M12 16v1a2 2 0 0 0 2 2h1a2 2 0 0 1 2 2v1M12 6a2 2 0 0 1 2 2"/><path d="M18 8c0 4-3.5 8-6 8s-6-4-6-8a6 6 0 0 1 12 0"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-birdhouse" viewBox="0 0 24 24"><path d="M12 18v4M17 18l1.956-11.468M3 8l7.82-5.615a2 2 0 0 1 2.36 0L21 8M4 18h16M7 18 5.044 6.532"/><circle cx="12" cy="10" r="2"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-book-search" viewBox="0 0 24 24"><path d="M11 22H5.5a1 1 0 0 1 0-5h4.501M21 22l-1.879-1.878"/><path d="M3 19.5v-15A2.5 2.5 0 0 1 5.5 2H18a1 1 0 0 1 1 1v8"/><circle cx="17" cy="18" r="3"/></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-brush-cleaning" viewBox="0 0 24 24"><path d="m16 22-1-4M19 13.99a1 1 0 0 0 1-1V12a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v.99a1 1 0 0 0 1 1M5 14h14l1.973 6.767A1 1 0 0 1 20 22H4a1 1 0 0 1-.973-1.233zM8 22l1-4"/></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-brush-cleaning" viewBox="0 0 24 24"><path d="m16 22-1-4M19 14a1 1 0 0 0 1-1v-1a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v1a1 1 0 0 0 1 1"/><path d="M19 14H5l-1.973 6.767A1 1 0 0 0 4 22h16a1 1 0 0 0 .973-1.233zM8 22l1-4"/></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-bubbles" viewBox="0 0 24 24"><path d="M7.2 14.8a2 2 0 0 1 2 2"/><circle cx="18.5" cy="8.5" r="3.5"/><circle cx="7.5" cy="16.5" r="5.5"/><circle cx="7.5" cy="4.5" r="2.5"/></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-bubbles" viewBox="0 0 24 24"><path d="M7.001 15.085A1.5 1.5 0 0 1 9 16.5"/><circle cx="18.5" cy="8.5" r="3.5"/><circle cx="7.5" cy="16.5" r="5.5"/><circle cx="7.5" cy="4.5" r="2.5"/></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-calendar-fold" viewBox="0 0 24 24"><path d="M8 2v4M16 2v4M21 17V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11ZM3 10h18"/><path d="M15 22v-4a2 2 0 0 1 2-2h4"/></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-calendar-fold" viewBox="0 0 24 24"><path d="M3 20a2 2 0 0 0 2 2h10a2.4 2.4 0 0 0 1.706-.706l3.588-3.588A2.4 2.4 0 0 0 21 16V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z"/><path d="M15 22v-5a1 1 0 0 1 1-1h5M8 2v4M16 2v4M3 10h18"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-calendars" viewBox="0 0 24 24"><path d="M12 2v2M15.726 21.01A2 2 0 0 1 14 22H4a2 2 0 0 1-2-2V10a2 2 0 0 1 2-2M18 2v2M2 13h2M8 8h14"/><rect width="14" height="14" x="8" y="3" rx="2"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-cannabis-off" viewBox="0 0 24 24"><path d="M12 22v-4c1.5 1.5 3.5 3 6 3 0-1.5-.5-3.5-2-5M13.988 8.327C13.902 6.054 13.365 3.82 12 2a9.3 9.3 0 0 0-1.445 2.9M17.375 11.725C18.882 10.53 21 7.841 21 6c-2.324 0-5.08 1.296-6.662 2.684M2 2l20 20M21.024 15.378A15 15 0 0 0 22 15c-.426-1.279-2.67-2.557-4.25-2.907M6.995 6.992C5.714 6.4 4.29 6 3 6c0 2 2.5 5 4 6-1.5 0-4.5 1.5-5 3 3.5 1.5 6 1 6 1-1.5 1.5-2 3.5-2 5 2.5 0 4.5-1.5 6-3"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-chess-bishop" viewBox="0 0 24 24"><path d="M5 20a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1zM15 18c1.5-.615 3-2.461 3-4.923C18 8.769 14.5 4.462 12 2 9.5 4.462 6 8.77 6 13.077 6 15.539 7.5 17.385 9 18M16 7l-2.5 2.5M9 2h6"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-chess-king" viewBox="0 0 24 24"><path d="M4 20a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1zM6.7 18l-1-1C4.35 15.682 3 14.09 3 12a5 5 0 0 1 4.95-5c1.584 0 2.7.455 4.05 1.818C13.35 7.455 14.466 7 16.05 7A5 5 0 0 1 21 12c0 2.082-1.359 3.673-2.7 5l-1 1M10 4h4M12 2v6.818"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-chess-knight" viewBox="0 0 24 24"><path d="M5 20a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1zM16.5 18c1-2 2.5-5 2.5-9a7 7 0 0 0-7-7H6.635a1 1 0 0 0-.768 1.64L7 5l-2.32 5.802a2 2 0 0 0 .95 2.526l2.87 1.456M15 5l1.425-1.425M17 8l1.53-1.53M9.713 12.185 7 18"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-chess-pawn" viewBox="0 0 24 24"><path d="M5 20a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1zM14.5 10l1.5 8M7 10h10M8 18l1.5-8"/><circle cx="12" cy="6" r="4"/></svg>