django-handyhelpers 0.3.19__py3-none-any.whl → 0.3.35__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (572) hide show
  1. {django_handyhelpers-0.3.19.dist-info → django_handyhelpers-0.3.35.dist-info}/METADATA +16 -6
  2. {django_handyhelpers-0.3.19.dist-info → django_handyhelpers-0.3.35.dist-info}/RECORD +563 -76
  3. {django_handyhelpers-0.3.19.dist-info → django_handyhelpers-0.3.35.dist-info}/WHEEL +1 -1
  4. handyhelpers/__init__.py +6 -6
  5. handyhelpers/forms.py +9 -1
  6. handyhelpers/mixins/form_mixins.py +61 -0
  7. handyhelpers/mixins/model_mixins.py +21 -0
  8. handyhelpers/mixins/serializer_mixins.py +35 -0
  9. handyhelpers/mixins/view_mixins.py +5 -2
  10. handyhelpers/serializers.py +23 -3
  11. handyhelpers/static/handyhelpers/css/table_sortable.css +17 -0
  12. handyhelpers/static/handyhelpers/js/sidebar.js +8 -4
  13. handyhelpers/static/handyhelpers/js/table_sortable.js +119 -0
  14. handyhelpers/static/node_modules/.bin/acorn +4 -0
  15. handyhelpers/static/node_modules/.bin/css-b64-images +13 -0
  16. handyhelpers/static/node_modules/.bin/esbuild +0 -0
  17. handyhelpers/static/node_modules/.bin/html-minifier-terser +308 -0
  18. handyhelpers/static/node_modules/.bin/minify +98 -0
  19. handyhelpers/static/node_modules/.bin/terser +21 -0
  20. handyhelpers/static/node_modules/.bin/uglifyjs +624 -0
  21. handyhelpers/static/node_modules/.package-lock.json +750 -0
  22. handyhelpers/static/node_modules/@esbuild/linux-x64/README.md +3 -0
  23. handyhelpers/static/node_modules/@esbuild/linux-x64/bin/esbuild +0 -0
  24. handyhelpers/static/node_modules/@esbuild/linux-x64/package.json +20 -0
  25. handyhelpers/static/node_modules/@jridgewell/gen-mapping/LICENSE +19 -0
  26. handyhelpers/static/node_modules/@jridgewell/gen-mapping/README.md +227 -0
  27. handyhelpers/static/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs +230 -0
  28. handyhelpers/static/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs.map +1 -0
  29. handyhelpers/static/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js +246 -0
  30. handyhelpers/static/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js.map +1 -0
  31. handyhelpers/static/node_modules/@jridgewell/gen-mapping/dist/types/gen-mapping.d.ts +88 -0
  32. handyhelpers/static/node_modules/@jridgewell/gen-mapping/dist/types/sourcemap-segment.d.ts +12 -0
  33. handyhelpers/static/node_modules/@jridgewell/gen-mapping/dist/types/types.d.ts +36 -0
  34. handyhelpers/static/node_modules/@jridgewell/gen-mapping/package.json +76 -0
  35. handyhelpers/static/node_modules/@jridgewell/resolve-uri/LICENSE +19 -0
  36. handyhelpers/static/node_modules/@jridgewell/resolve-uri/README.md +40 -0
  37. handyhelpers/static/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs +232 -0
  38. handyhelpers/static/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs.map +1 -0
  39. handyhelpers/static/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js +240 -0
  40. handyhelpers/static/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js.map +1 -0
  41. handyhelpers/static/node_modules/@jridgewell/resolve-uri/dist/types/resolve-uri.d.ts +4 -0
  42. handyhelpers/static/node_modules/@jridgewell/resolve-uri/package.json +69 -0
  43. handyhelpers/static/node_modules/@jridgewell/set-array/LICENSE +19 -0
  44. handyhelpers/static/node_modules/@jridgewell/set-array/README.md +37 -0
  45. handyhelpers/static/node_modules/@jridgewell/set-array/dist/set-array.mjs +69 -0
  46. handyhelpers/static/node_modules/@jridgewell/set-array/dist/set-array.mjs.map +1 -0
  47. handyhelpers/static/node_modules/@jridgewell/set-array/dist/set-array.umd.js +83 -0
  48. handyhelpers/static/node_modules/@jridgewell/set-array/dist/set-array.umd.js.map +1 -0
  49. handyhelpers/static/node_modules/@jridgewell/set-array/dist/types/set-array.d.ts +32 -0
  50. handyhelpers/static/node_modules/@jridgewell/set-array/package.json +65 -0
  51. handyhelpers/static/node_modules/@jridgewell/source-map/LICENSE +19 -0
  52. handyhelpers/static/node_modules/@jridgewell/source-map/README.md +184 -0
  53. handyhelpers/static/node_modules/@jridgewell/source-map/dist/source-map.cjs +95 -0
  54. handyhelpers/static/node_modules/@jridgewell/source-map/dist/source-map.cjs.map +1 -0
  55. handyhelpers/static/node_modules/@jridgewell/source-map/dist/source-map.mjs +90 -0
  56. handyhelpers/static/node_modules/@jridgewell/source-map/dist/source-map.mjs.map +1 -0
  57. handyhelpers/static/node_modules/@jridgewell/source-map/dist/source-map.umd.js +1242 -0
  58. handyhelpers/static/node_modules/@jridgewell/source-map/dist/source-map.umd.js.map +1 -0
  59. handyhelpers/static/node_modules/@jridgewell/source-map/dist/types/source-map.d.ts +35 -0
  60. handyhelpers/static/node_modules/@jridgewell/source-map/package.json +71 -0
  61. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/LICENSE +21 -0
  62. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/README.md +264 -0
  63. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs +424 -0
  64. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map +1 -0
  65. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js +439 -0
  66. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map +1 -0
  67. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/dist/types/scopes.d.ts +49 -0
  68. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/dist/types/sourcemap-codec.d.ts +8 -0
  69. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/dist/types/strings.d.ts +15 -0
  70. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/dist/types/vlq.d.ts +6 -0
  71. handyhelpers/static/node_modules/@jridgewell/sourcemap-codec/package.json +75 -0
  72. handyhelpers/static/node_modules/@jridgewell/trace-mapping/LICENSE +19 -0
  73. handyhelpers/static/node_modules/@jridgewell/trace-mapping/README.md +257 -0
  74. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs +580 -0
  75. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs.map +1 -0
  76. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js +600 -0
  77. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js.map +1 -0
  78. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/types/any-map.d.ts +8 -0
  79. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/types/binary-search.d.ts +32 -0
  80. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/types/by-source.d.ts +7 -0
  81. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/types/resolve.d.ts +1 -0
  82. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/types/sort.d.ts +2 -0
  83. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/types/sourcemap-segment.d.ts +16 -0
  84. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/types/strip-filename.d.ts +4 -0
  85. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/types/trace-mapping.d.ts +79 -0
  86. handyhelpers/static/node_modules/@jridgewell/trace-mapping/dist/types/types.d.ts +99 -0
  87. handyhelpers/static/node_modules/@jridgewell/trace-mapping/package.json +77 -0
  88. handyhelpers/static/node_modules/@popperjs/core/dist/cjs/enums.js +1 -1
  89. handyhelpers/static/node_modules/@popperjs/core/dist/cjs/popper-base.js +12 -170
  90. handyhelpers/static/node_modules/@popperjs/core/dist/cjs/popper-base.js.map +1 -1
  91. handyhelpers/static/node_modules/@popperjs/core/dist/cjs/popper-lite.js +14 -184
  92. handyhelpers/static/node_modules/@popperjs/core/dist/cjs/popper-lite.js.map +1 -1
  93. handyhelpers/static/node_modules/@popperjs/core/dist/cjs/popper.js +14 -197
  94. handyhelpers/static/node_modules/@popperjs/core/dist/cjs/popper.js.map +1 -1
  95. handyhelpers/static/node_modules/@popperjs/core/dist/esm/createPopper.js +6 -66
  96. handyhelpers/static/node_modules/@popperjs/core/dist/esm/modifiers/arrow.js +1 -12
  97. handyhelpers/static/node_modules/@popperjs/core/dist/esm/modifiers/computeStyles.js +2 -14
  98. handyhelpers/static/node_modules/@popperjs/core/dist/esm/utils/computeAutoPlacement.js +0 -4
  99. handyhelpers/static/node_modules/@popperjs/core/dist/esm/utils/userAgent.js +1 -1
  100. handyhelpers/static/node_modules/@popperjs/core/dist/umd/enums.js +1 -1
  101. handyhelpers/static/node_modules/@popperjs/core/dist/umd/enums.min.js +1 -1
  102. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper-base.js +12 -170
  103. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper-base.js.map +1 -1
  104. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper-base.min.js +2 -2
  105. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper-base.min.js.map +1 -1
  106. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper-lite.js +14 -184
  107. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper-lite.js.map +1 -1
  108. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper-lite.min.js +2 -2
  109. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper-lite.min.js.map +1 -1
  110. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper.js +14 -197
  111. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper.js.map +1 -1
  112. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper.min.js +2 -2
  113. handyhelpers/static/node_modules/@popperjs/core/dist/umd/popper.min.js.map +1 -1
  114. handyhelpers/static/node_modules/@popperjs/core/lib/createPopper.js +6 -66
  115. handyhelpers/static/node_modules/@popperjs/core/lib/createPopper.js.flow +2 -80
  116. handyhelpers/static/node_modules/@popperjs/core/lib/modifiers/arrow.js +1 -12
  117. handyhelpers/static/node_modules/@popperjs/core/lib/modifiers/arrow.js.flow +0 -22
  118. handyhelpers/static/node_modules/@popperjs/core/lib/modifiers/computeStyles.js +2 -14
  119. handyhelpers/static/node_modules/@popperjs/core/lib/modifiers/computeStyles.js.flow +3 -33
  120. handyhelpers/static/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js +0 -4
  121. handyhelpers/static/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js.flow +0 -12
  122. handyhelpers/static/node_modules/@popperjs/core/lib/utils/userAgent.js +1 -1
  123. handyhelpers/static/node_modules/@popperjs/core/lib/utils/userAgent.js.flow +1 -1
  124. handyhelpers/static/node_modules/@popperjs/core/package.json +1 -1
  125. handyhelpers/static/node_modules/@putout/minify/LICENSE +21 -0
  126. handyhelpers/static/node_modules/@putout/minify/README.md +110 -0
  127. handyhelpers/static/node_modules/@putout/minify/bundle/minify.min.js +52 -0
  128. handyhelpers/static/node_modules/@putout/minify/package.json +112 -0
  129. handyhelpers/static/node_modules/@swc/core/Visitor.d.ts +218 -0
  130. handyhelpers/static/node_modules/@swc/core/Visitor.js +1407 -0
  131. handyhelpers/static/node_modules/@swc/core/binding.d.ts +56 -0
  132. handyhelpers/static/node_modules/@swc/core/binding.js +351 -0
  133. handyhelpers/static/node_modules/@swc/core/index.d.ts +118 -0
  134. handyhelpers/static/node_modules/@swc/core/index.js +439 -0
  135. handyhelpers/static/node_modules/@swc/core/package.json +114 -0
  136. handyhelpers/static/node_modules/@swc/core/postinstall.js +148 -0
  137. handyhelpers/static/node_modules/@swc/core/spack.d.ts +51 -0
  138. handyhelpers/static/node_modules/@swc/core/spack.js +87 -0
  139. handyhelpers/static/node_modules/@swc/core/util.d.ts +1 -0
  140. handyhelpers/static/node_modules/@swc/core/util.js +104 -0
  141. handyhelpers/static/node_modules/@swc/core-linux-x64-gnu/README.md +3 -0
  142. handyhelpers/static/node_modules/@swc/core-linux-x64-gnu/package.json +45 -0
  143. handyhelpers/static/node_modules/@swc/core-linux-x64-gnu/swc.linux-x64-gnu.node +0 -0
  144. handyhelpers/static/node_modules/@swc/counter/CHANGELOG.md +7 -0
  145. handyhelpers/static/node_modules/@swc/counter/README.md +7 -0
  146. handyhelpers/static/node_modules/@swc/counter/index.js +1 -0
  147. handyhelpers/static/node_modules/@swc/counter/package.json +27 -0
  148. handyhelpers/static/node_modules/@swc/types/LICENSE +201 -0
  149. handyhelpers/static/node_modules/@swc/types/README.md +4 -0
  150. handyhelpers/static/node_modules/@swc/types/assumptions.d.ts +92 -0
  151. handyhelpers/static/node_modules/@swc/types/assumptions.js +2 -0
  152. handyhelpers/static/node_modules/@swc/types/index.d.ts +1977 -0
  153. handyhelpers/static/node_modules/@swc/types/index.js +2 -0
  154. handyhelpers/static/node_modules/@swc/types/package.json +39 -0
  155. handyhelpers/static/node_modules/acorn/CHANGELOG.md +928 -0
  156. handyhelpers/static/node_modules/acorn/LICENSE +21 -0
  157. handyhelpers/static/node_modules/acorn/README.md +282 -0
  158. handyhelpers/static/node_modules/acorn/bin/acorn +4 -0
  159. handyhelpers/static/node_modules/acorn/dist/acorn.d.mts +866 -0
  160. handyhelpers/static/node_modules/acorn/dist/acorn.d.ts +866 -0
  161. handyhelpers/static/node_modules/acorn/dist/acorn.js +6174 -0
  162. handyhelpers/static/node_modules/acorn/dist/acorn.mjs +6145 -0
  163. handyhelpers/static/node_modules/acorn/dist/bin.js +90 -0
  164. handyhelpers/static/node_modules/acorn/package.json +50 -0
  165. handyhelpers/static/node_modules/buffer-from/LICENSE +21 -0
  166. handyhelpers/static/node_modules/buffer-from/index.js +72 -0
  167. handyhelpers/static/node_modules/buffer-from/package.json +19 -0
  168. handyhelpers/static/node_modules/buffer-from/readme.md +69 -0
  169. handyhelpers/static/node_modules/camel-case/LICENSE +21 -0
  170. handyhelpers/static/node_modules/camel-case/README.md +47 -0
  171. handyhelpers/static/node_modules/camel-case/dist/index.d.ts +5 -0
  172. handyhelpers/static/node_modules/camel-case/dist/index.js +23 -0
  173. handyhelpers/static/node_modules/camel-case/dist/index.js.map +1 -0
  174. handyhelpers/static/node_modules/camel-case/dist/index.spec.d.ts +1 -0
  175. handyhelpers/static/node_modules/camel-case/dist/index.spec.js +26 -0
  176. handyhelpers/static/node_modules/camel-case/dist/index.spec.js.map +1 -0
  177. handyhelpers/static/node_modules/camel-case/dist.es2015/index.d.ts +5 -0
  178. handyhelpers/static/node_modules/camel-case/dist.es2015/index.js +17 -0
  179. handyhelpers/static/node_modules/camel-case/dist.es2015/index.js.map +1 -0
  180. handyhelpers/static/node_modules/camel-case/dist.es2015/index.spec.d.ts +1 -0
  181. handyhelpers/static/node_modules/camel-case/dist.es2015/index.spec.js +24 -0
  182. handyhelpers/static/node_modules/camel-case/dist.es2015/index.spec.js.map +1 -0
  183. handyhelpers/static/node_modules/camel-case/package.json +89 -0
  184. handyhelpers/static/node_modules/clean-css/History.md +1504 -0
  185. handyhelpers/static/node_modules/clean-css/LICENSE +19 -0
  186. handyhelpers/static/node_modules/clean-css/README.md +987 -0
  187. handyhelpers/static/node_modules/clean-css/index.js +1 -0
  188. handyhelpers/static/node_modules/clean-css/package.json +48 -0
  189. handyhelpers/static/node_modules/commander/LICENSE +22 -0
  190. handyhelpers/static/node_modules/commander/Readme.md +1134 -0
  191. handyhelpers/static/node_modules/commander/esm.mjs +16 -0
  192. handyhelpers/static/node_modules/commander/index.js +27 -0
  193. handyhelpers/static/node_modules/commander/package-support.json +16 -0
  194. handyhelpers/static/node_modules/commander/package.json +80 -0
  195. handyhelpers/static/node_modules/commander/typings/index.d.ts +889 -0
  196. handyhelpers/static/node_modules/css-b64-images/.npmignore +15 -0
  197. handyhelpers/static/node_modules/css-b64-images/.travis.yml +5 -0
  198. handyhelpers/static/node_modules/css-b64-images/README.md +78 -0
  199. handyhelpers/static/node_modules/css-b64-images/bin/css-b64-images +13 -0
  200. handyhelpers/static/node_modules/css-b64-images/draft.png +0 -0
  201. handyhelpers/static/node_modules/css-b64-images/draft.xcf +0 -0
  202. handyhelpers/static/node_modules/css-b64-images/package.json +30 -0
  203. handyhelpers/static/node_modules/css-b64-images/test/css-b64-images-test.js +38 -0
  204. handyhelpers/static/node_modules/css-b64-images/test/fixture/css/style.css +52 -0
  205. handyhelpers/static/node_modules/css-b64-images/test/fixture/fonts/callunasansregular-webfont.eot +0 -0
  206. handyhelpers/static/node_modules/css-b64-images/test/fixture/fonts/callunasansregular-webfont.svg +248 -0
  207. handyhelpers/static/node_modules/css-b64-images/test/fixture/fonts/callunasansregular-webfont.ttf +0 -0
  208. handyhelpers/static/node_modules/css-b64-images/test/fixture/fonts/callunasansregular-webfont.woff +0 -0
  209. handyhelpers/static/node_modules/css-b64-images/test/fixture/fonts/maven_pro_medium-webfont.eot +0 -0
  210. handyhelpers/static/node_modules/css-b64-images/test/fixture/fonts/maven_pro_medium-webfont.svg +245 -0
  211. handyhelpers/static/node_modules/css-b64-images/test/fixture/fonts/maven_pro_medium-webfont.ttf +0 -0
  212. handyhelpers/static/node_modules/css-b64-images/test/fixture/fonts/maven_pro_medium-webfont.woff +0 -0
  213. handyhelpers/static/node_modules/css-b64-images/test/fixture/img/background-pattern.gif +0 -0
  214. handyhelpers/static/node_modules/css-b64-images/test/fixture/img/dots.svg +6 -0
  215. handyhelpers/static/node_modules/css-b64-images/test/fixture/img/mixit-banner.png +0 -0
  216. handyhelpers/static/node_modules/debug/LICENSE +20 -0
  217. handyhelpers/static/node_modules/debug/README.md +481 -0
  218. handyhelpers/static/node_modules/debug/package.json +65 -0
  219. handyhelpers/static/node_modules/debug/src/browser.js +272 -0
  220. handyhelpers/static/node_modules/debug/src/common.js +292 -0
  221. handyhelpers/static/node_modules/debug/src/index.js +10 -0
  222. handyhelpers/static/node_modules/debug/src/node.js +263 -0
  223. handyhelpers/static/node_modules/dot-case/LICENSE +21 -0
  224. handyhelpers/static/node_modules/dot-case/README.md +37 -0
  225. handyhelpers/static/node_modules/dot-case/dist/index.d.ts +3 -0
  226. handyhelpers/static/node_modules/dot-case/dist/index.js +11 -0
  227. handyhelpers/static/node_modules/dot-case/dist/index.js.map +1 -0
  228. handyhelpers/static/node_modules/dot-case/dist/index.spec.d.ts +1 -0
  229. handyhelpers/static/node_modules/dot-case/dist/index.spec.js +26 -0
  230. handyhelpers/static/node_modules/dot-case/dist/index.spec.js.map +1 -0
  231. handyhelpers/static/node_modules/dot-case/dist.es2015/index.d.ts +3 -0
  232. handyhelpers/static/node_modules/dot-case/dist.es2015/index.js +7 -0
  233. handyhelpers/static/node_modules/dot-case/dist.es2015/index.js.map +1 -0
  234. handyhelpers/static/node_modules/dot-case/dist.es2015/index.spec.d.ts +1 -0
  235. handyhelpers/static/node_modules/dot-case/dist.es2015/index.spec.js +24 -0
  236. handyhelpers/static/node_modules/dot-case/dist.es2015/index.spec.js.map +1 -0
  237. handyhelpers/static/node_modules/dot-case/package.json +89 -0
  238. handyhelpers/static/node_modules/entities/LICENSE +11 -0
  239. handyhelpers/static/node_modules/entities/package.json +90 -0
  240. handyhelpers/static/node_modules/entities/readme.md +122 -0
  241. handyhelpers/static/node_modules/esbuild/LICENSE.md +21 -0
  242. handyhelpers/static/node_modules/esbuild/README.md +3 -0
  243. handyhelpers/static/node_modules/esbuild/bin/esbuild +0 -0
  244. handyhelpers/static/node_modules/esbuild/install.js +286 -0
  245. handyhelpers/static/node_modules/esbuild/package.json +47 -0
  246. handyhelpers/static/node_modules/find-up/index.d.ts +247 -0
  247. handyhelpers/static/node_modules/find-up/index.js +107 -0
  248. handyhelpers/static/node_modules/find-up/license +9 -0
  249. handyhelpers/static/node_modules/find-up/package.json +61 -0
  250. handyhelpers/static/node_modules/find-up/readme.md +160 -0
  251. handyhelpers/static/node_modules/fun-effects/LICENSE +674 -0
  252. handyhelpers/static/node_modules/fun-effects/README.md +10 -0
  253. handyhelpers/static/node_modules/fun-effects/dist/css/background_icons.min.css +1 -0
  254. handyhelpers/static/node_modules/fun-effects/dist/css/blur_group.min.css +1 -0
  255. handyhelpers/static/node_modules/fun-effects/dist/css/fades.min.css +1 -0
  256. handyhelpers/static/node_modules/fun-effects/dist/css/marquee.min.css +1 -0
  257. handyhelpers/static/node_modules/fun-effects/dist/css/scroller.min.css +1 -0
  258. handyhelpers/static/node_modules/fun-effects/dist/index.js +15 -0
  259. handyhelpers/static/node_modules/fun-effects/dist/js/background_icons.min.js +1 -0
  260. handyhelpers/static/node_modules/fun-effects/dist/js/marquee.min.js +1 -0
  261. handyhelpers/static/node_modules/fun-effects/dist/js/scroller.min.js +1 -0
  262. handyhelpers/static/node_modules/fun-effects/package.json +39 -0
  263. handyhelpers/static/node_modules/fun-effects/src/css/background_icons.css +39 -0
  264. handyhelpers/static/node_modules/fun-effects/src/css/blur_group.css +22 -0
  265. handyhelpers/static/node_modules/fun-effects/src/css/fades.css +94 -0
  266. handyhelpers/static/node_modules/fun-effects/src/css/marquee.css +45 -0
  267. handyhelpers/static/node_modules/fun-effects/src/css/scroller.css +144 -0
  268. handyhelpers/static/node_modules/fun-effects/src/index.js +15 -0
  269. handyhelpers/static/node_modules/fun-effects/src/js/background_icons.js +101 -0
  270. handyhelpers/static/node_modules/fun-effects/src/js/marquee.js +81 -0
  271. handyhelpers/static/node_modules/fun-effects/src/js/scroller.js +37 -0
  272. handyhelpers/static/node_modules/html-minifier-terser/LICENSE +22 -0
  273. handyhelpers/static/node_modules/html-minifier-terser/README.md +168 -0
  274. handyhelpers/static/node_modules/html-minifier-terser/cli.js +308 -0
  275. handyhelpers/static/node_modules/html-minifier-terser/dist/htmlminifier.cjs +1857 -0
  276. handyhelpers/static/node_modules/html-minifier-terser/dist/htmlminifier.esm.bundle.js +57509 -0
  277. handyhelpers/static/node_modules/html-minifier-terser/dist/htmlminifier.umd.bundle.js +57520 -0
  278. handyhelpers/static/node_modules/html-minifier-terser/dist/htmlminifier.umd.bundle.min.js +9 -0
  279. handyhelpers/static/node_modules/html-minifier-terser/package.json +105 -0
  280. handyhelpers/static/node_modules/html-minifier-terser/src/htmlminifier.js +1366 -0
  281. handyhelpers/static/node_modules/html-minifier-terser/src/htmlparser.js +565 -0
  282. handyhelpers/static/node_modules/html-minifier-terser/src/tokenchain.js +68 -0
  283. handyhelpers/static/node_modules/html-minifier-terser/src/utils.js +11 -0
  284. handyhelpers/static/node_modules/jju/LICENSE +21 -0
  285. handyhelpers/static/node_modules/jju/Makefile +20 -0
  286. handyhelpers/static/node_modules/jju/README.md +249 -0
  287. handyhelpers/static/node_modules/jju/index.js +32 -0
  288. handyhelpers/static/node_modules/jju/package.json +34 -0
  289. handyhelpers/static/node_modules/jju/package.yaml +36 -0
  290. handyhelpers/static/node_modules/locate-path/index.d.ts +92 -0
  291. handyhelpers/static/node_modules/locate-path/index.js +77 -0
  292. handyhelpers/static/node_modules/locate-path/license +9 -0
  293. handyhelpers/static/node_modules/locate-path/package.json +48 -0
  294. handyhelpers/static/node_modules/locate-path/readme.md +123 -0
  295. handyhelpers/static/node_modules/lower-case/LICENSE +21 -0
  296. handyhelpers/static/node_modules/lower-case/README.md +35 -0
  297. handyhelpers/static/node_modules/lower-case/dist/index.d.ts +8 -0
  298. handyhelpers/static/node_modules/lower-case/dist/index.js +53 -0
  299. handyhelpers/static/node_modules/lower-case/dist/index.js.map +1 -0
  300. handyhelpers/static/node_modules/lower-case/dist/index.spec.d.ts +1 -0
  301. handyhelpers/static/node_modules/lower-case/dist/index.spec.js +36 -0
  302. handyhelpers/static/node_modules/lower-case/dist/index.spec.js.map +1 -0
  303. handyhelpers/static/node_modules/lower-case/dist.es2015/index.d.ts +8 -0
  304. handyhelpers/static/node_modules/lower-case/dist.es2015/index.js +48 -0
  305. handyhelpers/static/node_modules/lower-case/dist.es2015/index.js.map +1 -0
  306. handyhelpers/static/node_modules/lower-case/dist.es2015/index.spec.d.ts +1 -0
  307. handyhelpers/static/node_modules/lower-case/dist.es2015/index.spec.js +34 -0
  308. handyhelpers/static/node_modules/lower-case/dist.es2015/index.spec.js.map +1 -0
  309. handyhelpers/static/node_modules/lower-case/package.json +87 -0
  310. handyhelpers/static/node_modules/minify/ChangeLog +1307 -0
  311. handyhelpers/static/node_modules/minify/LICENSE +22 -0
  312. handyhelpers/static/node_modules/minify/README.md +177 -0
  313. handyhelpers/static/node_modules/minify/bin/minify.js +98 -0
  314. handyhelpers/static/node_modules/minify/deno.json +5 -0
  315. handyhelpers/static/node_modules/minify/help.json +8 -0
  316. handyhelpers/static/node_modules/minify/package.json +65 -0
  317. handyhelpers/static/node_modules/ms/index.js +162 -0
  318. handyhelpers/static/node_modules/ms/license.md +21 -0
  319. handyhelpers/static/node_modules/ms/package.json +38 -0
  320. handyhelpers/static/node_modules/ms/readme.md +59 -0
  321. handyhelpers/static/node_modules/no-case/LICENSE +21 -0
  322. handyhelpers/static/node_modules/no-case/README.md +37 -0
  323. handyhelpers/static/node_modules/no-case/dist/index.d.ts +10 -0
  324. handyhelpers/static/node_modules/no-case/dist/index.js +35 -0
  325. handyhelpers/static/node_modules/no-case/dist/index.js.map +1 -0
  326. handyhelpers/static/node_modules/no-case/dist/index.spec.d.ts +1 -0
  327. handyhelpers/static/node_modules/no-case/dist/index.spec.js +59 -0
  328. handyhelpers/static/node_modules/no-case/dist/index.spec.js.map +1 -0
  329. handyhelpers/static/node_modules/no-case/dist.es2015/index.d.ts +10 -0
  330. handyhelpers/static/node_modules/no-case/dist.es2015/index.js +31 -0
  331. handyhelpers/static/node_modules/no-case/dist.es2015/index.js.map +1 -0
  332. handyhelpers/static/node_modules/no-case/dist.es2015/index.spec.d.ts +1 -0
  333. handyhelpers/static/node_modules/no-case/dist.es2015/index.spec.js +57 -0
  334. handyhelpers/static/node_modules/no-case/dist.es2015/index.spec.js.map +1 -0
  335. handyhelpers/static/node_modules/no-case/package.json +85 -0
  336. handyhelpers/static/node_modules/p-limit/index.d.ts +40 -0
  337. handyhelpers/static/node_modules/p-limit/index.js +68 -0
  338. handyhelpers/static/node_modules/p-limit/license +9 -0
  339. handyhelpers/static/node_modules/p-limit/package.json +54 -0
  340. handyhelpers/static/node_modules/p-limit/readme.md +99 -0
  341. handyhelpers/static/node_modules/p-locate/index.d.ts +49 -0
  342. handyhelpers/static/node_modules/p-locate/index.js +48 -0
  343. handyhelpers/static/node_modules/p-locate/license +9 -0
  344. handyhelpers/static/node_modules/p-locate/package.json +56 -0
  345. handyhelpers/static/node_modules/p-locate/readme.md +91 -0
  346. handyhelpers/static/node_modules/param-case/LICENSE +21 -0
  347. handyhelpers/static/node_modules/param-case/README.md +37 -0
  348. handyhelpers/static/node_modules/param-case/dist/index.d.ts +3 -0
  349. handyhelpers/static/node_modules/param-case/dist/index.js +11 -0
  350. handyhelpers/static/node_modules/param-case/dist/index.js.map +1 -0
  351. handyhelpers/static/node_modules/param-case/dist/index.spec.d.ts +1 -0
  352. handyhelpers/static/node_modules/param-case/dist/index.spec.js +24 -0
  353. handyhelpers/static/node_modules/param-case/dist/index.spec.js.map +1 -0
  354. handyhelpers/static/node_modules/param-case/dist.es2015/index.d.ts +3 -0
  355. handyhelpers/static/node_modules/param-case/dist.es2015/index.js +7 -0
  356. handyhelpers/static/node_modules/param-case/dist.es2015/index.js.map +1 -0
  357. handyhelpers/static/node_modules/param-case/dist.es2015/index.spec.d.ts +1 -0
  358. handyhelpers/static/node_modules/param-case/dist.es2015/index.spec.js +22 -0
  359. handyhelpers/static/node_modules/param-case/dist.es2015/index.spec.js.map +1 -0
  360. handyhelpers/static/node_modules/param-case/package.json +91 -0
  361. handyhelpers/static/node_modules/pascal-case/LICENSE +21 -0
  362. handyhelpers/static/node_modules/pascal-case/README.md +47 -0
  363. handyhelpers/static/node_modules/pascal-case/dist/index.d.ts +5 -0
  364. handyhelpers/static/node_modules/pascal-case/dist/index.js +24 -0
  365. handyhelpers/static/node_modules/pascal-case/dist/index.js.map +1 -0
  366. handyhelpers/static/node_modules/pascal-case/dist/index.spec.d.ts +1 -0
  367. handyhelpers/static/node_modules/pascal-case/dist/index.spec.js +25 -0
  368. handyhelpers/static/node_modules/pascal-case/dist/index.spec.js.map +1 -0
  369. handyhelpers/static/node_modules/pascal-case/dist.es2015/index.d.ts +5 -0
  370. handyhelpers/static/node_modules/pascal-case/dist.es2015/index.js +18 -0
  371. handyhelpers/static/node_modules/pascal-case/dist.es2015/index.js.map +1 -0
  372. handyhelpers/static/node_modules/pascal-case/dist.es2015/index.spec.d.ts +1 -0
  373. handyhelpers/static/node_modules/pascal-case/dist.es2015/index.spec.js +23 -0
  374. handyhelpers/static/node_modules/pascal-case/dist.es2015/index.spec.js.map +1 -0
  375. handyhelpers/static/node_modules/pascal-case/package.json +90 -0
  376. handyhelpers/static/node_modules/path-exists/index.d.ts +31 -0
  377. handyhelpers/static/node_modules/path-exists/index.js +19 -0
  378. handyhelpers/static/node_modules/path-exists/license +9 -0
  379. handyhelpers/static/node_modules/path-exists/package.json +41 -0
  380. handyhelpers/static/node_modules/path-exists/readme.md +52 -0
  381. handyhelpers/static/node_modules/readjson/ChangeLog +110 -0
  382. handyhelpers/static/node_modules/readjson/LICENSE +21 -0
  383. handyhelpers/static/node_modules/readjson/README.md +36 -0
  384. handyhelpers/static/node_modules/readjson/package.json +46 -0
  385. handyhelpers/static/node_modules/relateurl/README.md +159 -0
  386. handyhelpers/static/node_modules/relateurl/license +21 -0
  387. handyhelpers/static/node_modules/relateurl/package.json +46 -0
  388. handyhelpers/static/node_modules/simport/ChangeLog +77 -0
  389. handyhelpers/static/node_modules/simport/LICENSE +21 -0
  390. handyhelpers/static/node_modules/simport/README.md +81 -0
  391. handyhelpers/static/node_modules/simport/fixture/context.js +3 -0
  392. handyhelpers/static/node_modules/simport/fixture/default-frozen-function.mjs +2 -0
  393. handyhelpers/static/node_modules/simport/fixture/default-frozen-object.mjs +2 -0
  394. handyhelpers/static/node_modules/simport/package.json +65 -0
  395. handyhelpers/static/node_modules/simport/simport.js +84 -0
  396. handyhelpers/static/node_modules/simport/simport.mjs +22 -0
  397. handyhelpers/static/node_modules/source-map/CHANGELOG.md +301 -0
  398. handyhelpers/static/node_modules/source-map/LICENSE +28 -0
  399. handyhelpers/static/node_modules/source-map/README.md +742 -0
  400. handyhelpers/static/node_modules/source-map/dist/source-map.debug.js +3234 -0
  401. handyhelpers/static/node_modules/source-map/dist/source-map.js +3233 -0
  402. handyhelpers/static/node_modules/source-map/dist/source-map.min.js +2 -0
  403. handyhelpers/static/node_modules/source-map/dist/source-map.min.js.map +1 -0
  404. handyhelpers/static/node_modules/source-map/package.json +73 -0
  405. handyhelpers/static/node_modules/source-map/source-map.d.ts +98 -0
  406. handyhelpers/static/node_modules/source-map/source-map.js +8 -0
  407. handyhelpers/static/node_modules/source-map-support/LICENSE.md +21 -0
  408. handyhelpers/static/node_modules/source-map-support/README.md +284 -0
  409. handyhelpers/static/node_modules/source-map-support/browser-source-map-support.js +114 -0
  410. handyhelpers/static/node_modules/source-map-support/package.json +31 -0
  411. handyhelpers/static/node_modules/source-map-support/register-hook-require.js +1 -0
  412. handyhelpers/static/node_modules/source-map-support/register.js +1 -0
  413. handyhelpers/static/node_modules/source-map-support/source-map-support.js +625 -0
  414. handyhelpers/static/node_modules/terser/CHANGELOG.md +783 -0
  415. handyhelpers/static/node_modules/terser/LICENSE +27 -0
  416. handyhelpers/static/node_modules/terser/PATRONS.md +15 -0
  417. handyhelpers/static/node_modules/terser/README.md +1421 -0
  418. handyhelpers/static/node_modules/terser/bin/package.json +10 -0
  419. handyhelpers/static/node_modules/terser/bin/terser +21 -0
  420. handyhelpers/static/node_modules/terser/bin/uglifyjs +10 -0
  421. handyhelpers/static/node_modules/terser/dist/.gitkeep +0 -0
  422. handyhelpers/static/node_modules/terser/dist/bundle.min.js +32962 -0
  423. handyhelpers/static/node_modules/terser/dist/package.json +10 -0
  424. handyhelpers/static/node_modules/terser/main.js +27 -0
  425. handyhelpers/static/node_modules/terser/node_modules/commander/CHANGELOG.md +419 -0
  426. handyhelpers/static/node_modules/terser/node_modules/commander/LICENSE +22 -0
  427. handyhelpers/static/node_modules/terser/node_modules/commander/Readme.md +428 -0
  428. handyhelpers/static/node_modules/terser/node_modules/commander/index.js +1224 -0
  429. handyhelpers/static/node_modules/terser/node_modules/commander/package.json +38 -0
  430. handyhelpers/static/node_modules/terser/node_modules/commander/typings/index.d.ts +310 -0
  431. handyhelpers/static/node_modules/terser/package.json +153 -0
  432. handyhelpers/static/node_modules/terser/tools/domprops.js +9026 -0
  433. handyhelpers/static/node_modules/terser/tools/exit.cjs +7 -0
  434. handyhelpers/static/node_modules/terser/tools/props.html +68 -0
  435. handyhelpers/static/node_modules/terser/tools/terser.d.ts +216 -0
  436. handyhelpers/static/node_modules/tippy.js/LICENSE +21 -0
  437. handyhelpers/static/node_modules/tippy.js/README.md +63 -0
  438. handyhelpers/static/node_modules/tippy.js/animations/perspective-extreme.css +1 -0
  439. handyhelpers/static/node_modules/tippy.js/animations/perspective-subtle.css +1 -0
  440. handyhelpers/static/node_modules/tippy.js/animations/perspective.css +1 -0
  441. handyhelpers/static/node_modules/tippy.js/animations/scale-extreme.css +1 -0
  442. handyhelpers/static/node_modules/tippy.js/animations/scale-subtle.css +1 -0
  443. handyhelpers/static/node_modules/tippy.js/animations/scale.css +1 -0
  444. handyhelpers/static/node_modules/tippy.js/animations/shift-away-extreme.css +1 -0
  445. handyhelpers/static/node_modules/tippy.js/animations/shift-away-subtle.css +1 -0
  446. handyhelpers/static/node_modules/tippy.js/animations/shift-away.css +1 -0
  447. handyhelpers/static/node_modules/tippy.js/animations/shift-toward-extreme.css +1 -0
  448. handyhelpers/static/node_modules/tippy.js/animations/shift-toward-subtle.css +1 -0
  449. handyhelpers/static/node_modules/tippy.js/animations/shift-toward.css +1 -0
  450. handyhelpers/static/node_modules/tippy.js/dist/backdrop.css +1 -0
  451. handyhelpers/static/node_modules/tippy.js/dist/border.css +1 -0
  452. handyhelpers/static/node_modules/tippy.js/dist/svg-arrow.css +1 -0
  453. handyhelpers/static/node_modules/tippy.js/dist/tippy-bundle.umd.js +2516 -0
  454. handyhelpers/static/node_modules/tippy.js/dist/tippy-bundle.umd.js.map +1 -0
  455. handyhelpers/static/node_modules/tippy.js/dist/tippy-bundle.umd.min.js +2 -0
  456. handyhelpers/static/node_modules/tippy.js/dist/tippy-bundle.umd.min.js.map +1 -0
  457. handyhelpers/static/node_modules/tippy.js/dist/tippy.cjs.js +2497 -0
  458. handyhelpers/static/node_modules/tippy.js/dist/tippy.cjs.js.map +1 -0
  459. handyhelpers/static/node_modules/tippy.js/dist/tippy.css +1 -0
  460. handyhelpers/static/node_modules/tippy.js/dist/tippy.esm.js +2486 -0
  461. handyhelpers/static/node_modules/tippy.js/dist/tippy.esm.js.map +1 -0
  462. handyhelpers/static/node_modules/tippy.js/dist/tippy.umd.js +2496 -0
  463. handyhelpers/static/node_modules/tippy.js/dist/tippy.umd.js.map +1 -0
  464. handyhelpers/static/node_modules/tippy.js/dist/tippy.umd.min.js +2 -0
  465. handyhelpers/static/node_modules/tippy.js/dist/tippy.umd.min.js.map +1 -0
  466. handyhelpers/static/node_modules/tippy.js/headless/dist/tippy-headless.cjs.js +2388 -0
  467. handyhelpers/static/node_modules/tippy.js/headless/dist/tippy-headless.cjs.js.map +1 -0
  468. handyhelpers/static/node_modules/tippy.js/headless/dist/tippy-headless.esm.js +2377 -0
  469. handyhelpers/static/node_modules/tippy.js/headless/dist/tippy-headless.esm.js.map +1 -0
  470. handyhelpers/static/node_modules/tippy.js/headless/dist/tippy-headless.umd.js +2382 -0
  471. handyhelpers/static/node_modules/tippy.js/headless/dist/tippy-headless.umd.js.map +1 -0
  472. handyhelpers/static/node_modules/tippy.js/headless/dist/tippy-headless.umd.min.js +2 -0
  473. handyhelpers/static/node_modules/tippy.js/headless/dist/tippy-headless.umd.min.js.map +1 -0
  474. handyhelpers/static/node_modules/tippy.js/headless/package.json +16 -0
  475. handyhelpers/static/node_modules/tippy.js/index.d.ts +260 -0
  476. handyhelpers/static/node_modules/tippy.js/package.json +157 -0
  477. handyhelpers/static/node_modules/tippy.js/themes/light-border.css +1 -0
  478. handyhelpers/static/node_modules/tippy.js/themes/light.css +1 -0
  479. handyhelpers/static/node_modules/tippy.js/themes/material.css +1 -0
  480. handyhelpers/static/node_modules/tippy.js/themes/translucent.css +1 -0
  481. handyhelpers/static/node_modules/try-catch/ChangeLog +55 -0
  482. handyhelpers/static/node_modules/try-catch/LICENSE +21 -0
  483. handyhelpers/static/node_modules/try-catch/README.md +38 -0
  484. handyhelpers/static/node_modules/try-catch/package.json +34 -0
  485. handyhelpers/static/node_modules/try-to-catch/ChangeLog +64 -0
  486. handyhelpers/static/node_modules/try-to-catch/LICENSE +21 -0
  487. handyhelpers/static/node_modules/try-to-catch/README.md +74 -0
  488. handyhelpers/static/node_modules/try-to-catch/package.json +47 -0
  489. handyhelpers/static/node_modules/tslib/CopyrightNotice.txt +15 -0
  490. handyhelpers/static/node_modules/tslib/LICENSE.txt +12 -0
  491. handyhelpers/static/node_modules/tslib/README.md +164 -0
  492. handyhelpers/static/node_modules/tslib/SECURITY.md +41 -0
  493. handyhelpers/static/node_modules/tslib/modules/index.d.ts +38 -0
  494. handyhelpers/static/node_modules/tslib/modules/index.js +70 -0
  495. handyhelpers/static/node_modules/tslib/modules/package.json +3 -0
  496. handyhelpers/static/node_modules/tslib/package.json +47 -0
  497. handyhelpers/static/node_modules/tslib/tslib.d.ts +460 -0
  498. handyhelpers/static/node_modules/tslib/tslib.es6.html +1 -0
  499. handyhelpers/static/node_modules/tslib/tslib.es6.js +402 -0
  500. handyhelpers/static/node_modules/tslib/tslib.es6.mjs +401 -0
  501. handyhelpers/static/node_modules/tslib/tslib.html +1 -0
  502. handyhelpers/static/node_modules/tslib/tslib.js +484 -0
  503. handyhelpers/static/node_modules/uglify-js/LICENSE +29 -0
  504. handyhelpers/static/node_modules/uglify-js/README.md +1479 -0
  505. handyhelpers/static/node_modules/uglify-js/bin/uglifyjs +624 -0
  506. handyhelpers/static/node_modules/uglify-js/package.json +56 -0
  507. handyhelpers/static/node_modules/uglify-js/tools/domprops.html +456 -0
  508. handyhelpers/static/node_modules/uglify-js/tools/domprops.json +8327 -0
  509. handyhelpers/static/node_modules/uglify-js/tools/exports.js +8 -0
  510. handyhelpers/static/node_modules/uglify-js/tools/node.js +115 -0
  511. handyhelpers/static/node_modules/uglify-js/tools/tty.js +22 -0
  512. handyhelpers/static/node_modules/unicorn-magic/default.js +14 -0
  513. handyhelpers/static/node_modules/unicorn-magic/index.d.ts +29 -0
  514. handyhelpers/static/node_modules/unicorn-magic/license +9 -0
  515. handyhelpers/static/node_modules/unicorn-magic/node.js +7 -0
  516. handyhelpers/static/node_modules/unicorn-magic/package.json +49 -0
  517. handyhelpers/static/node_modules/unicorn-magic/readme.md +25 -0
  518. handyhelpers/static/node_modules/yocto-queue/index.d.ts +61 -0
  519. handyhelpers/static/node_modules/yocto-queue/index.js +78 -0
  520. handyhelpers/static/node_modules/yocto-queue/license +9 -0
  521. handyhelpers/static/node_modules/yocto-queue/package.json +48 -0
  522. handyhelpers/static/node_modules/yocto-queue/readme.md +70 -0
  523. handyhelpers/static/package.json +3 -1
  524. handyhelpers/static/yarn.lock +393 -20
  525. handyhelpers/templates/handyhelpers/generic/bs5/generic_index.html +5 -8
  526. handyhelpers/templates/handyhelpers/handyhelpers_base_bs5.htm +5 -1
  527. handyhelpers/templates/handyhelpers/handyhelpers_with_sidebar.htm +50 -3
  528. handyhelpers/templates/handyhelpers/htmx/bs5/filter_form/generic_modal_swap.htm +48 -0
  529. handyhelpers/templates/handyhelpers/htmx/bs5/form/form_wrapper.htm +48 -0
  530. handyhelpers/templates/handyhelpers/htmx/bs5/form/inline_form.htm +166 -0
  531. handyhelpers/templates/handyhelpers/htmx/bs5/form/inline_form_disabled.htm +125 -0
  532. handyhelpers/templates/handyhelpers/htmx/bs5/generic_modal_swap.htm +2 -3
  533. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/content_title.htm +38 -0
  534. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/controls.htm +21 -0
  535. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/examples/card.htm +17 -0
  536. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/examples/list.htm +11 -0
  537. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/examples/table.htm +21 -0
  538. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/filter_form_modal_swap.htm +48 -0
  539. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/full.html +6 -0
  540. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/wrapper_card.htm +7 -0
  541. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/wrapper_list.htm +7 -0
  542. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/wrapper_minimal.htm +7 -0
  543. handyhelpers/templates/handyhelpers/htmx/bs5/htmx_option_multi_filter_view/wrapper_table.htm +18 -0
  544. handyhelpers/templates/handyhelpers/htmx/bs5/index.htm +34 -0
  545. handyhelpers/templates/handyhelpers/partials/calendar.htm +1 -1
  546. handyhelpers/templates/handyhelpers/report/annual_stats.html +6 -0
  547. handyhelpers/templates/handyhelpers/report/annual_stats_content.htm +43 -0
  548. handyhelpers/templates/handyhelpers/report/chartjs/annual_progress_chart.htm +1 -1
  549. handyhelpers/templates/handyhelpers/report/chartjs/annual_progress_content.htm +40 -39
  550. handyhelpers/templates/handyhelpers/report/chartjs/annual_stats.html +25 -36
  551. handyhelpers/templates/handyhelpers/report/chartjs/annual_trends_content.htm +35 -34
  552. handyhelpers/templates/handyhelpers/report/chartjs/day_count_chart.htm +1 -1
  553. handyhelpers/templates/handyhelpers/report/chartjs/month_count_chart.htm +1 -1
  554. handyhelpers/templates/handyhelpers/report/chartjs/week_count_chart.htm +1 -1
  555. handyhelpers/templates/handyhelpers/report/chartjs/year_count_chart.htm +1 -1
  556. handyhelpers/templatetags/form_tags.py +47 -0
  557. handyhelpers/templatetags/htmx_tags.py +21 -0
  558. handyhelpers/views/action.py +3 -1
  559. handyhelpers/views/calendar.py +34 -14
  560. handyhelpers/views/htmx.py +396 -4
  561. handyhelpers/views/report.py +12 -5
  562. handyhelpers/management/commands/generate_admin.py +0 -110
  563. handyhelpers/static/node_modules/@popperjs/core/dist/esm/utils/format.js +0 -9
  564. handyhelpers/static/node_modules/@popperjs/core/dist/esm/utils/validateModifiers.js +0 -81
  565. handyhelpers/static/node_modules/@popperjs/core/lib/utils/format.d.ts +0 -1
  566. handyhelpers/static/node_modules/@popperjs/core/lib/utils/format.js +0 -9
  567. handyhelpers/static/node_modules/@popperjs/core/lib/utils/format.js.flow +0 -5
  568. handyhelpers/static/node_modules/@popperjs/core/lib/utils/validateModifiers.d.ts +0 -1
  569. handyhelpers/static/node_modules/@popperjs/core/lib/utils/validateModifiers.js +0 -81
  570. handyhelpers/static/node_modules/@popperjs/core/lib/utils/validateModifiers.js.flow +0 -151
  571. {django_handyhelpers-0.3.19.dist-info → django_handyhelpers-0.3.35.dist-info}/LICENSE +0 -0
  572. {django_handyhelpers-0.3.19.dist-info → django_handyhelpers-0.3.35.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1857 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var CleanCSS = require('clean-css');
6
+ var entities = require('entities');
7
+ var RelateURL = require('relateurl');
8
+ var terser = require('terser');
9
+
10
+ async function replaceAsync(str, regex, asyncFn) {
11
+ const promises = [];
12
+
13
+ str.replace(regex, (match, ...args) => {
14
+ const promise = asyncFn(match, ...args);
15
+ promises.push(promise);
16
+ });
17
+
18
+ const data = await Promise.all(promises);
19
+ return str.replace(regex, () => data.shift());
20
+ }
21
+
22
+ /*!
23
+ * HTML Parser By John Resig (ejohn.org)
24
+ * Modified by Juriy "kangax" Zaytsev
25
+ * Original code by Erik Arvidsson, Mozilla Public License
26
+ * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
27
+ */
28
+
29
+ class CaseInsensitiveSet extends Set {
30
+ has(str) {
31
+ return super.has(str.toLowerCase());
32
+ }
33
+ }
34
+
35
+ // Regular Expressions for parsing tags and attributes
36
+ const singleAttrIdentifier = /([^\s"'<>/=]+)/;
37
+ const singleAttrAssigns = [/=/];
38
+ const singleAttrValues = [
39
+ // attr value double quotes
40
+ /"([^"]*)"+/.source,
41
+ // attr value, single quotes
42
+ /'([^']*)'+/.source,
43
+ // attr value, no quotes
44
+ /([^ \t\n\f\r"'`=<>]+)/.source
45
+ ];
46
+ // https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName
47
+ const qnameCapture = (function () {
48
+ // based on https://www.npmjs.com/package/ncname
49
+ const combiningChar = '\\u0300-\\u0345\\u0360\\u0361\\u0483-\\u0486\\u0591-\\u05A1\\u05A3-\\u05B9\\u05BB-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u064B-\\u0652\\u0670\\u06D6-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0901-\\u0903\\u093C\\u093E-\\u094D\\u0951-\\u0954\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u0A02\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A70\\u0A71\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B43\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B82\\u0B83\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C01-\\u0C03\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C82\\u0C83\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D43\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86-\\u0F8B\\u0F90-\\u0F95\\u0F97\\u0F99-\\u0FAD\\u0FB1-\\u0FB7\\u0FB9\\u20D0-\\u20DC\\u20E1\\u302A-\\u302F\\u3099\\u309A';
50
+ const digit = '0-9\\u0660-\\u0669\\u06F0-\\u06F9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE7-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29';
51
+ const extender = '\\xB7\\u02D0\\u02D1\\u0387\\u0640\\u0E46\\u0EC6\\u3005\\u3031-\\u3035\\u309D\\u309E\\u30FC-\\u30FE';
52
+ const letter = 'A-Za-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u0131\\u0134-\\u013E\\u0141-\\u0148\\u014A-\\u017E\\u0180-\\u01C3\\u01CD-\\u01F0\\u01F4\\u01F5\\u01FA-\\u0217\\u0250-\\u02A8\\u02BB-\\u02C1\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03CE\\u03D0-\\u03D6\\u03DA\\u03DC\\u03DE\\u03E0\\u03E2-\\u03F3\\u0401-\\u040C\\u040E-\\u044F\\u0451-\\u045C\\u045E-\\u0481\\u0490-\\u04C4\\u04C7\\u04C8\\u04CB\\u04CC\\u04D0-\\u04EB\\u04EE-\\u04F5\\u04F8\\u04F9\\u0531-\\u0556\\u0559\\u0561-\\u0586\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u063A\\u0641-\\u064A\\u0671-\\u06B7\\u06BA-\\u06BE\\u06C0-\\u06CE\\u06D0-\\u06D3\\u06D5\\u06E5\\u06E6\\u0905-\\u0939\\u093D\\u0958-\\u0961\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8B\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AE0\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B36-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB5\\u0BB7-\\u0BB9\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D60\\u0D61\\u0E01-\\u0E2E\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E45\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD\\u0EAE\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0F40-\\u0F47\\u0F49-\\u0F69\\u10A0-\\u10C5\\u10D0-\\u10F6\\u1100\\u1102\\u1103\\u1105-\\u1107\\u1109\\u110B\\u110C\\u110E-\\u1112\\u113C\\u113E\\u1140\\u114C\\u114E\\u1150\\u1154\\u1155\\u1159\\u115F-\\u1161\\u1163\\u1165\\u1167\\u1169\\u116D\\u116E\\u1172\\u1173\\u1175\\u119E\\u11A8\\u11AB\\u11AE\\u11AF\\u11B7\\u11B8\\u11BA\\u11BC-\\u11C2\\u11EB\\u11F0\\u11F9\\u1E00-\\u1E9B\\u1EA0-\\u1EF9\\u1F00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2126\\u212A\\u212B\\u212E\\u2180-\\u2182\\u3007\\u3021-\\u3029\\u3041-\\u3094\\u30A1-\\u30FA\\u3105-\\u312C\\u4E00-\\u9FA5\\uAC00-\\uD7A3';
53
+ const ncname = '[' + letter + '_][' + letter + digit + '\\.\\-_' + combiningChar + extender + ']*';
54
+ return '((?:' + ncname + '\\:)?' + ncname + ')';
55
+ })();
56
+ const startTagOpen = new RegExp('^<' + qnameCapture);
57
+ const startTagClose = /^\s*(\/?)>/;
58
+ const endTag = new RegExp('^<\\/' + qnameCapture + '[^>]*>');
59
+ const doctype = /^<!DOCTYPE\s?[^>]+>/i;
60
+
61
+ let IS_REGEX_CAPTURING_BROKEN = false;
62
+ 'x'.replace(/x(.)?/g, function (m, g) {
63
+ IS_REGEX_CAPTURING_BROKEN = g === '';
64
+ });
65
+
66
+ // Empty Elements
67
+ const empty = new CaseInsensitiveSet(['area', 'base', 'basefont', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
68
+
69
+ // Inline Elements
70
+ const inline = new CaseInsensitiveSet(['a', 'abbr', 'acronym', 'applet', 'b', 'basefont', 'bdo', 'big', 'br', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'label', 'map', 'noscript', 'object', 'q', 's', 'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'tt', 'u', 'var']);
71
+
72
+ // Elements that you can, intentionally, leave open
73
+ // (and which close themselves)
74
+ const closeSelf = new CaseInsensitiveSet(['colgroup', 'dd', 'dt', 'li', 'option', 'p', 'td', 'tfoot', 'th', 'thead', 'tr', 'source']);
75
+
76
+ // Attributes that have their values filled in disabled='disabled'
77
+ const fillAttrs = new CaseInsensitiveSet(['checked', 'compact', 'declare', 'defer', 'disabled', 'ismap', 'multiple', 'nohref', 'noresize', 'noshade', 'nowrap', 'readonly', 'selected']);
78
+
79
+ // Special Elements (can contain anything)
80
+ const special = new CaseInsensitiveSet(['script', 'style']);
81
+
82
+ // HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
83
+ // Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
84
+ const nonPhrasing = new CaseInsensitiveSet(['address', 'article', 'aside', 'base', 'blockquote', 'body', 'caption', 'col', 'colgroup', 'dd', 'details', 'dialog', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'legend', 'li', 'menuitem', 'meta', 'ol', 'optgroup', 'option', 'param', 'rp', 'rt', 'source', 'style', 'summary', 'tbody', 'td', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul']);
85
+
86
+ const reCache = {};
87
+
88
+ function attrForHandler(handler) {
89
+ let pattern = singleAttrIdentifier.source +
90
+ '(?:\\s*(' + joinSingleAttrAssigns(handler) + ')' +
91
+ '[ \\t\\n\\f\\r]*(?:' + singleAttrValues.join('|') + '))?';
92
+ if (handler.customAttrSurround) {
93
+ const attrClauses = [];
94
+ for (let i = handler.customAttrSurround.length - 1; i >= 0; i--) {
95
+ attrClauses[i] = '(?:' +
96
+ '(' + handler.customAttrSurround[i][0].source + ')\\s*' +
97
+ pattern +
98
+ '\\s*(' + handler.customAttrSurround[i][1].source + ')' +
99
+ ')';
100
+ }
101
+ attrClauses.push('(?:' + pattern + ')');
102
+ pattern = '(?:' + attrClauses.join('|') + ')';
103
+ }
104
+ return new RegExp('^\\s*' + pattern);
105
+ }
106
+
107
+ function joinSingleAttrAssigns(handler) {
108
+ return singleAttrAssigns.concat(
109
+ handler.customAttrAssign || []
110
+ ).map(function (assign) {
111
+ return '(?:' + assign.source + ')';
112
+ }).join('|');
113
+ }
114
+
115
+ class HTMLParser {
116
+ constructor(html, handler) {
117
+ this.html = html;
118
+ this.handler = handler;
119
+ }
120
+
121
+ async parse() {
122
+ let html = this.html;
123
+ const handler = this.handler;
124
+
125
+ const stack = []; let lastTag;
126
+ const attribute = attrForHandler(handler);
127
+ let last, prevTag, nextTag;
128
+ while (html) {
129
+ last = html;
130
+ // Make sure we're not in a script or style element
131
+ if (!lastTag || !special.has(lastTag)) {
132
+ let textEnd = html.indexOf('<');
133
+ if (textEnd === 0) {
134
+ // Comment:
135
+ if (/^<!--/.test(html)) {
136
+ const commentEnd = html.indexOf('-->');
137
+
138
+ if (commentEnd >= 0) {
139
+ if (handler.comment) {
140
+ await handler.comment(html.substring(4, commentEnd));
141
+ }
142
+ html = html.substring(commentEnd + 3);
143
+ prevTag = '';
144
+ continue;
145
+ }
146
+ }
147
+
148
+ // https://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
149
+ if (/^<!\[/.test(html)) {
150
+ const conditionalEnd = html.indexOf(']>');
151
+
152
+ if (conditionalEnd >= 0) {
153
+ if (handler.comment) {
154
+ await handler.comment(html.substring(2, conditionalEnd + 1), true /* non-standard */);
155
+ }
156
+ html = html.substring(conditionalEnd + 2);
157
+ prevTag = '';
158
+ continue;
159
+ }
160
+ }
161
+
162
+ // Doctype:
163
+ const doctypeMatch = html.match(doctype);
164
+ if (doctypeMatch) {
165
+ if (handler.doctype) {
166
+ handler.doctype(doctypeMatch[0]);
167
+ }
168
+ html = html.substring(doctypeMatch[0].length);
169
+ prevTag = '';
170
+ continue;
171
+ }
172
+
173
+ // End tag:
174
+ const endTagMatch = html.match(endTag);
175
+ if (endTagMatch) {
176
+ html = html.substring(endTagMatch[0].length);
177
+ await replaceAsync(endTagMatch[0], endTag, parseEndTag);
178
+ prevTag = '/' + endTagMatch[1].toLowerCase();
179
+ continue;
180
+ }
181
+
182
+ // Start tag:
183
+ const startTagMatch = parseStartTag(html);
184
+ if (startTagMatch) {
185
+ html = startTagMatch.rest;
186
+ await handleStartTag(startTagMatch);
187
+ prevTag = startTagMatch.tagName.toLowerCase();
188
+ continue;
189
+ }
190
+
191
+ // Treat `<` as text
192
+ if (handler.continueOnParseError) {
193
+ textEnd = html.indexOf('<', 1);
194
+ }
195
+ }
196
+
197
+ let text;
198
+ if (textEnd >= 0) {
199
+ text = html.substring(0, textEnd);
200
+ html = html.substring(textEnd);
201
+ } else {
202
+ text = html;
203
+ html = '';
204
+ }
205
+
206
+ // next tag
207
+ let nextTagMatch = parseStartTag(html);
208
+ if (nextTagMatch) {
209
+ nextTag = nextTagMatch.tagName;
210
+ } else {
211
+ nextTagMatch = html.match(endTag);
212
+ if (nextTagMatch) {
213
+ nextTag = '/' + nextTagMatch[1];
214
+ } else {
215
+ nextTag = '';
216
+ }
217
+ }
218
+
219
+ if (handler.chars) {
220
+ await handler.chars(text, prevTag, nextTag);
221
+ }
222
+ prevTag = '';
223
+ } else {
224
+ const stackedTag = lastTag.toLowerCase();
225
+ const reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)</' + stackedTag + '[^>]*>', 'i'));
226
+
227
+ html = await replaceAsync(html, reStackedTag, async (_, text) => {
228
+ if (stackedTag !== 'script' && stackedTag !== 'style' && stackedTag !== 'noscript') {
229
+ text = text
230
+ .replace(/<!--([\s\S]*?)-->/g, '$1')
231
+ .replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1');
232
+ }
233
+
234
+ if (handler.chars) {
235
+ await handler.chars(text);
236
+ }
237
+
238
+ return '';
239
+ });
240
+
241
+ await parseEndTag('</' + stackedTag + '>', stackedTag);
242
+ }
243
+
244
+ if (html === last) {
245
+ throw new Error('Parse Error: ' + html);
246
+ }
247
+ }
248
+
249
+ if (!handler.partialMarkup) {
250
+ // Clean up any remaining tags
251
+ await parseEndTag();
252
+ }
253
+
254
+ function parseStartTag(input) {
255
+ const start = input.match(startTagOpen);
256
+ if (start) {
257
+ const match = {
258
+ tagName: start[1],
259
+ attrs: []
260
+ };
261
+ input = input.slice(start[0].length);
262
+ let end, attr;
263
+ while (!(end = input.match(startTagClose)) && (attr = input.match(attribute))) {
264
+ input = input.slice(attr[0].length);
265
+ match.attrs.push(attr);
266
+ }
267
+ if (end) {
268
+ match.unarySlash = end[1];
269
+ match.rest = input.slice(end[0].length);
270
+ return match;
271
+ }
272
+ }
273
+ }
274
+
275
+ async function closeIfFound(tagName) {
276
+ if (findTag(tagName) >= 0) {
277
+ await parseEndTag('', tagName);
278
+ return true;
279
+ }
280
+ }
281
+
282
+ async function handleStartTag(match) {
283
+ const tagName = match.tagName;
284
+ let unarySlash = match.unarySlash;
285
+
286
+ if (handler.html5) {
287
+ if (lastTag === 'p' && nonPhrasing.has(tagName)) {
288
+ await parseEndTag('', lastTag);
289
+ } else if (tagName === 'tbody') {
290
+ await closeIfFound('thead');
291
+ } else if (tagName === 'tfoot') {
292
+ if (!await closeIfFound('tbody')) {
293
+ await closeIfFound('thead');
294
+ }
295
+ }
296
+ if (tagName === 'col' && findTag('colgroup') < 0) {
297
+ lastTag = 'colgroup';
298
+ stack.push({ tag: lastTag, attrs: [] });
299
+ if (handler.start) {
300
+ await handler.start(lastTag, [], false, '');
301
+ }
302
+ }
303
+ }
304
+
305
+ if (!handler.html5 && !inline.has(tagName)) {
306
+ while (lastTag && inline.has(lastTag)) {
307
+ await parseEndTag('', lastTag);
308
+ }
309
+ }
310
+
311
+ if (closeSelf.has(tagName) && lastTag === tagName) {
312
+ await parseEndTag('', tagName);
313
+ }
314
+
315
+ const unary = empty.has(tagName) || (tagName === 'html' && lastTag === 'head') || !!unarySlash;
316
+
317
+ const attrs = match.attrs.map(function (args) {
318
+ let name, value, customOpen, customClose, customAssign, quote;
319
+ const ncp = 7; // number of captured parts, scalar
320
+
321
+ // hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778
322
+ if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) {
323
+ if (args[3] === '') { delete args[3]; }
324
+ if (args[4] === '') { delete args[4]; }
325
+ if (args[5] === '') { delete args[5]; }
326
+ }
327
+
328
+ function populate(index) {
329
+ customAssign = args[index];
330
+ value = args[index + 1];
331
+ if (typeof value !== 'undefined') {
332
+ return '"';
333
+ }
334
+ value = args[index + 2];
335
+ if (typeof value !== 'undefined') {
336
+ return '\'';
337
+ }
338
+ value = args[index + 3];
339
+ if (typeof value === 'undefined' && fillAttrs.has(name)) {
340
+ value = name;
341
+ }
342
+ return '';
343
+ }
344
+
345
+ let j = 1;
346
+ if (handler.customAttrSurround) {
347
+ for (let i = 0, l = handler.customAttrSurround.length; i < l; i++, j += ncp) {
348
+ name = args[j + 1];
349
+ if (name) {
350
+ quote = populate(j + 2);
351
+ customOpen = args[j];
352
+ customClose = args[j + 6];
353
+ break;
354
+ }
355
+ }
356
+ }
357
+
358
+ if (!name && (name = args[j])) {
359
+ quote = populate(j + 1);
360
+ }
361
+
362
+ return {
363
+ name,
364
+ value,
365
+ customAssign: customAssign || '=',
366
+ customOpen: customOpen || '',
367
+ customClose: customClose || '',
368
+ quote: quote || ''
369
+ };
370
+ });
371
+
372
+ if (!unary) {
373
+ stack.push({ tag: tagName, attrs });
374
+ lastTag = tagName;
375
+ unarySlash = '';
376
+ }
377
+
378
+ if (handler.start) {
379
+ await handler.start(tagName, attrs, unary, unarySlash);
380
+ }
381
+ }
382
+
383
+ function findTag(tagName) {
384
+ let pos;
385
+ const needle = tagName.toLowerCase();
386
+ for (pos = stack.length - 1; pos >= 0; pos--) {
387
+ if (stack[pos].tag.toLowerCase() === needle) {
388
+ break;
389
+ }
390
+ }
391
+ return pos;
392
+ }
393
+
394
+ async function parseEndTag(tag, tagName) {
395
+ let pos;
396
+
397
+ // Find the closest opened tag of the same type
398
+ if (tagName) {
399
+ pos = findTag(tagName);
400
+ } else { // If no tag name is provided, clean shop
401
+ pos = 0;
402
+ }
403
+
404
+ if (pos >= 0) {
405
+ // Close all the open elements, up the stack
406
+ for (let i = stack.length - 1; i >= pos; i--) {
407
+ if (handler.end) {
408
+ handler.end(stack[i].tag, stack[i].attrs, i > pos || !tag);
409
+ }
410
+ }
411
+
412
+ // Remove the open elements from the stack
413
+ stack.length = pos;
414
+ lastTag = pos && stack[pos - 1].tag;
415
+ } else if (tagName.toLowerCase() === 'br') {
416
+ if (handler.start) {
417
+ await handler.start(tagName, [], true, '');
418
+ }
419
+ } else if (tagName.toLowerCase() === 'p') {
420
+ if (handler.start) {
421
+ await handler.start(tagName, [], false, '', true);
422
+ }
423
+ if (handler.end) {
424
+ handler.end(tagName, []);
425
+ }
426
+ }
427
+ }
428
+ }
429
+ }
430
+
431
+ class Sorter {
432
+ sort(tokens, fromIndex = 0) {
433
+ for (let i = 0, len = this.keys.length; i < len; i++) {
434
+ const key = this.keys[i];
435
+ const token = key.slice(1);
436
+
437
+ let index = tokens.indexOf(token, fromIndex);
438
+
439
+ if (index !== -1) {
440
+ do {
441
+ if (index !== fromIndex) {
442
+ tokens.splice(index, 1);
443
+ tokens.splice(fromIndex, 0, token);
444
+ }
445
+ fromIndex++;
446
+ } while ((index = tokens.indexOf(token, fromIndex)) !== -1);
447
+
448
+ return this[key].sort(tokens, fromIndex);
449
+ }
450
+ }
451
+ return tokens;
452
+ }
453
+ }
454
+
455
+ class TokenChain {
456
+ add(tokens) {
457
+ tokens.forEach((token) => {
458
+ const key = '$' + token;
459
+ if (!this[key]) {
460
+ this[key] = [];
461
+ this[key].processed = 0;
462
+ }
463
+ this[key].push(tokens);
464
+ });
465
+ }
466
+
467
+ createSorter() {
468
+ const sorter = new Sorter();
469
+
470
+ sorter.keys = Object.keys(this).sort((j, k) => {
471
+ const m = this[j].length;
472
+ const n = this[k].length;
473
+ return m < n ? 1 : m > n ? -1 : j < k ? -1 : j > k ? 1 : 0;
474
+ }).filter((key) => {
475
+ if (this[key].processed < this[key].length) {
476
+ const token = key.slice(1);
477
+ const chain = new TokenChain();
478
+
479
+ this[key].forEach((tokens) => {
480
+ let index;
481
+ while ((index = tokens.indexOf(token)) !== -1) {
482
+ tokens.splice(index, 1);
483
+ }
484
+ tokens.forEach((token) => {
485
+ this['$' + token].processed++;
486
+ });
487
+ chain.add(tokens.slice(0));
488
+ });
489
+ sorter[key] = chain.createSorter();
490
+ return true;
491
+ }
492
+ return false;
493
+ });
494
+ return sorter;
495
+ }
496
+ }
497
+
498
+ function trimWhitespace(str) {
499
+ return str && str.replace(/^[ \n\r\t\f]+/, '').replace(/[ \n\r\t\f]+$/, '');
500
+ }
501
+
502
+ function collapseWhitespaceAll(str) {
503
+ // Non-breaking space is specifically handled inside the replacer function here:
504
+ return str && str.replace(/[ \n\r\t\f\xA0]+/g, function (spaces) {
505
+ return spaces === '\t' ? '\t' : spaces.replace(/(^|\xA0+)[^\xA0]+/g, '$1 ');
506
+ });
507
+ }
508
+
509
+ function collapseWhitespace(str, options, trimLeft, trimRight, collapseAll) {
510
+ let lineBreakBefore = ''; let lineBreakAfter = '';
511
+
512
+ if (options.preserveLineBreaks) {
513
+ str = str.replace(/^[ \n\r\t\f]*?[\n\r][ \n\r\t\f]*/, function () {
514
+ lineBreakBefore = '\n';
515
+ return '';
516
+ }).replace(/[ \n\r\t\f]*?[\n\r][ \n\r\t\f]*$/, function () {
517
+ lineBreakAfter = '\n';
518
+ return '';
519
+ });
520
+ }
521
+
522
+ if (trimLeft) {
523
+ // Non-breaking space is specifically handled inside the replacer function here:
524
+ str = str.replace(/^[ \n\r\t\f\xA0]+/, function (spaces) {
525
+ const conservative = !lineBreakBefore && options.conservativeCollapse;
526
+ if (conservative && spaces === '\t') {
527
+ return '\t';
528
+ }
529
+ return spaces.replace(/^[^\xA0]+/, '').replace(/(\xA0+)[^\xA0]+/g, '$1 ') || (conservative ? ' ' : '');
530
+ });
531
+ }
532
+
533
+ if (trimRight) {
534
+ // Non-breaking space is specifically handled inside the replacer function here:
535
+ str = str.replace(/[ \n\r\t\f\xA0]+$/, function (spaces) {
536
+ const conservative = !lineBreakAfter && options.conservativeCollapse;
537
+ if (conservative && spaces === '\t') {
538
+ return '\t';
539
+ }
540
+ return spaces.replace(/[^\xA0]+(\xA0+)/g, ' $1').replace(/[^\xA0]+$/, '') || (conservative ? ' ' : '');
541
+ });
542
+ }
543
+
544
+ if (collapseAll) {
545
+ // strip non space whitespace then compress spaces to one
546
+ str = collapseWhitespaceAll(str);
547
+ }
548
+
549
+ return lineBreakBefore + str + lineBreakAfter;
550
+ }
551
+
552
+ // non-empty tags that will maintain whitespace around them
553
+ const inlineTags = new Set(['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'ins', 'kbd', 'label', 'mark', 'math', 'nobr', 'object', 'q', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var']);
554
+ // non-empty tags that will maintain whitespace within them
555
+ const inlineTextTags = new Set(['a', 'abbr', 'acronym', 'b', 'big', 'del', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'nobr', 'rp', 's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'time', 'tt', 'u', 'var']);
556
+ // self-closing tags that will maintain whitespace around them
557
+ const selfClosingInlineTags = new Set(['comment', 'img', 'input', 'wbr']);
558
+
559
+ function collapseWhitespaceSmart(str, prevTag, nextTag, options) {
560
+ let trimLeft = prevTag && !selfClosingInlineTags.has(prevTag);
561
+ if (trimLeft && !options.collapseInlineTagWhitespace) {
562
+ trimLeft = prevTag.charAt(0) === '/' ? !inlineTags.has(prevTag.slice(1)) : !inlineTextTags.has(prevTag);
563
+ }
564
+ let trimRight = nextTag && !selfClosingInlineTags.has(nextTag);
565
+ if (trimRight && !options.collapseInlineTagWhitespace) {
566
+ trimRight = nextTag.charAt(0) === '/' ? !inlineTextTags.has(nextTag.slice(1)) : !inlineTags.has(nextTag);
567
+ }
568
+ return collapseWhitespace(str, options, trimLeft, trimRight, prevTag && nextTag);
569
+ }
570
+
571
+ function isConditionalComment(text) {
572
+ return /^\[if\s[^\]]+]|\[endif]$/.test(text);
573
+ }
574
+
575
+ function isIgnoredComment(text, options) {
576
+ for (let i = 0, len = options.ignoreCustomComments.length; i < len; i++) {
577
+ if (options.ignoreCustomComments[i].test(text)) {
578
+ return true;
579
+ }
580
+ }
581
+ return false;
582
+ }
583
+
584
+ function isEventAttribute(attrName, options) {
585
+ const patterns = options.customEventAttributes;
586
+ if (patterns) {
587
+ for (let i = patterns.length; i--;) {
588
+ if (patterns[i].test(attrName)) {
589
+ return true;
590
+ }
591
+ }
592
+ return false;
593
+ }
594
+ return /^on[a-z]{3,}$/.test(attrName);
595
+ }
596
+
597
+ function canRemoveAttributeQuotes(value) {
598
+ // https://mathiasbynens.be/notes/unquoted-attribute-values
599
+ return /^[^ \t\n\f\r"'`=<>]+$/.test(value);
600
+ }
601
+
602
+ function attributesInclude(attributes, attribute) {
603
+ for (let i = attributes.length; i--;) {
604
+ if (attributes[i].name.toLowerCase() === attribute) {
605
+ return true;
606
+ }
607
+ }
608
+ return false;
609
+ }
610
+
611
+ function isAttributeRedundant(tag, attrName, attrValue, attrs) {
612
+ attrValue = attrValue ? trimWhitespace(attrValue.toLowerCase()) : '';
613
+
614
+ return (
615
+ (tag === 'script' &&
616
+ attrName === 'language' &&
617
+ attrValue === 'javascript') ||
618
+
619
+ (tag === 'form' &&
620
+ attrName === 'method' &&
621
+ attrValue === 'get') ||
622
+
623
+ (tag === 'input' &&
624
+ attrName === 'type' &&
625
+ attrValue === 'text') ||
626
+
627
+ (tag === 'script' &&
628
+ attrName === 'charset' &&
629
+ !attributesInclude(attrs, 'src')) ||
630
+
631
+ (tag === 'a' &&
632
+ attrName === 'name' &&
633
+ attributesInclude(attrs, 'id')) ||
634
+
635
+ (tag === 'area' &&
636
+ attrName === 'shape' &&
637
+ attrValue === 'rect')
638
+ );
639
+ }
640
+
641
+ // https://mathiasbynens.be/demo/javascript-mime-type
642
+ // https://developer.mozilla.org/en/docs/Web/HTML/Element/script#attr-type
643
+ const executableScriptsMimetypes = new Set([
644
+ 'text/javascript',
645
+ 'text/ecmascript',
646
+ 'text/jscript',
647
+ 'application/javascript',
648
+ 'application/x-javascript',
649
+ 'application/ecmascript',
650
+ 'module'
651
+ ]);
652
+
653
+ const keepScriptsMimetypes = new Set([
654
+ 'module'
655
+ ]);
656
+
657
+ function isScriptTypeAttribute(attrValue = '') {
658
+ attrValue = trimWhitespace(attrValue.split(/;/, 2)[0]).toLowerCase();
659
+ return attrValue === '' || executableScriptsMimetypes.has(attrValue);
660
+ }
661
+
662
+ function keepScriptTypeAttribute(attrValue = '') {
663
+ attrValue = trimWhitespace(attrValue.split(/;/, 2)[0]).toLowerCase();
664
+ return keepScriptsMimetypes.has(attrValue);
665
+ }
666
+
667
+ function isExecutableScript(tag, attrs) {
668
+ if (tag !== 'script') {
669
+ return false;
670
+ }
671
+ for (let i = 0, len = attrs.length; i < len; i++) {
672
+ const attrName = attrs[i].name.toLowerCase();
673
+ if (attrName === 'type') {
674
+ return isScriptTypeAttribute(attrs[i].value);
675
+ }
676
+ }
677
+ return true;
678
+ }
679
+
680
+ function isStyleLinkTypeAttribute(attrValue = '') {
681
+ attrValue = trimWhitespace(attrValue).toLowerCase();
682
+ return attrValue === '' || attrValue === 'text/css';
683
+ }
684
+
685
+ function isStyleSheet(tag, attrs) {
686
+ if (tag !== 'style') {
687
+ return false;
688
+ }
689
+ for (let i = 0, len = attrs.length; i < len; i++) {
690
+ const attrName = attrs[i].name.toLowerCase();
691
+ if (attrName === 'type') {
692
+ return isStyleLinkTypeAttribute(attrs[i].value);
693
+ }
694
+ }
695
+ return true;
696
+ }
697
+
698
+ const isSimpleBoolean = new Set(['allowfullscreen', 'async', 'autofocus', 'autoplay', 'checked', 'compact', 'controls', 'declare', 'default', 'defaultchecked', 'defaultmuted', 'defaultselected', 'defer', 'disabled', 'enabled', 'formnovalidate', 'hidden', 'indeterminate', 'inert', 'ismap', 'itemscope', 'loop', 'multiple', 'muted', 'nohref', 'noresize', 'noshade', 'novalidate', 'nowrap', 'open', 'pauseonexit', 'readonly', 'required', 'reversed', 'scoped', 'seamless', 'selected', 'sortable', 'truespeed', 'typemustmatch', 'visible']);
699
+ const isBooleanValue = new Set(['true', 'false']);
700
+
701
+ function isBooleanAttribute(attrName, attrValue) {
702
+ return isSimpleBoolean.has(attrName) || (attrName === 'draggable' && !isBooleanValue.has(attrValue));
703
+ }
704
+
705
+ function isUriTypeAttribute(attrName, tag) {
706
+ return (
707
+ (/^(?:a|area|link|base)$/.test(tag) && attrName === 'href') ||
708
+ (tag === 'img' && /^(?:src|longdesc|usemap)$/.test(attrName)) ||
709
+ (tag === 'object' && /^(?:classid|codebase|data|usemap)$/.test(attrName)) ||
710
+ (tag === 'q' && attrName === 'cite') ||
711
+ (tag === 'blockquote' && attrName === 'cite') ||
712
+ ((tag === 'ins' || tag === 'del') && attrName === 'cite') ||
713
+ (tag === 'form' && attrName === 'action') ||
714
+ (tag === 'input' && (attrName === 'src' || attrName === 'usemap')) ||
715
+ (tag === 'head' && attrName === 'profile') ||
716
+ (tag === 'script' && (attrName === 'src' || attrName === 'for'))
717
+ );
718
+ }
719
+
720
+ function isNumberTypeAttribute(attrName, tag) {
721
+ return (
722
+ (/^(?:a|area|object|button)$/.test(tag) && attrName === 'tabindex') ||
723
+ (tag === 'input' && (attrName === 'maxlength' || attrName === 'tabindex')) ||
724
+ (tag === 'select' && (attrName === 'size' || attrName === 'tabindex')) ||
725
+ (tag === 'textarea' && /^(?:rows|cols|tabindex)$/.test(attrName)) ||
726
+ (tag === 'colgroup' && attrName === 'span') ||
727
+ (tag === 'col' && attrName === 'span') ||
728
+ ((tag === 'th' || tag === 'td') && (attrName === 'rowspan' || attrName === 'colspan'))
729
+ );
730
+ }
731
+
732
+ function isLinkType(tag, attrs, value) {
733
+ if (tag !== 'link') {
734
+ return false;
735
+ }
736
+ for (let i = 0, len = attrs.length; i < len; i++) {
737
+ if (attrs[i].name === 'rel' && attrs[i].value === value) {
738
+ return true;
739
+ }
740
+ }
741
+ }
742
+
743
+ function isMediaQuery(tag, attrs, attrName) {
744
+ return attrName === 'media' && (isLinkType(tag, attrs, 'stylesheet') || isStyleSheet(tag, attrs));
745
+ }
746
+
747
+ const srcsetTags = new Set(['img', 'source']);
748
+
749
+ function isSrcset(attrName, tag) {
750
+ return attrName === 'srcset' && srcsetTags.has(tag);
751
+ }
752
+
753
+ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs) {
754
+ if (isEventAttribute(attrName, options)) {
755
+ attrValue = trimWhitespace(attrValue).replace(/^javascript:\s*/i, '');
756
+ return options.minifyJS(attrValue, true);
757
+ } else if (attrName === 'class') {
758
+ attrValue = trimWhitespace(attrValue);
759
+ if (options.sortClassName) {
760
+ attrValue = options.sortClassName(attrValue);
761
+ } else {
762
+ attrValue = collapseWhitespaceAll(attrValue);
763
+ }
764
+ return attrValue;
765
+ } else if (isUriTypeAttribute(attrName, tag)) {
766
+ attrValue = trimWhitespace(attrValue);
767
+ return isLinkType(tag, attrs, 'canonical') ? attrValue : options.minifyURLs(attrValue);
768
+ } else if (isNumberTypeAttribute(attrName, tag)) {
769
+ return trimWhitespace(attrValue);
770
+ } else if (attrName === 'style') {
771
+ attrValue = trimWhitespace(attrValue);
772
+ if (attrValue) {
773
+ if (/;$/.test(attrValue) && !/&#?[0-9a-zA-Z]+;$/.test(attrValue)) {
774
+ attrValue = attrValue.replace(/\s*;$/, ';');
775
+ }
776
+ attrValue = await options.minifyCSS(attrValue, 'inline');
777
+ }
778
+ return attrValue;
779
+ } else if (isSrcset(attrName, tag)) {
780
+ // https://html.spec.whatwg.org/multipage/embedded-content.html#attr-img-srcset
781
+ attrValue = trimWhitespace(attrValue).split(/\s+,\s*|\s*,\s+/).map(function (candidate) {
782
+ let url = candidate;
783
+ let descriptor = '';
784
+ const match = candidate.match(/\s+([1-9][0-9]*w|[0-9]+(?:\.[0-9]+)?x)$/);
785
+ if (match) {
786
+ url = url.slice(0, -match[0].length);
787
+ const num = +match[1].slice(0, -1);
788
+ const suffix = match[1].slice(-1);
789
+ if (num !== 1 || suffix !== 'x') {
790
+ descriptor = ' ' + num + suffix;
791
+ }
792
+ }
793
+ return options.minifyURLs(url) + descriptor;
794
+ }).join(', ');
795
+ } else if (isMetaViewport(tag, attrs) && attrName === 'content') {
796
+ attrValue = attrValue.replace(/\s+/g, '').replace(/[0-9]+\.[0-9]+/g, function (numString) {
797
+ // "0.90000" -> "0.9"
798
+ // "1.0" -> "1"
799
+ // "1.0001" -> "1.0001" (unchanged)
800
+ return (+numString).toString();
801
+ });
802
+ } else if (isContentSecurityPolicy(tag, attrs) && attrName.toLowerCase() === 'content') {
803
+ return collapseWhitespaceAll(attrValue);
804
+ } else if (options.customAttrCollapse && options.customAttrCollapse.test(attrName)) {
805
+ attrValue = trimWhitespace(attrValue.replace(/ ?[\n\r]+ ?/g, '').replace(/\s{2,}/g, options.conservativeCollapse ? ' ' : ''));
806
+ } else if (tag === 'script' && attrName === 'type') {
807
+ attrValue = trimWhitespace(attrValue.replace(/\s*;\s*/g, ';'));
808
+ } else if (isMediaQuery(tag, attrs, attrName)) {
809
+ attrValue = trimWhitespace(attrValue);
810
+ return options.minifyCSS(attrValue, 'media');
811
+ }
812
+ return attrValue;
813
+ }
814
+
815
+ function isMetaViewport(tag, attrs) {
816
+ if (tag !== 'meta') {
817
+ return false;
818
+ }
819
+ for (let i = 0, len = attrs.length; i < len; i++) {
820
+ if (attrs[i].name === 'name' && attrs[i].value === 'viewport') {
821
+ return true;
822
+ }
823
+ }
824
+ }
825
+
826
+ function isContentSecurityPolicy(tag, attrs) {
827
+ if (tag !== 'meta') {
828
+ return false;
829
+ }
830
+ for (let i = 0, len = attrs.length; i < len; i++) {
831
+ if (attrs[i].name.toLowerCase() === 'http-equiv' && attrs[i].value.toLowerCase() === 'content-security-policy') {
832
+ return true;
833
+ }
834
+ }
835
+ }
836
+
837
+ function ignoreCSS(id) {
838
+ return '/* clean-css ignore:start */' + id + '/* clean-css ignore:end */';
839
+ }
840
+
841
+ // Wrap CSS declarations for CleanCSS > 3.x
842
+ // See https://github.com/jakubpawlowicz/clean-css/issues/418
843
+ function wrapCSS(text, type) {
844
+ switch (type) {
845
+ case 'inline':
846
+ return '*{' + text + '}';
847
+ case 'media':
848
+ return '@media ' + text + '{a{top:0}}';
849
+ default:
850
+ return text;
851
+ }
852
+ }
853
+
854
+ function unwrapCSS(text, type) {
855
+ let matches;
856
+ switch (type) {
857
+ case 'inline':
858
+ matches = text.match(/^\*\{([\s\S]*)\}$/);
859
+ break;
860
+ case 'media':
861
+ matches = text.match(/^@media ([\s\S]*?)\s*{[\s\S]*}$/);
862
+ break;
863
+ }
864
+ return matches ? matches[1] : text;
865
+ }
866
+
867
+ async function cleanConditionalComment(comment, options) {
868
+ return options.processConditionalComments
869
+ ? await replaceAsync(comment, /^(\[if\s[^\]]+]>)([\s\S]*?)(<!\[endif])$/, async function (match, prefix, text, suffix) {
870
+ return prefix + await minifyHTML(text, options, true) + suffix;
871
+ })
872
+ : comment;
873
+ }
874
+
875
+ async function processScript(text, options, currentAttrs) {
876
+ for (let i = 0, len = currentAttrs.length; i < len; i++) {
877
+ if (currentAttrs[i].name.toLowerCase() === 'type' &&
878
+ options.processScripts.indexOf(currentAttrs[i].value) > -1) {
879
+ return await minifyHTML(text, options);
880
+ }
881
+ }
882
+ return text;
883
+ }
884
+
885
+ // Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
886
+ // with the following deviations:
887
+ // - retain <body> if followed by <noscript>
888
+ // - </rb>, </rt>, </rtc>, </rp> & </tfoot> follow https://www.w3.org/TR/html5/syntax.html#optional-tags
889
+ // - retain all tags which are adjacent to non-standard HTML tags
890
+ const optionalStartTags = new Set(['html', 'head', 'body', 'colgroup', 'tbody']);
891
+ const optionalEndTags = new Set(['html', 'head', 'body', 'li', 'dt', 'dd', 'p', 'rb', 'rt', 'rtc', 'rp', 'optgroup', 'option', 'colgroup', 'caption', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'th']);
892
+ const headerTags = new Set(['meta', 'link', 'script', 'style', 'template', 'noscript']);
893
+ const descriptionTags = new Set(['dt', 'dd']);
894
+ const pBlockTags = new Set(['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']);
895
+ const pInlineTags = new Set(['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video']);
896
+ const rubyTags = new Set(['rb', 'rt', 'rtc', 'rp']);
897
+ const rtcTag = new Set(['rb', 'rtc', 'rp']);
898
+ const optionTag = new Set(['option', 'optgroup']);
899
+ const tableContentTags = new Set(['tbody', 'tfoot']);
900
+ const tableSectionTags = new Set(['thead', 'tbody', 'tfoot']);
901
+ const cellTags = new Set(['td', 'th']);
902
+ const topLevelTags = new Set(['html', 'head', 'body']);
903
+ const compactTags = new Set(['html', 'body']);
904
+ const looseTags = new Set(['head', 'colgroup', 'caption']);
905
+ const trailingTags = new Set(['dt', 'thead']);
906
+ const htmlTags = new Set(['a', 'abbr', 'acronym', 'address', 'applet', 'area', 'article', 'aside', 'audio', 'b', 'base', 'basefont', 'bdi', 'bdo', 'bgsound', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'content', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'image', 'img', 'input', 'ins', 'isindex', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'listing', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meta', 'meter', 'multicol', 'nav', 'nobr', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'plaintext', 'pre', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'script', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr', 'xmp']);
907
+
908
+ function canRemoveParentTag(optionalStartTag, tag) {
909
+ switch (optionalStartTag) {
910
+ case 'html':
911
+ case 'head':
912
+ return true;
913
+ case 'body':
914
+ return !headerTags.has(tag);
915
+ case 'colgroup':
916
+ return tag === 'col';
917
+ case 'tbody':
918
+ return tag === 'tr';
919
+ }
920
+ return false;
921
+ }
922
+
923
+ function isStartTagMandatory(optionalEndTag, tag) {
924
+ switch (tag) {
925
+ case 'colgroup':
926
+ return optionalEndTag === 'colgroup';
927
+ case 'tbody':
928
+ return tableSectionTags.has(optionalEndTag);
929
+ }
930
+ return false;
931
+ }
932
+
933
+ function canRemovePrecedingTag(optionalEndTag, tag) {
934
+ switch (optionalEndTag) {
935
+ case 'html':
936
+ case 'head':
937
+ case 'body':
938
+ case 'colgroup':
939
+ case 'caption':
940
+ return true;
941
+ case 'li':
942
+ case 'optgroup':
943
+ case 'tr':
944
+ return tag === optionalEndTag;
945
+ case 'dt':
946
+ case 'dd':
947
+ return descriptionTags.has(tag);
948
+ case 'p':
949
+ return pBlockTags.has(tag);
950
+ case 'rb':
951
+ case 'rt':
952
+ case 'rp':
953
+ return rubyTags.has(tag);
954
+ case 'rtc':
955
+ return rtcTag.has(tag);
956
+ case 'option':
957
+ return optionTag.has(tag);
958
+ case 'thead':
959
+ case 'tbody':
960
+ return tableContentTags.has(tag);
961
+ case 'tfoot':
962
+ return tag === 'tbody';
963
+ case 'td':
964
+ case 'th':
965
+ return cellTags.has(tag);
966
+ }
967
+ return false;
968
+ }
969
+
970
+ const reEmptyAttribute = new RegExp(
971
+ '^(?:class|id|style|title|lang|dir|on(?:focus|blur|change|click|dblclick|mouse(' +
972
+ '?:down|up|over|move|out)|key(?:press|down|up)))$');
973
+
974
+ function canDeleteEmptyAttribute(tag, attrName, attrValue, options) {
975
+ const isValueEmpty = !attrValue || /^\s*$/.test(attrValue);
976
+ if (!isValueEmpty) {
977
+ return false;
978
+ }
979
+ if (typeof options.removeEmptyAttributes === 'function') {
980
+ return options.removeEmptyAttributes(attrName, tag);
981
+ }
982
+ return (tag === 'input' && attrName === 'value') || reEmptyAttribute.test(attrName);
983
+ }
984
+
985
+ function hasAttrName(name, attrs) {
986
+ for (let i = attrs.length - 1; i >= 0; i--) {
987
+ if (attrs[i].name === name) {
988
+ return true;
989
+ }
990
+ }
991
+ return false;
992
+ }
993
+
994
+ function canRemoveElement(tag, attrs) {
995
+ switch (tag) {
996
+ case 'textarea':
997
+ return false;
998
+ case 'audio':
999
+ case 'script':
1000
+ case 'video':
1001
+ if (hasAttrName('src', attrs)) {
1002
+ return false;
1003
+ }
1004
+ break;
1005
+ case 'iframe':
1006
+ if (hasAttrName('src', attrs) || hasAttrName('srcdoc', attrs)) {
1007
+ return false;
1008
+ }
1009
+ break;
1010
+ case 'object':
1011
+ if (hasAttrName('data', attrs)) {
1012
+ return false;
1013
+ }
1014
+ break;
1015
+ case 'applet':
1016
+ if (hasAttrName('code', attrs)) {
1017
+ return false;
1018
+ }
1019
+ break;
1020
+ }
1021
+ return true;
1022
+ }
1023
+
1024
+ function canCollapseWhitespace(tag) {
1025
+ return !/^(?:script|style|pre|textarea)$/.test(tag);
1026
+ }
1027
+
1028
+ function canTrimWhitespace(tag) {
1029
+ return !/^(?:pre|textarea)$/.test(tag);
1030
+ }
1031
+
1032
+ async function normalizeAttr(attr, attrs, tag, options) {
1033
+ const attrName = options.name(attr.name);
1034
+ let attrValue = attr.value;
1035
+
1036
+ if (options.decodeEntities && attrValue) {
1037
+ attrValue = entities.decodeHTMLStrict(attrValue);
1038
+ }
1039
+
1040
+ if ((options.removeRedundantAttributes &&
1041
+ isAttributeRedundant(tag, attrName, attrValue, attrs)) ||
1042
+ (options.removeScriptTypeAttributes && tag === 'script' &&
1043
+ attrName === 'type' && isScriptTypeAttribute(attrValue) && !keepScriptTypeAttribute(attrValue)) ||
1044
+ (options.removeStyleLinkTypeAttributes && (tag === 'style' || tag === 'link') &&
1045
+ attrName === 'type' && isStyleLinkTypeAttribute(attrValue))) {
1046
+ return;
1047
+ }
1048
+
1049
+ if (attrValue) {
1050
+ attrValue = await cleanAttributeValue(tag, attrName, attrValue, options, attrs);
1051
+ }
1052
+
1053
+ if (options.removeEmptyAttributes &&
1054
+ canDeleteEmptyAttribute(tag, attrName, attrValue, options)) {
1055
+ return;
1056
+ }
1057
+
1058
+ if (options.decodeEntities && attrValue) {
1059
+ attrValue = attrValue.replace(/&(#?[0-9a-zA-Z]+;)/g, '&amp;$1');
1060
+ }
1061
+
1062
+ return {
1063
+ attr,
1064
+ name: attrName,
1065
+ value: attrValue
1066
+ };
1067
+ }
1068
+
1069
+ function buildAttr(normalized, hasUnarySlash, options, isLast, uidAttr) {
1070
+ const attrName = normalized.name;
1071
+ let attrValue = normalized.value;
1072
+ const attr = normalized.attr;
1073
+ let attrQuote = attr.quote;
1074
+ let attrFragment;
1075
+ let emittedAttrValue;
1076
+
1077
+ if (typeof attrValue !== 'undefined' && (!options.removeAttributeQuotes ||
1078
+ ~attrValue.indexOf(uidAttr) || !canRemoveAttributeQuotes(attrValue))) {
1079
+ if (!options.preventAttributesEscaping) {
1080
+ if (typeof options.quoteCharacter === 'undefined') {
1081
+ const apos = (attrValue.match(/'/g) || []).length;
1082
+ const quot = (attrValue.match(/"/g) || []).length;
1083
+ attrQuote = apos < quot ? '\'' : '"';
1084
+ } else {
1085
+ attrQuote = options.quoteCharacter === '\'' ? '\'' : '"';
1086
+ }
1087
+ if (attrQuote === '"') {
1088
+ attrValue = attrValue.replace(/"/g, '&#34;');
1089
+ } else {
1090
+ attrValue = attrValue.replace(/'/g, '&#39;');
1091
+ }
1092
+ }
1093
+ emittedAttrValue = attrQuote + attrValue + attrQuote;
1094
+ if (!isLast && !options.removeTagWhitespace) {
1095
+ emittedAttrValue += ' ';
1096
+ }
1097
+ } else if (isLast && !hasUnarySlash && !/\/$/.test(attrValue)) {
1098
+ // make sure trailing slash is not interpreted as HTML self-closing tag
1099
+ emittedAttrValue = attrValue;
1100
+ } else {
1101
+ emittedAttrValue = attrValue + ' ';
1102
+ }
1103
+
1104
+ if (typeof attrValue === 'undefined' || (options.collapseBooleanAttributes &&
1105
+ isBooleanAttribute(attrName.toLowerCase(), attrValue.toLowerCase()))) {
1106
+ attrFragment = attrName;
1107
+ if (!isLast) {
1108
+ attrFragment += ' ';
1109
+ }
1110
+ } else {
1111
+ attrFragment = attrName + attr.customAssign + emittedAttrValue;
1112
+ }
1113
+
1114
+ return attr.customOpen + attrFragment + attr.customClose;
1115
+ }
1116
+
1117
+ function identity(value) {
1118
+ return value;
1119
+ }
1120
+
1121
+ function identityAsync(value) {
1122
+ return Promise.resolve(value);
1123
+ }
1124
+
1125
+ const processOptions = (inputOptions) => {
1126
+ const options = {
1127
+ name: function (name) {
1128
+ return name.toLowerCase();
1129
+ },
1130
+ canCollapseWhitespace,
1131
+ canTrimWhitespace,
1132
+ html5: true,
1133
+ ignoreCustomComments: [
1134
+ /^!/,
1135
+ /^\s*#/
1136
+ ],
1137
+ ignoreCustomFragments: [
1138
+ /<%[\s\S]*?%>/,
1139
+ /<\?[\s\S]*?\?>/
1140
+ ],
1141
+ includeAutoGeneratedTags: true,
1142
+ log: identity,
1143
+ minifyCSS: identityAsync,
1144
+ minifyJS: identity,
1145
+ minifyURLs: identity
1146
+ };
1147
+
1148
+ Object.keys(inputOptions).forEach(function (key) {
1149
+ const option = inputOptions[key];
1150
+
1151
+ if (key === 'caseSensitive') {
1152
+ if (option) {
1153
+ options.name = identity;
1154
+ }
1155
+ } else if (key === 'log') {
1156
+ if (typeof option === 'function') {
1157
+ options.log = option;
1158
+ }
1159
+ } else if (key === 'minifyCSS' && typeof option !== 'function') {
1160
+ if (!option) {
1161
+ return;
1162
+ }
1163
+
1164
+ const cleanCssOptions = typeof option === 'object' ? option : {};
1165
+
1166
+ options.minifyCSS = async function (text, type) {
1167
+ text = text.replace(/(url\s*\(\s*)("|'|)(.*?)\2(\s*\))/ig, function (match, prefix, quote, url, suffix) {
1168
+ return prefix + quote + options.minifyURLs(url) + quote + suffix;
1169
+ });
1170
+
1171
+ const inputCSS = wrapCSS(text, type);
1172
+
1173
+ return new Promise((resolve) => {
1174
+ new CleanCSS(cleanCssOptions).minify(inputCSS, (_err, output) => {
1175
+ if (output.errors.length > 0) {
1176
+ output.errors.forEach(options.log);
1177
+ resolve(text);
1178
+ }
1179
+
1180
+ const outputCSS = unwrapCSS(output.styles, type);
1181
+ resolve(outputCSS);
1182
+ });
1183
+ });
1184
+ };
1185
+ } else if (key === 'minifyJS' && typeof option !== 'function') {
1186
+ if (!option) {
1187
+ return;
1188
+ }
1189
+
1190
+ const terserOptions = typeof option === 'object' ? option : {};
1191
+
1192
+ terserOptions.parse = {
1193
+ ...terserOptions.parse,
1194
+ bare_returns: false
1195
+ };
1196
+
1197
+ options.minifyJS = async function (text, inline) {
1198
+ const start = text.match(/^\s*<!--.*/);
1199
+ const code = start ? text.slice(start[0].length).replace(/\n\s*-->\s*$/, '') : text;
1200
+
1201
+ terserOptions.parse.bare_returns = inline;
1202
+
1203
+ try {
1204
+ const result = await terser.minify(code, terserOptions);
1205
+ return result.code.replace(/;$/, '');
1206
+ } catch (error) {
1207
+ options.log(error);
1208
+ return text;
1209
+ }
1210
+ };
1211
+ } else if (key === 'minifyURLs' && typeof option !== 'function') {
1212
+ if (!option) {
1213
+ return;
1214
+ }
1215
+
1216
+ let relateUrlOptions = option;
1217
+
1218
+ if (typeof option === 'string') {
1219
+ relateUrlOptions = { site: option };
1220
+ } else if (typeof option !== 'object') {
1221
+ relateUrlOptions = {};
1222
+ }
1223
+
1224
+ options.minifyURLs = function (text) {
1225
+ try {
1226
+ return RelateURL.relate(text, relateUrlOptions);
1227
+ } catch (err) {
1228
+ options.log(err);
1229
+ return text;
1230
+ }
1231
+ };
1232
+ } else {
1233
+ options[key] = option;
1234
+ }
1235
+ });
1236
+ return options;
1237
+ };
1238
+
1239
+ function uniqueId(value) {
1240
+ let id;
1241
+ do {
1242
+ id = Math.random().toString(36).replace(/^0\.[0-9]*/, '');
1243
+ } while (~value.indexOf(id));
1244
+ return id;
1245
+ }
1246
+
1247
+ const specialContentTags = new Set(['script', 'style']);
1248
+
1249
+ async function createSortFns(value, options, uidIgnore, uidAttr) {
1250
+ const attrChains = options.sortAttributes && Object.create(null);
1251
+ const classChain = options.sortClassName && new TokenChain();
1252
+
1253
+ function attrNames(attrs) {
1254
+ return attrs.map(function (attr) {
1255
+ return options.name(attr.name);
1256
+ });
1257
+ }
1258
+
1259
+ function shouldSkipUID(token, uid) {
1260
+ return !uid || token.indexOf(uid) === -1;
1261
+ }
1262
+
1263
+ function shouldSkipUIDs(token) {
1264
+ return shouldSkipUID(token, uidIgnore) && shouldSkipUID(token, uidAttr);
1265
+ }
1266
+
1267
+ async function scan(input) {
1268
+ let currentTag, currentType;
1269
+ const parser = new HTMLParser(input, {
1270
+ start: function (tag, attrs) {
1271
+ if (attrChains) {
1272
+ if (!attrChains[tag]) {
1273
+ attrChains[tag] = new TokenChain();
1274
+ }
1275
+ attrChains[tag].add(attrNames(attrs).filter(shouldSkipUIDs));
1276
+ }
1277
+ for (let i = 0, len = attrs.length; i < len; i++) {
1278
+ const attr = attrs[i];
1279
+ if (classChain && attr.value && options.name(attr.name) === 'class') {
1280
+ classChain.add(trimWhitespace(attr.value).split(/[ \t\n\f\r]+/).filter(shouldSkipUIDs));
1281
+ } else if (options.processScripts && attr.name.toLowerCase() === 'type') {
1282
+ currentTag = tag;
1283
+ currentType = attr.value;
1284
+ }
1285
+ }
1286
+ },
1287
+ end: function () {
1288
+ currentTag = '';
1289
+ },
1290
+ chars: async function (text) {
1291
+ if (options.processScripts && specialContentTags.has(currentTag) &&
1292
+ options.processScripts.indexOf(currentType) > -1) {
1293
+ await scan(text);
1294
+ }
1295
+ }
1296
+ });
1297
+
1298
+ await parser.parse();
1299
+ }
1300
+
1301
+ const log = options.log;
1302
+ options.log = identity;
1303
+ options.sortAttributes = false;
1304
+ options.sortClassName = false;
1305
+ await scan(await minifyHTML(value, options));
1306
+ options.log = log;
1307
+ if (attrChains) {
1308
+ const attrSorters = Object.create(null);
1309
+ for (const tag in attrChains) {
1310
+ attrSorters[tag] = attrChains[tag].createSorter();
1311
+ }
1312
+ options.sortAttributes = function (tag, attrs) {
1313
+ const sorter = attrSorters[tag];
1314
+ if (sorter) {
1315
+ const attrMap = Object.create(null);
1316
+ const names = attrNames(attrs);
1317
+ names.forEach(function (name, index) {
1318
+ (attrMap[name] || (attrMap[name] = [])).push(attrs[index]);
1319
+ });
1320
+ sorter.sort(names).forEach(function (name, index) {
1321
+ attrs[index] = attrMap[name].shift();
1322
+ });
1323
+ }
1324
+ };
1325
+ }
1326
+ if (classChain) {
1327
+ const sorter = classChain.createSorter();
1328
+ options.sortClassName = function (value) {
1329
+ return sorter.sort(value.split(/[ \n\f\r]+/)).join(' ');
1330
+ };
1331
+ }
1332
+ }
1333
+
1334
+ async function minifyHTML(value, options, partialMarkup) {
1335
+ if (options.collapseWhitespace) {
1336
+ value = collapseWhitespace(value, options, true, true);
1337
+ }
1338
+
1339
+ const buffer = [];
1340
+ let charsPrevTag;
1341
+ let currentChars = '';
1342
+ let hasChars;
1343
+ let currentTag = '';
1344
+ let currentAttrs = [];
1345
+ const stackNoTrimWhitespace = [];
1346
+ const stackNoCollapseWhitespace = [];
1347
+ let optionalStartTag = '';
1348
+ let optionalEndTag = '';
1349
+ const ignoredMarkupChunks = [];
1350
+ const ignoredCustomMarkupChunks = [];
1351
+ let uidIgnore;
1352
+ let uidAttr;
1353
+ let uidPattern;
1354
+
1355
+ // temporarily replace ignored chunks with comments,
1356
+ // so that we don't have to worry what's there.
1357
+ // for all we care there might be
1358
+ // completely-horribly-broken-alien-non-html-emoj-cthulhu-filled content
1359
+ value = value.replace(/<!-- htmlmin:ignore -->([\s\S]*?)<!-- htmlmin:ignore -->/g, function (match, group1) {
1360
+ if (!uidIgnore) {
1361
+ uidIgnore = uniqueId(value);
1362
+ const pattern = new RegExp('^' + uidIgnore + '([0-9]+)$');
1363
+ if (options.ignoreCustomComments) {
1364
+ options.ignoreCustomComments = options.ignoreCustomComments.slice();
1365
+ } else {
1366
+ options.ignoreCustomComments = [];
1367
+ }
1368
+ options.ignoreCustomComments.push(pattern);
1369
+ }
1370
+ const token = '<!--' + uidIgnore + ignoredMarkupChunks.length + '-->';
1371
+ ignoredMarkupChunks.push(group1);
1372
+ return token;
1373
+ });
1374
+
1375
+ const customFragments = options.ignoreCustomFragments.map(function (re) {
1376
+ return re.source;
1377
+ });
1378
+ if (customFragments.length) {
1379
+ const reCustomIgnore = new RegExp('\\s*(?:' + customFragments.join('|') + ')+\\s*', 'g');
1380
+ // temporarily replace custom ignored fragments with unique attributes
1381
+ value = value.replace(reCustomIgnore, function (match) {
1382
+ if (!uidAttr) {
1383
+ uidAttr = uniqueId(value);
1384
+ uidPattern = new RegExp('(\\s*)' + uidAttr + '([0-9]+)' + uidAttr + '(\\s*)', 'g');
1385
+
1386
+ if (options.minifyCSS) {
1387
+ options.minifyCSS = (function (fn) {
1388
+ return function (text, type) {
1389
+ text = text.replace(uidPattern, function (match, prefix, index) {
1390
+ const chunks = ignoredCustomMarkupChunks[+index];
1391
+ return chunks[1] + uidAttr + index + uidAttr + chunks[2];
1392
+ });
1393
+
1394
+ const ids = [];
1395
+ new CleanCSS().minify(wrapCSS(text, type)).warnings.forEach(function (warning) {
1396
+ const match = uidPattern.exec(warning);
1397
+ if (match) {
1398
+ const id = uidAttr + match[2] + uidAttr;
1399
+ text = text.replace(id, ignoreCSS(id));
1400
+ ids.push(id);
1401
+ }
1402
+ });
1403
+
1404
+ return fn(text, type).then(chunk => {
1405
+ ids.forEach(function (id) {
1406
+ chunk = chunk.replace(ignoreCSS(id), id);
1407
+ });
1408
+
1409
+ return chunk;
1410
+ });
1411
+ };
1412
+ })(options.minifyCSS);
1413
+ }
1414
+
1415
+ if (options.minifyJS) {
1416
+ options.minifyJS = (function (fn) {
1417
+ return function (text, type) {
1418
+ return fn(text.replace(uidPattern, function (match, prefix, index) {
1419
+ const chunks = ignoredCustomMarkupChunks[+index];
1420
+ return chunks[1] + uidAttr + index + uidAttr + chunks[2];
1421
+ }), type);
1422
+ };
1423
+ })(options.minifyJS);
1424
+ }
1425
+ }
1426
+
1427
+ const token = uidAttr + ignoredCustomMarkupChunks.length + uidAttr;
1428
+ ignoredCustomMarkupChunks.push(/^(\s*)[\s\S]*?(\s*)$/.exec(match));
1429
+ return '\t' + token + '\t';
1430
+ });
1431
+ }
1432
+
1433
+ if ((options.sortAttributes && typeof options.sortAttributes !== 'function') ||
1434
+ (options.sortClassName && typeof options.sortClassName !== 'function')) {
1435
+ await createSortFns(value, options, uidIgnore, uidAttr);
1436
+ }
1437
+
1438
+ function _canCollapseWhitespace(tag, attrs) {
1439
+ return options.canCollapseWhitespace(tag, attrs, canCollapseWhitespace);
1440
+ }
1441
+
1442
+ function _canTrimWhitespace(tag, attrs) {
1443
+ return options.canTrimWhitespace(tag, attrs, canTrimWhitespace);
1444
+ }
1445
+
1446
+ function removeStartTag() {
1447
+ let index = buffer.length - 1;
1448
+ while (index > 0 && !/^<[^/!]/.test(buffer[index])) {
1449
+ index--;
1450
+ }
1451
+ buffer.length = Math.max(0, index);
1452
+ }
1453
+
1454
+ function removeEndTag() {
1455
+ let index = buffer.length - 1;
1456
+ while (index > 0 && !/^<\//.test(buffer[index])) {
1457
+ index--;
1458
+ }
1459
+ buffer.length = Math.max(0, index);
1460
+ }
1461
+
1462
+ // look for trailing whitespaces, bypass any inline tags
1463
+ function trimTrailingWhitespace(index, nextTag) {
1464
+ for (let endTag = null; index >= 0 && _canTrimWhitespace(endTag); index--) {
1465
+ const str = buffer[index];
1466
+ const match = str.match(/^<\/([\w:-]+)>$/);
1467
+ if (match) {
1468
+ endTag = match[1];
1469
+ } else if (/>$/.test(str) || (buffer[index] = collapseWhitespaceSmart(str, null, nextTag, options))) {
1470
+ break;
1471
+ }
1472
+ }
1473
+ }
1474
+
1475
+ // look for trailing whitespaces from previously processed text
1476
+ // which may not be trimmed due to a following comment or an empty
1477
+ // element which has now been removed
1478
+ function squashTrailingWhitespace(nextTag) {
1479
+ let charsIndex = buffer.length - 1;
1480
+ if (buffer.length > 1) {
1481
+ const item = buffer[buffer.length - 1];
1482
+ if (/^(?:<!|$)/.test(item) && item.indexOf(uidIgnore) === -1) {
1483
+ charsIndex--;
1484
+ }
1485
+ }
1486
+ trimTrailingWhitespace(charsIndex, nextTag);
1487
+ }
1488
+
1489
+ const parser = new HTMLParser(value, {
1490
+ partialMarkup,
1491
+ continueOnParseError: options.continueOnParseError,
1492
+ customAttrAssign: options.customAttrAssign,
1493
+ customAttrSurround: options.customAttrSurround,
1494
+ html5: options.html5,
1495
+
1496
+ start: async function (tag, attrs, unary, unarySlash, autoGenerated) {
1497
+ if (tag.toLowerCase() === 'svg') {
1498
+ options = Object.create(options);
1499
+ options.caseSensitive = true;
1500
+ options.keepClosingSlash = true;
1501
+ options.name = identity;
1502
+ }
1503
+ tag = options.name(tag);
1504
+ currentTag = tag;
1505
+ charsPrevTag = tag;
1506
+ if (!inlineTextTags.has(tag)) {
1507
+ currentChars = '';
1508
+ }
1509
+ hasChars = false;
1510
+ currentAttrs = attrs;
1511
+
1512
+ let optional = options.removeOptionalTags;
1513
+ if (optional) {
1514
+ const htmlTag = htmlTags.has(tag);
1515
+ // <html> may be omitted if first thing inside is not comment
1516
+ // <head> may be omitted if first thing inside is an element
1517
+ // <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
1518
+ // <colgroup> may be omitted if first thing inside is <col>
1519
+ // <tbody> may be omitted if first thing inside is <tr>
1520
+ if (htmlTag && canRemoveParentTag(optionalStartTag, tag)) {
1521
+ removeStartTag();
1522
+ }
1523
+ optionalStartTag = '';
1524
+ // end-tag-followed-by-start-tag omission rules
1525
+ if (htmlTag && canRemovePrecedingTag(optionalEndTag, tag)) {
1526
+ removeEndTag();
1527
+ // <colgroup> cannot be omitted if preceding </colgroup> is omitted
1528
+ // <tbody> cannot be omitted if preceding </tbody>, </thead> or </tfoot> is omitted
1529
+ optional = !isStartTagMandatory(optionalEndTag, tag);
1530
+ }
1531
+ optionalEndTag = '';
1532
+ }
1533
+
1534
+ // set whitespace flags for nested tags (eg. <code> within a <pre>)
1535
+ if (options.collapseWhitespace) {
1536
+ if (!stackNoTrimWhitespace.length) {
1537
+ squashTrailingWhitespace(tag);
1538
+ }
1539
+ if (!unary) {
1540
+ if (!_canTrimWhitespace(tag, attrs) || stackNoTrimWhitespace.length) {
1541
+ stackNoTrimWhitespace.push(tag);
1542
+ }
1543
+ if (!_canCollapseWhitespace(tag, attrs) || stackNoCollapseWhitespace.length) {
1544
+ stackNoCollapseWhitespace.push(tag);
1545
+ }
1546
+ }
1547
+ }
1548
+
1549
+ const openTag = '<' + tag;
1550
+ const hasUnarySlash = unarySlash && options.keepClosingSlash;
1551
+
1552
+ buffer.push(openTag);
1553
+
1554
+ if (options.sortAttributes) {
1555
+ options.sortAttributes(tag, attrs);
1556
+ }
1557
+
1558
+ const parts = [];
1559
+ for (let i = attrs.length, isLast = true; --i >= 0;) {
1560
+ const normalized = await normalizeAttr(attrs[i], attrs, tag, options);
1561
+ if (normalized) {
1562
+ parts.unshift(buildAttr(normalized, hasUnarySlash, options, isLast, uidAttr));
1563
+ isLast = false;
1564
+ }
1565
+ }
1566
+ if (parts.length > 0) {
1567
+ buffer.push(' ');
1568
+ buffer.push.apply(buffer, parts);
1569
+ } else if (optional && optionalStartTags.has(tag)) {
1570
+ // start tag must never be omitted if it has any attributes
1571
+ optionalStartTag = tag;
1572
+ }
1573
+
1574
+ buffer.push(buffer.pop() + (hasUnarySlash ? '/' : '') + '>');
1575
+
1576
+ if (autoGenerated && !options.includeAutoGeneratedTags) {
1577
+ removeStartTag();
1578
+ optionalStartTag = '';
1579
+ }
1580
+ },
1581
+ end: function (tag, attrs, autoGenerated) {
1582
+ if (tag.toLowerCase() === 'svg') {
1583
+ options = Object.getPrototypeOf(options);
1584
+ }
1585
+ tag = options.name(tag);
1586
+
1587
+ // check if current tag is in a whitespace stack
1588
+ if (options.collapseWhitespace) {
1589
+ if (stackNoTrimWhitespace.length) {
1590
+ if (tag === stackNoTrimWhitespace[stackNoTrimWhitespace.length - 1]) {
1591
+ stackNoTrimWhitespace.pop();
1592
+ }
1593
+ } else {
1594
+ squashTrailingWhitespace('/' + tag);
1595
+ }
1596
+ if (stackNoCollapseWhitespace.length &&
1597
+ tag === stackNoCollapseWhitespace[stackNoCollapseWhitespace.length - 1]) {
1598
+ stackNoCollapseWhitespace.pop();
1599
+ }
1600
+ }
1601
+
1602
+ let isElementEmpty = false;
1603
+ if (tag === currentTag) {
1604
+ currentTag = '';
1605
+ isElementEmpty = !hasChars;
1606
+ }
1607
+
1608
+ if (options.removeOptionalTags) {
1609
+ // <html>, <head> or <body> may be omitted if the element is empty
1610
+ if (isElementEmpty && topLevelTags.has(optionalStartTag)) {
1611
+ removeStartTag();
1612
+ }
1613
+ optionalStartTag = '';
1614
+ // </html> or </body> may be omitted if not followed by comment
1615
+ // </head> may be omitted if not followed by space or comment
1616
+ // </p> may be omitted if no more content in non-</a> parent
1617
+ // except for </dt> or </thead>, end tags may be omitted if no more content in parent element
1618
+ if (htmlTags.has(tag) && optionalEndTag && !trailingTags.has(optionalEndTag) && (optionalEndTag !== 'p' || !pInlineTags.has(tag))) {
1619
+ removeEndTag();
1620
+ }
1621
+ optionalEndTag = optionalEndTags.has(tag) ? tag : '';
1622
+ }
1623
+
1624
+ if (options.removeEmptyElements && isElementEmpty && canRemoveElement(tag, attrs)) {
1625
+ // remove last "element" from buffer
1626
+ removeStartTag();
1627
+ optionalStartTag = '';
1628
+ optionalEndTag = '';
1629
+ } else {
1630
+ if (autoGenerated && !options.includeAutoGeneratedTags) {
1631
+ optionalEndTag = '';
1632
+ } else {
1633
+ buffer.push('</' + tag + '>');
1634
+ }
1635
+ charsPrevTag = '/' + tag;
1636
+ if (!inlineTags.has(tag)) {
1637
+ currentChars = '';
1638
+ } else if (isElementEmpty) {
1639
+ currentChars += '|';
1640
+ }
1641
+ }
1642
+ },
1643
+ chars: async function (text, prevTag, nextTag) {
1644
+ prevTag = prevTag === '' ? 'comment' : prevTag;
1645
+ nextTag = nextTag === '' ? 'comment' : nextTag;
1646
+ if (options.decodeEntities && text && !specialContentTags.has(currentTag)) {
1647
+ text = entities.decodeHTML(text);
1648
+ }
1649
+ if (options.collapseWhitespace) {
1650
+ if (!stackNoTrimWhitespace.length) {
1651
+ if (prevTag === 'comment') {
1652
+ const prevComment = buffer[buffer.length - 1];
1653
+ if (prevComment.indexOf(uidIgnore) === -1) {
1654
+ if (!prevComment) {
1655
+ prevTag = charsPrevTag;
1656
+ }
1657
+ if (buffer.length > 1 && (!prevComment || (!options.conservativeCollapse && / $/.test(currentChars)))) {
1658
+ const charsIndex = buffer.length - 2;
1659
+ buffer[charsIndex] = buffer[charsIndex].replace(/\s+$/, function (trailingSpaces) {
1660
+ text = trailingSpaces + text;
1661
+ return '';
1662
+ });
1663
+ }
1664
+ }
1665
+ }
1666
+ if (prevTag) {
1667
+ if (prevTag === '/nobr' || prevTag === 'wbr') {
1668
+ if (/^\s/.test(text)) {
1669
+ let tagIndex = buffer.length - 1;
1670
+ while (tagIndex > 0 && buffer[tagIndex].lastIndexOf('<' + prevTag) !== 0) {
1671
+ tagIndex--;
1672
+ }
1673
+ trimTrailingWhitespace(tagIndex - 1, 'br');
1674
+ }
1675
+ } else if (inlineTextTags.has(prevTag.charAt(0) === '/' ? prevTag.slice(1) : prevTag)) {
1676
+ text = collapseWhitespace(text, options, /(?:^|\s)$/.test(currentChars));
1677
+ }
1678
+ }
1679
+ if (prevTag || nextTag) {
1680
+ text = collapseWhitespaceSmart(text, prevTag, nextTag, options);
1681
+ } else {
1682
+ text = collapseWhitespace(text, options, true, true);
1683
+ }
1684
+ if (!text && /\s$/.test(currentChars) && prevTag && prevTag.charAt(0) === '/') {
1685
+ trimTrailingWhitespace(buffer.length - 1, nextTag);
1686
+ }
1687
+ }
1688
+ if (!stackNoCollapseWhitespace.length && nextTag !== 'html' && !(prevTag && nextTag)) {
1689
+ text = collapseWhitespace(text, options, false, false, true);
1690
+ }
1691
+ }
1692
+ if (options.processScripts && specialContentTags.has(currentTag)) {
1693
+ text = await processScript(text, options, currentAttrs);
1694
+ }
1695
+ if (isExecutableScript(currentTag, currentAttrs)) {
1696
+ text = await options.minifyJS(text);
1697
+ }
1698
+ if (isStyleSheet(currentTag, currentAttrs)) {
1699
+ text = await options.minifyCSS(text);
1700
+ }
1701
+ if (options.removeOptionalTags && text) {
1702
+ // <html> may be omitted if first thing inside is not comment
1703
+ // <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
1704
+ if (optionalStartTag === 'html' || (optionalStartTag === 'body' && !/^\s/.test(text))) {
1705
+ removeStartTag();
1706
+ }
1707
+ optionalStartTag = '';
1708
+ // </html> or </body> may be omitted if not followed by comment
1709
+ // </head>, </colgroup> or </caption> may be omitted if not followed by space or comment
1710
+ if (compactTags.has(optionalEndTag) || (looseTags.has(optionalEndTag) && !/^\s/.test(text))) {
1711
+ removeEndTag();
1712
+ }
1713
+ optionalEndTag = '';
1714
+ }
1715
+ charsPrevTag = /^\s*$/.test(text) ? prevTag : 'comment';
1716
+ if (options.decodeEntities && text && !specialContentTags.has(currentTag)) {
1717
+ // Escape any `&` symbols that start either:
1718
+ // 1) a legacy named character reference (i.e. one that doesn't end with `;`)
1719
+ // 2) or any other character reference (i.e. one that does end with `;`)
1720
+ // Note that `&` can be escaped as `&amp`, without the semi-colon.
1721
+ // https://mathiasbynens.be/notes/ambiguous-ampersands
1722
+ text = text.replace(/&((?:Iacute|aacute|uacute|plusmn|Otilde|otilde|agrave|Agrave|Yacute|yacute|Oslash|oslash|atilde|Atilde|brvbar|ccedil|Ccedil|Ograve|curren|divide|eacute|Eacute|ograve|Oacute|egrave|Egrave|Ugrave|frac12|frac14|frac34|ugrave|oacute|iacute|Ntilde|ntilde|Uacute|middot|igrave|Igrave|iquest|Aacute|cedil|laquo|micro|iexcl|Icirc|icirc|acirc|Ucirc|Ecirc|ocirc|Ocirc|ecirc|ucirc|Aring|aring|AElig|aelig|acute|pound|raquo|Acirc|times|THORN|szlig|thorn|COPY|auml|ordf|ordm|Uuml|macr|uuml|Auml|ouml|Ouml|para|nbsp|euml|quot|QUOT|Euml|yuml|cent|sect|copy|sup1|sup2|sup3|iuml|Iuml|ETH|shy|reg|not|yen|amp|AMP|REG|uml|eth|deg|gt|GT|LT|lt)(?!;)|(?:#?[0-9a-zA-Z]+;))/g, '&amp$1').replace(/</g, '&lt;');
1723
+ }
1724
+ if (uidPattern && options.collapseWhitespace && stackNoTrimWhitespace.length) {
1725
+ text = text.replace(uidPattern, function (match, prefix, index) {
1726
+ return ignoredCustomMarkupChunks[+index][0];
1727
+ });
1728
+ }
1729
+ currentChars += text;
1730
+ if (text) {
1731
+ hasChars = true;
1732
+ }
1733
+ buffer.push(text);
1734
+ },
1735
+ comment: async function (text, nonStandard) {
1736
+ const prefix = nonStandard ? '<!' : '<!--';
1737
+ const suffix = nonStandard ? '>' : '-->';
1738
+ if (isConditionalComment(text)) {
1739
+ text = prefix + await cleanConditionalComment(text, options) + suffix;
1740
+ } else if (options.removeComments) {
1741
+ if (isIgnoredComment(text, options)) {
1742
+ text = '<!--' + text + '-->';
1743
+ } else {
1744
+ text = '';
1745
+ }
1746
+ } else {
1747
+ text = prefix + text + suffix;
1748
+ }
1749
+ if (options.removeOptionalTags && text) {
1750
+ // preceding comments suppress tag omissions
1751
+ optionalStartTag = '';
1752
+ optionalEndTag = '';
1753
+ }
1754
+ buffer.push(text);
1755
+ },
1756
+ doctype: function (doctype) {
1757
+ buffer.push(options.useShortDoctype
1758
+ ? '<!doctype' +
1759
+ (options.removeTagWhitespace ? '' : ' ') + 'html>'
1760
+ : collapseWhitespaceAll(doctype));
1761
+ }
1762
+ });
1763
+
1764
+ await parser.parse();
1765
+
1766
+ if (options.removeOptionalTags) {
1767
+ // <html> may be omitted if first thing inside is not comment
1768
+ // <head> or <body> may be omitted if empty
1769
+ if (topLevelTags.has(optionalStartTag)) {
1770
+ removeStartTag();
1771
+ }
1772
+ // except for </dt> or </thead>, end tags may be omitted if no more content in parent element
1773
+ if (optionalEndTag && !trailingTags.has(optionalEndTag)) {
1774
+ removeEndTag();
1775
+ }
1776
+ }
1777
+ if (options.collapseWhitespace) {
1778
+ squashTrailingWhitespace('br');
1779
+ }
1780
+
1781
+ return joinResultSegments(buffer, options, uidPattern
1782
+ ? function (str) {
1783
+ return str.replace(uidPattern, function (match, prefix, index, suffix) {
1784
+ let chunk = ignoredCustomMarkupChunks[+index][0];
1785
+ if (options.collapseWhitespace) {
1786
+ if (prefix !== '\t') {
1787
+ chunk = prefix + chunk;
1788
+ }
1789
+ if (suffix !== '\t') {
1790
+ chunk += suffix;
1791
+ }
1792
+ return collapseWhitespace(chunk, {
1793
+ preserveLineBreaks: options.preserveLineBreaks,
1794
+ conservativeCollapse: !options.trimCustomFragments
1795
+ }, /^[ \n\r\t\f]/.test(chunk), /[ \n\r\t\f]$/.test(chunk));
1796
+ }
1797
+ return chunk;
1798
+ });
1799
+ }
1800
+ : identity, uidIgnore
1801
+ ? function (str) {
1802
+ return str.replace(new RegExp('<!--' + uidIgnore + '([0-9]+)-->', 'g'), function (match, index) {
1803
+ return ignoredMarkupChunks[+index];
1804
+ });
1805
+ }
1806
+ : identity);
1807
+ }
1808
+
1809
+ function joinResultSegments(results, options, restoreCustom, restoreIgnore) {
1810
+ let str;
1811
+ const maxLineLength = options.maxLineLength;
1812
+ const noNewlinesBeforeTagClose = options.noNewlinesBeforeTagClose;
1813
+
1814
+ if (maxLineLength) {
1815
+ let line = ''; const lines = [];
1816
+ while (results.length) {
1817
+ const len = line.length;
1818
+ const end = results[0].indexOf('\n');
1819
+ const isClosingTag = Boolean(results[0].match(endTag));
1820
+ const shouldKeepSameLine = noNewlinesBeforeTagClose && isClosingTag;
1821
+
1822
+ if (end < 0) {
1823
+ line += restoreIgnore(restoreCustom(results.shift()));
1824
+ } else {
1825
+ line += restoreIgnore(restoreCustom(results[0].slice(0, end)));
1826
+ results[0] = results[0].slice(end + 1);
1827
+ }
1828
+ if (len > 0 && line.length > maxLineLength && !shouldKeepSameLine) {
1829
+ lines.push(line.slice(0, len));
1830
+ line = line.slice(len);
1831
+ } else if (end >= 0) {
1832
+ lines.push(line);
1833
+ line = '';
1834
+ }
1835
+ }
1836
+ if (line) {
1837
+ lines.push(line);
1838
+ }
1839
+ str = lines.join('\n');
1840
+ } else {
1841
+ str = restoreIgnore(restoreCustom(results.join('')));
1842
+ }
1843
+ return options.collapseWhitespace ? collapseWhitespace(str, options, true, true) : str;
1844
+ }
1845
+
1846
+ const minify = async function (value, options) {
1847
+ const start = Date.now();
1848
+ options = processOptions(options || {});
1849
+ const result = await minifyHTML(value, options);
1850
+ options.log('minified in: ' + (Date.now() - start) + 'ms');
1851
+ return result;
1852
+ };
1853
+
1854
+ var htmlminifier = { minify };
1855
+
1856
+ exports.default = htmlminifier;
1857
+ exports.minify = minify;