@hkyhy/marsun-components-core 0.1.89 → 0.1.98

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/dist/components/Audit/AuditLogList.d.ts +27 -0
  2. package/dist/components/Audit/AuditLogList.js +272 -0
  3. package/dist/components/Audit/AuditLogList.js.map +1 -0
  4. package/dist/components/Audit/formatAuditCurl.d.ts +27 -0
  5. package/dist/components/Audit/formatAuditCurl.js +115 -0
  6. package/dist/components/Audit/formatAuditCurl.js.map +1 -0
  7. package/dist/components/Audit/formatAuditJson.d.ts +15 -0
  8. package/dist/components/Audit/formatAuditJson.js +135 -0
  9. package/dist/components/Audit/formatAuditJson.js.map +1 -0
  10. package/dist/components/Audit/index.d.ts +3 -0
  11. package/dist/components/Audit/style.module.scss.js +30 -0
  12. package/dist/components/Audit/style.module.scss.js.map +1 -0
  13. package/dist/components/Audit/types.d.ts +39 -0
  14. package/dist/components/Editor/RichTextEditor/RichTextEditor.d.ts +24 -0
  15. package/dist/components/Editor/RichTextEditor/RichTextEditor.js +93 -0
  16. package/dist/components/Editor/RichTextEditor/RichTextEditor.js.map +1 -0
  17. package/dist/components/Editor/RichTextEditor/index.d.ts +2 -0
  18. package/dist/components/Editor/RichTextEditor/style.module.scss.js +11 -0
  19. package/dist/components/Editor/RichTextEditor/style.module.scss.js.map +1 -0
  20. package/dist/components/Editor/VariablePicker.d.ts +19 -0
  21. package/dist/components/Editor/VariablePicker.js +55 -0
  22. package/dist/components/Editor/VariablePicker.js.map +1 -0
  23. package/dist/components/Editor/index.d.ts +7 -0
  24. package/dist/components/Editor/index.js +21 -0
  25. package/dist/components/Editor/index.js.map +1 -0
  26. package/dist/components/Editor/msgVarTokenPlugin.d.ts +13 -0
  27. package/dist/components/Editor/msgVarTokenPlugin.js +94 -0
  28. package/dist/components/Editor/msgVarTokenPlugin.js.map +1 -0
  29. package/dist/components/Editor/variableMention.d.ts +37 -0
  30. package/dist/components/Editor/variableMention.js +64 -0
  31. package/dist/components/Editor/variableMention.js.map +1 -0
  32. package/dist/components/FormInfo/RichTextField/index.d.ts +21 -0
  33. package/dist/components/FormInfo/RichTextField/index.js +82 -0
  34. package/dist/components/FormInfo/RichTextField/index.js.map +1 -0
  35. package/dist/components/FormInfo/RichTextField/style.module.scss.js +9 -0
  36. package/dist/components/FormInfo/RichTextField/style.module.scss.js.map +1 -0
  37. package/dist/components/FormInfo/VariableMentionInput/index.d.ts +17 -0
  38. package/dist/components/FormInfo/VariableMentionInput/index.js +73 -0
  39. package/dist/components/FormInfo/VariableMentionInput/index.js.map +1 -0
  40. package/dist/components/FormInfo/VariableMentionInput/style.module.scss.js +11 -0
  41. package/dist/components/FormInfo/VariableMentionInput/style.module.scss.js.map +1 -0
  42. package/dist/components/FormInfo/fields.d.ts +5 -0
  43. package/dist/components/FormInfo/fields.js +32 -23
  44. package/dist/components/FormInfo/fields.js.map +1 -1
  45. package/dist/components/FormInfo/index.d.ts +4 -0
  46. package/dist/components/StateBar/StateBar.d.ts +19 -6
  47. package/dist/components/StateBar/StateBar.js +87 -50
  48. package/dist/components/StateBar/StateBar.js.map +1 -1
  49. package/dist/components/StateBar/style.module.scss.js +13 -10
  50. package/dist/components/StateBar/style.module.scss.js.map +1 -1
  51. package/dist/components/Tools/Inbox/InboxBell/InboxBell.d.ts +45 -0
  52. package/dist/components/Tools/Inbox/InboxBell/InboxBell.js +156 -0
  53. package/dist/components/Tools/Inbox/InboxBell/InboxBell.js.map +1 -0
  54. package/dist/components/Tools/Inbox/InboxBell/index.d.ts +2 -0
  55. package/dist/components/Tools/Inbox/InboxBell/style.module.scss.js +30 -0
  56. package/dist/components/Tools/Inbox/InboxBell/style.module.scss.js.map +1 -0
  57. package/dist/components/Tools/Inbox/index.d.ts +2 -0
  58. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/List/columns.d.ts +8 -0
  59. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/List/columns.js +56 -0
  60. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/List/columns.js.map +1 -0
  61. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.d.ts +8 -0
  62. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.js +216 -0
  63. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.js.map +1 -0
  64. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.d.ts +26 -0
  65. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.js +190 -0
  66. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.js.map +1 -0
  67. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/index.d.ts +3 -0
  68. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/style.module.scss.js +12 -0
  69. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/style.module.scss.js.map +1 -0
  70. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/types.d.ts +76 -0
  71. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/types.js +26 -0
  72. package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/types.js.map +1 -0
  73. package/dist/components/Tools/MessageCenter/index.d.ts +3 -0
  74. package/dist/components/Tools/MessageCenter/utils/templateCode.d.ts +8 -0
  75. package/dist/components/Tools/MessageCenter/utils/templateCode.js +25 -0
  76. package/dist/components/Tools/MessageCenter/utils/templateCode.js.map +1 -0
  77. package/dist/components/Tools/index.d.ts +5 -0
  78. package/dist/components/index.d.ts +3 -0
  79. package/dist/editor.d.ts +5 -0
  80. package/dist/editor.js +21 -0
  81. package/dist/editor.js.map +1 -0
  82. package/dist/form-info.js +33 -29
  83. package/dist/form-info.js.map +1 -1
  84. package/dist/index.d.ts +5 -0
  85. package/dist/index.js +805 -773
  86. package/dist/index.js.map +1 -1
  87. package/dist/marsun-components-core.css +4 -1
  88. package/dist/node_modules/@ckeditor/ckeditor5-basic-styles/dist/index.js +301 -0
  89. package/dist/node_modules/@ckeditor/ckeditor5-basic-styles/dist/index.js.map +1 -0
  90. package/dist/node_modules/@ckeditor/ckeditor5-clipboard/dist/index.js +1256 -0
  91. package/dist/node_modules/@ckeditor/ckeditor5-clipboard/dist/index.js.map +1 -0
  92. package/dist/node_modules/@ckeditor/ckeditor5-core/dist/index.js +2107 -0
  93. package/dist/node_modules/@ckeditor/ckeditor5-core/dist/index.js.map +1 -0
  94. package/dist/node_modules/@ckeditor/ckeditor5-editor-classic/dist/index.js +259 -0
  95. package/dist/node_modules/@ckeditor/ckeditor5-editor-classic/dist/index.js.map +1 -0
  96. package/dist/node_modules/@ckeditor/ckeditor5-engine/dist/index.js +23990 -0
  97. package/dist/node_modules/@ckeditor/ckeditor5-engine/dist/index.js.map +1 -0
  98. package/dist/node_modules/@ckeditor/ckeditor5-enter/dist/index.js +249 -0
  99. package/dist/node_modules/@ckeditor/ckeditor5-enter/dist/index.js.map +1 -0
  100. package/dist/node_modules/@ckeditor/ckeditor5-essentials/dist/index.js +47 -0
  101. package/dist/node_modules/@ckeditor/ckeditor5-essentials/dist/index.js.map +1 -0
  102. package/dist/node_modules/@ckeditor/ckeditor5-font/dist/index.js +100 -0
  103. package/dist/node_modules/@ckeditor/ckeditor5-font/dist/index.js.map +1 -0
  104. package/dist/node_modules/@ckeditor/ckeditor5-icons/dist/index.js +31 -0
  105. package/dist/node_modules/@ckeditor/ckeditor5-icons/dist/index.js.map +1 -0
  106. package/dist/node_modules/@ckeditor/ckeditor5-integrations-common/dist/index.js +194 -0
  107. package/dist/node_modules/@ckeditor/ckeditor5-integrations-common/dist/index.js.map +1 -0
  108. package/dist/node_modules/@ckeditor/ckeditor5-list/dist/index.js +2042 -0
  109. package/dist/node_modules/@ckeditor/ckeditor5-list/dist/index.js.map +1 -0
  110. package/dist/node_modules/@ckeditor/ckeditor5-mention/dist/index.js +9 -0
  111. package/dist/node_modules/@ckeditor/ckeditor5-mention/dist/index.js.map +1 -0
  112. package/dist/node_modules/@ckeditor/ckeditor5-paragraph/dist/index.js +167 -0
  113. package/dist/node_modules/@ckeditor/ckeditor5-paragraph/dist/index.js.map +1 -0
  114. package/dist/node_modules/@ckeditor/ckeditor5-react/dist/index.js +471 -0
  115. package/dist/node_modules/@ckeditor/ckeditor5-react/dist/index.js.map +1 -0
  116. package/dist/node_modules/@ckeditor/ckeditor5-select-all/dist/index.js +139 -0
  117. package/dist/node_modules/@ckeditor/ckeditor5-select-all/dist/index.js.map +1 -0
  118. package/dist/node_modules/@ckeditor/ckeditor5-typing/dist/index.js +755 -0
  119. package/dist/node_modules/@ckeditor/ckeditor5-typing/dist/index.js.map +1 -0
  120. package/dist/node_modules/@ckeditor/ckeditor5-ui/dist/index.js +7838 -0
  121. package/dist/node_modules/@ckeditor/ckeditor5-ui/dist/index.js.map +1 -0
  122. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/conversions.js +422 -0
  123. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/conversions.js.map +1 -0
  124. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/index.js +33 -0
  125. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/index.js.map +1 -0
  126. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/route.js +47 -0
  127. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-convert/route.js.map +1 -0
  128. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-name/index.js +156 -0
  129. package/dist/node_modules/@ckeditor/ckeditor5-ui/node_modules/color-name/index.js.map +1 -0
  130. package/dist/node_modules/@ckeditor/ckeditor5-undo/dist/index.js +313 -0
  131. package/dist/node_modules/@ckeditor/ckeditor5-undo/dist/index.js.map +1 -0
  132. package/dist/node_modules/@ckeditor/ckeditor5-utils/dist/index.js +2942 -0
  133. package/dist/node_modules/@ckeditor/ckeditor5-utils/dist/index.js.map +1 -0
  134. package/dist/node_modules/@ckeditor/ckeditor5-watchdog/dist/index.js +892 -0
  135. package/dist/node_modules/@ckeditor/ckeditor5-watchdog/dist/index.js.map +1 -0
  136. package/dist/node_modules/@ckeditor/ckeditor5-widget/dist/index.js +1047 -0
  137. package/dist/node_modules/@ckeditor/ckeditor5-widget/dist/index.js.map +1 -0
  138. package/dist/node_modules/color-parse/node_modules/color-name/index.js +153 -0
  139. package/dist/node_modules/color-parse/node_modules/color-name/index.js.map +1 -0
  140. package/dist/node_modules/es-toolkit/dist/_internal/globalThis.js +7 -0
  141. package/dist/node_modules/es-toolkit/dist/_internal/globalThis.js.map +1 -0
  142. package/dist/node_modules/es-toolkit/dist/_internal/isUnsafeProperty.js +7 -0
  143. package/dist/node_modules/es-toolkit/dist/_internal/isUnsafeProperty.js.map +1 -0
  144. package/dist/node_modules/es-toolkit/dist/_internal/isUnsafeToWriteProperty.js +7 -0
  145. package/dist/node_modules/es-toolkit/dist/_internal/isUnsafeToWriteProperty.js.map +1 -0
  146. package/dist/node_modules/es-toolkit/dist/compat/_internal/assignValue.js +9 -0
  147. package/dist/node_modules/es-toolkit/dist/compat/_internal/assignValue.js.map +1 -0
  148. package/dist/node_modules/es-toolkit/dist/compat/_internal/getSymbols.js +7 -0
  149. package/dist/node_modules/es-toolkit/dist/compat/_internal/getSymbols.js.map +1 -0
  150. package/dist/node_modules/es-toolkit/dist/compat/_internal/getTag.js +7 -0
  151. package/dist/node_modules/es-toolkit/dist/compat/_internal/getTag.js.map +1 -0
  152. package/dist/node_modules/es-toolkit/dist/compat/_internal/isDeepKey.js +16 -0
  153. package/dist/node_modules/es-toolkit/dist/compat/_internal/isDeepKey.js.map +1 -0
  154. package/dist/node_modules/es-toolkit/dist/compat/_internal/isIndex.js +15 -0
  155. package/dist/node_modules/es-toolkit/dist/compat/_internal/isIndex.js.map +1 -0
  156. package/dist/node_modules/es-toolkit/dist/compat/_internal/isKey.js +9 -0
  157. package/dist/node_modules/es-toolkit/dist/compat/_internal/isKey.js.map +1 -0
  158. package/dist/node_modules/es-toolkit/dist/compat/_internal/isPrototype.js +8 -0
  159. package/dist/node_modules/es-toolkit/dist/compat/_internal/isPrototype.js.map +1 -0
  160. package/dist/node_modules/es-toolkit/dist/compat/_internal/tags.js +30 -0
  161. package/dist/node_modules/es-toolkit/dist/compat/_internal/tags.js.map +1 -0
  162. package/dist/node_modules/es-toolkit/dist/compat/_internal/toKey.js +8 -0
  163. package/dist/node_modules/es-toolkit/dist/compat/_internal/toKey.js.map +1 -0
  164. package/dist/node_modules/es-toolkit/dist/compat/function/debounce.js +17 -0
  165. package/dist/node_modules/es-toolkit/dist/compat/function/debounce.js.map +1 -0
  166. package/dist/node_modules/es-toolkit/dist/compat/function/throttle.js +13 -0
  167. package/dist/node_modules/es-toolkit/dist/compat/function/throttle.js.map +1 -0
  168. package/dist/node_modules/es-toolkit/dist/compat/object/assignIn.js +17 -0
  169. package/dist/node_modules/es-toolkit/dist/compat/object/assignIn.js.map +1 -0
  170. package/dist/node_modules/es-toolkit/dist/compat/object/clone.js +102 -0
  171. package/dist/node_modules/es-toolkit/dist/compat/object/clone.js.map +1 -0
  172. package/dist/node_modules/es-toolkit/dist/compat/object/cloneDeep.js +8 -0
  173. package/dist/node_modules/es-toolkit/dist/compat/object/cloneDeep.js.map +1 -0
  174. package/dist/node_modules/es-toolkit/dist/compat/object/cloneDeepWith.js +33 -0
  175. package/dist/node_modules/es-toolkit/dist/compat/object/cloneDeepWith.js.map +1 -0
  176. package/dist/node_modules/es-toolkit/dist/compat/object/get.js +39 -0
  177. package/dist/node_modules/es-toolkit/dist/compat/object/get.js.map +1 -0
  178. package/dist/node_modules/es-toolkit/dist/compat/object/has.js +21 -0
  179. package/dist/node_modules/es-toolkit/dist/compat/object/has.js.map +1 -0
  180. package/dist/node_modules/es-toolkit/dist/compat/object/keysIn.js +33 -0
  181. package/dist/node_modules/es-toolkit/dist/compat/object/keysIn.js.map +1 -0
  182. package/dist/node_modules/es-toolkit/dist/compat/object/mapValues.js +10 -0
  183. package/dist/node_modules/es-toolkit/dist/compat/object/mapValues.js.map +1 -0
  184. package/dist/node_modules/es-toolkit/dist/compat/object/merge.js +9 -0
  185. package/dist/node_modules/es-toolkit/dist/compat/object/merge.js.map +1 -0
  186. package/dist/node_modules/es-toolkit/dist/compat/object/mergeWith.js +53 -0
  187. package/dist/node_modules/es-toolkit/dist/compat/object/mergeWith.js.map +1 -0
  188. package/dist/node_modules/es-toolkit/dist/compat/object/property.js +10 -0
  189. package/dist/node_modules/es-toolkit/dist/compat/object/property.js.map +1 -0
  190. package/dist/node_modules/es-toolkit/dist/compat/object/set.js +9 -0
  191. package/dist/node_modules/es-toolkit/dist/compat/object/set.js.map +1 -0
  192. package/dist/node_modules/es-toolkit/dist/compat/object/updateWith.js +31 -0
  193. package/dist/node_modules/es-toolkit/dist/compat/object/updateWith.js.map +1 -0
  194. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArguments.js +8 -0
  195. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArguments.js.map +1 -0
  196. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArray.js +7 -0
  197. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArray.js.map +1 -0
  198. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArrayLike.js +8 -0
  199. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArrayLike.js.map +1 -0
  200. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArrayLikeObject.js +9 -0
  201. package/dist/node_modules/es-toolkit/dist/compat/predicate/isArrayLikeObject.js.map +1 -0
  202. package/dist/node_modules/es-toolkit/dist/compat/predicate/isElement.js +9 -0
  203. package/dist/node_modules/es-toolkit/dist/compat/predicate/isElement.js.map +1 -0
  204. package/dist/node_modules/es-toolkit/dist/compat/predicate/isEqualWith.js +15 -0
  205. package/dist/node_modules/es-toolkit/dist/compat/predicate/isEqualWith.js.map +1 -0
  206. package/dist/node_modules/es-toolkit/dist/compat/predicate/isFunction.js +7 -0
  207. package/dist/node_modules/es-toolkit/dist/compat/predicate/isFunction.js.map +1 -0
  208. package/dist/node_modules/es-toolkit/dist/compat/predicate/isMatch.js +9 -0
  209. package/dist/node_modules/es-toolkit/dist/compat/predicate/isMatch.js.map +1 -0
  210. package/dist/node_modules/es-toolkit/dist/compat/predicate/isMatchWith.js +81 -0
  211. package/dist/node_modules/es-toolkit/dist/compat/predicate/isMatchWith.js.map +1 -0
  212. package/dist/node_modules/es-toolkit/dist/compat/predicate/isObject.js +7 -0
  213. package/dist/node_modules/es-toolkit/dist/compat/predicate/isObject.js.map +1 -0
  214. package/dist/node_modules/es-toolkit/dist/compat/predicate/isObjectLike.js +7 -0
  215. package/dist/node_modules/es-toolkit/dist/compat/predicate/isObjectLike.js.map +1 -0
  216. package/dist/node_modules/es-toolkit/dist/compat/predicate/isPlainObject.js +16 -0
  217. package/dist/node_modules/es-toolkit/dist/compat/predicate/isPlainObject.js.map +1 -0
  218. package/dist/node_modules/es-toolkit/dist/compat/predicate/isString.js +7 -0
  219. package/dist/node_modules/es-toolkit/dist/compat/predicate/isString.js.map +1 -0
  220. package/dist/node_modules/es-toolkit/dist/compat/predicate/isSymbol.js +7 -0
  221. package/dist/node_modules/es-toolkit/dist/compat/predicate/isSymbol.js.map +1 -0
  222. package/dist/node_modules/es-toolkit/dist/compat/predicate/isTypedArray.js +8 -0
  223. package/dist/node_modules/es-toolkit/dist/compat/predicate/isTypedArray.js.map +1 -0
  224. package/dist/node_modules/es-toolkit/dist/compat/predicate/matches.js +9 -0
  225. package/dist/node_modules/es-toolkit/dist/compat/predicate/matches.js.map +1 -0
  226. package/dist/node_modules/es-toolkit/dist/compat/predicate/matchesProperty.js +23 -0
  227. package/dist/node_modules/es-toolkit/dist/compat/predicate/matchesProperty.js.map +1 -0
  228. package/dist/node_modules/es-toolkit/dist/compat/util/eq.js +7 -0
  229. package/dist/node_modules/es-toolkit/dist/compat/util/eq.js.map +1 -0
  230. package/dist/node_modules/es-toolkit/dist/compat/util/iteratee.js +19 -0
  231. package/dist/node_modules/es-toolkit/dist/compat/util/iteratee.js.map +1 -0
  232. package/dist/node_modules/es-toolkit/dist/compat/util/times.js +11 -0
  233. package/dist/node_modules/es-toolkit/dist/compat/util/times.js.map +1 -0
  234. package/dist/node_modules/es-toolkit/dist/compat/util/toFinite.js +8 -0
  235. package/dist/node_modules/es-toolkit/dist/compat/util/toFinite.js.map +1 -0
  236. package/dist/node_modules/es-toolkit/dist/compat/util/toInteger.js +9 -0
  237. package/dist/node_modules/es-toolkit/dist/compat/util/toInteger.js.map +1 -0
  238. package/dist/node_modules/es-toolkit/dist/compat/util/toNumber.js +8 -0
  239. package/dist/node_modules/es-toolkit/dist/compat/util/toNumber.js.map +1 -0
  240. package/dist/node_modules/es-toolkit/dist/compat/util/toPath.js +37 -0
  241. package/dist/node_modules/es-toolkit/dist/compat/util/toPath.js.map +1 -0
  242. package/dist/node_modules/es-toolkit/dist/compat/util/toString.js +15 -0
  243. package/dist/node_modules/es-toolkit/dist/compat/util/toString.js.map +1 -0
  244. package/dist/node_modules/es-toolkit/dist/function/after.js +11 -0
  245. package/dist/node_modules/es-toolkit/dist/function/after.js.map +1 -0
  246. package/dist/node_modules/es-toolkit/dist/function/debounce.js +30 -0
  247. package/dist/node_modules/es-toolkit/dist/function/debounce.js.map +1 -0
  248. package/dist/node_modules/es-toolkit/dist/function/identity.js +7 -0
  249. package/dist/node_modules/es-toolkit/dist/function/identity.js.map +1 -0
  250. package/dist/node_modules/es-toolkit/dist/function/noop.js +6 -0
  251. package/dist/node_modules/es-toolkit/dist/function/noop.js.map +1 -0
  252. package/dist/node_modules/es-toolkit/dist/object/clone.js +27 -0
  253. package/dist/node_modules/es-toolkit/dist/object/clone.js.map +1 -0
  254. package/dist/node_modules/es-toolkit/dist/object/cloneDeep.js +8 -0
  255. package/dist/node_modules/es-toolkit/dist/object/cloneDeep.js.map +1 -0
  256. package/dist/node_modules/es-toolkit/dist/object/cloneDeepWith.js +121 -0
  257. package/dist/node_modules/es-toolkit/dist/object/cloneDeepWith.js.map +1 -0
  258. package/dist/node_modules/es-toolkit/dist/object/mapValues.js +12 -0
  259. package/dist/node_modules/es-toolkit/dist/object/mapValues.js.map +1 -0
  260. package/dist/node_modules/es-toolkit/dist/predicate/isBuffer.js +8 -0
  261. package/dist/node_modules/es-toolkit/dist/predicate/isBuffer.js.map +1 -0
  262. package/dist/node_modules/es-toolkit/dist/predicate/isEqual.js +9 -0
  263. package/dist/node_modules/es-toolkit/dist/predicate/isEqual.js.map +1 -0
  264. package/dist/node_modules/es-toolkit/dist/predicate/isEqualWith.js +110 -0
  265. package/dist/node_modules/es-toolkit/dist/predicate/isEqualWith.js.map +1 -0
  266. package/dist/node_modules/es-toolkit/dist/predicate/isLength.js +7 -0
  267. package/dist/node_modules/es-toolkit/dist/predicate/isLength.js.map +1 -0
  268. package/dist/node_modules/es-toolkit/dist/predicate/isPlainObject.js +9 -0
  269. package/dist/node_modules/es-toolkit/dist/predicate/isPlainObject.js.map +1 -0
  270. package/dist/node_modules/es-toolkit/dist/predicate/isPrimitive.js +7 -0
  271. package/dist/node_modules/es-toolkit/dist/predicate/isPrimitive.js.map +1 -0
  272. package/dist/node_modules/es-toolkit/dist/predicate/isTypedArray.js +7 -0
  273. package/dist/node_modules/es-toolkit/dist/predicate/isTypedArray.js.map +1 -0
  274. package/dist/styles/global.css +4 -1
  275. package/dist/utils/copyText.d.ts +4 -0
  276. package/dist/utils/copyText.js +21 -0
  277. package/dist/utils/copyText.js.map +1 -0
  278. package/package.json +9 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../../node_modules/@ckeditor/ckeditor5-list/dist/index.js"],"sourcesContent":["/**\n * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n */\nimport { Command, Plugin } from \"@ckeditor/ckeditor5-core\";\nimport { Delete } from \"@ckeditor/ckeditor5-typing\";\nimport { Enter } from \"@ckeditor/ckeditor5-enter\";\nimport { CKEditorError, FocusTracker, KeystrokeHandler, createElement, env, first, getCode, getLocalizedArrowKeyCodeDirection, global, parseKeystroke, toArray, uid } from \"@ckeditor/ckeditor5-utils\";\nimport { _normalizeFontSizeOptions } from \"@ckeditor/ckeditor5-font\";\nimport { ClipboardPipeline } from \"@ckeditor/ckeditor5-clipboard\";\nimport { ButtonView, CollapsibleView, FocusCycler, LabeledFieldView, MenuBarMenuListItemButtonView, MenuBarMenuView, SplitButtonView, SwitchButtonView, View, ViewCollection, addKeyboardHandlingForGrid, createDropdown, createLabeledInputNumber, focusChildOnDropdownOpen } from \"@ckeditor/ckeditor5-ui\";\nimport { IconBulletedList, IconListStyleArabicIndic, IconListStyleCircle, IconListStyleDecimal, IconListStyleDecimalLeadingZero, IconListStyleDisc, IconListStyleLowerLatin, IconListStyleLowerRoman, IconListStyleSquare, IconListStyleUpperLatin, IconListStyleUpperRoman, IconNumberedList, IconTodoList } from \"@ckeditor/ckeditor5-icons\";\nimport { pick } from \"es-toolkit/compat\";\nimport { DomEventObserver, Matcher, ModelTreeWalker, getViewFillerOffset } from \"@ckeditor/ckeditor5-engine\";\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/list/utils/listwalker\n*/\n/**\n* Document list blocks iterator.\n*\n* @internal\n*/\nvar ListWalker = class {\n\t/**\n\t* The start list item block element.\n\t*/\n\t_startElement;\n\t/**\n\t* The reference indent. Initialized by the indent of the start block.\n\t*/\n\t_referenceIndent;\n\t/**\n\t* The iterating direction.\n\t*/\n\t_isForward;\n\t/**\n\t* Whether start block should be included in the result (if it's matching other criteria).\n\t*/\n\t_includeSelf;\n\t/**\n\t* Additional attributes that must be the same for each block.\n\t*/\n\t_sameAttributes;\n\t/**\n\t* Whether blocks with the same indent level as the start block should be included in the result.\n\t*/\n\t_sameIndent;\n\t/**\n\t* Whether blocks with a lower indent level than the start block should be included in the result.\n\t*/\n\t_lowerIndent;\n\t/**\n\t* Whether blocks with a higher indent level than the start block should be included in the result.\n\t*/\n\t_higherIndent;\n\t/**\n\t* Creates a document list iterator.\n\t*\n\t* @param startElement The start list item block element.\n\t* @param options.direction The iterating direction.\n\t* @param options.includeSelf Whether start block should be included in the result (if it's matching other criteria).\n\t* @param options.sameAttributes Additional attributes that must be the same for each block.\n\t* @param options.sameIndent Whether blocks with the same indent level as the start block should be included\n\t* in the result.\n\t* @param options.lowerIndent Whether blocks with a lower indent level than the start block should be included\n\t* in the result.\n\t* @param options.higherIndent Whether blocks with a higher indent level than the start block should be included\n\t* in the result.\n\t*/\n\tconstructor(startElement, options) {\n\t\tthis._startElement = startElement;\n\t\tthis._referenceIndent = startElement.getAttribute(\"listIndent\");\n\t\tthis._isForward = options.direction == \"forward\";\n\t\tthis._includeSelf = !!options.includeSelf;\n\t\tthis._sameAttributes = toArray(options.sameAttributes || []);\n\t\tthis._sameIndent = !!options.sameIndent;\n\t\tthis._lowerIndent = !!options.lowerIndent;\n\t\tthis._higherIndent = !!options.higherIndent;\n\t}\n\t/**\n\t* Performs only first step of iteration and returns the result.\n\t*\n\t* @param startElement The start list item block element.\n\t* @param options.direction The iterating direction.\n\t* @param options.includeSelf Whether start block should be included in the result (if it's matching other criteria).\n\t* @param options.sameAttributes Additional attributes that must be the same for each block.\n\t* @param options.sameIndent Whether blocks with the same indent level as the start block should be included\n\t* in the result.\n\t* @param options.lowerIndent Whether blocks with a lower indent level than the start block should be included\n\t* in the result.\n\t* @param options.higherIndent Whether blocks with a higher indent level than the start block should be included\n\t* in the result.\n\t*/\n\tstatic first(startElement, options) {\n\t\tconst iterator = new this(startElement, options)[Symbol.iterator]();\n\t\treturn first(iterator);\n\t}\n\t/**\n\t* Iterable interface.\n\t*/\n\t*[Symbol.iterator]() {\n\t\tconst nestedItems = [];\n\t\tfor (const { node } of new SiblingListBlocksIterator(this._getStartNode(), this._isForward ? \"forward\" : \"backward\")) {\n\t\t\tconst indent = node.getAttribute(\"listIndent\");\n\t\t\tif (indent < this._referenceIndent) {\n\t\t\t\tif (!this._lowerIndent) break;\n\t\t\t\tthis._referenceIndent = indent;\n\t\t\t} else if (indent > this._referenceIndent) {\n\t\t\t\tif (!this._higherIndent) continue;\n\t\t\t\tif (!this._isForward) {\n\t\t\t\t\tnestedItems.push(node);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (!this._sameIndent) {\n\t\t\t\t\tif (this._higherIndent) {\n\t\t\t\t\t\tif (nestedItems.length) {\n\t\t\t\t\t\t\tyield* nestedItems;\n\t\t\t\t\t\t\tnestedItems.length = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (this._sameAttributes.some((attr) => node.getAttribute(attr) !== this._startElement.getAttribute(attr))) break;\n\t\t\t}\n\t\t\tif (nestedItems.length) {\n\t\t\t\tyield* nestedItems;\n\t\t\t\tnestedItems.length = 0;\n\t\t\t}\n\t\t\tyield node;\n\t\t}\n\t}\n\t/**\n\t* Returns the model element to start iterating.\n\t*/\n\t_getStartNode() {\n\t\tif (this._includeSelf) return this._startElement;\n\t\treturn this._isForward ? this._startElement.nextSibling : this._startElement.previousSibling;\n\t}\n};\n/**\n* Iterates sibling list blocks starting from the given node.\n*\n* @internal\n*/\nvar SiblingListBlocksIterator = class {\n\t_node;\n\t_isForward;\n\t_previousNodesByIndent = [];\n\t_previous = null;\n\t_previousNodeIndent = null;\n\t/**\n\t* @param node The model node.\n\t* @param direction Iteration direction.\n\t*/\n\tconstructor(node, direction = \"forward\") {\n\t\tthis._node = node;\n\t\tthis._isForward = direction === \"forward\";\n\t}\n\t[Symbol.iterator]() {\n\t\treturn this;\n\t}\n\tnext() {\n\t\tif (!isListItemBlock(this._node)) return {\n\t\t\tdone: true,\n\t\t\tvalue: void 0\n\t\t};\n\t\tconst nodeIndent = this._node.getAttribute(\"listIndent\");\n\t\tlet previousNodeInList = null;\n\t\tif (this._previous) {\n\t\t\tconst previousNodeIndent = this._previousNodeIndent;\n\t\t\tif (nodeIndent > previousNodeIndent) this._previousNodesByIndent[previousNodeIndent] = this._previous;\n\t\t\telse if (nodeIndent < previousNodeIndent) {\n\t\t\t\tpreviousNodeInList = this._previousNodesByIndent[nodeIndent] || null;\n\t\t\t\tthis._previousNodesByIndent.length = nodeIndent;\n\t\t\t} else previousNodeInList = this._previous;\n\t\t}\n\t\tconst value = {\n\t\t\tnode: this._node,\n\t\t\tprevious: this._previous,\n\t\t\tpreviousNodeInList\n\t\t};\n\t\tthis._previous = this._node;\n\t\tthis._previousNodeIndent = nodeIndent;\n\t\tthis._node = this._isForward ? this._node.nextSibling : this._node.previousSibling;\n\t\treturn {\n\t\t\tvalue,\n\t\t\tdone: false\n\t\t};\n\t}\n};\n/**\n* The iterable protocol over the list elements.\n*\n* @internal\n*/\nvar ListBlocksIterable = class {\n\t_listHead;\n\t/**\n\t* @param listHead The head element of a list.\n\t*/\n\tconstructor(listHead) {\n\t\tthis._listHead = listHead;\n\t}\n\t/**\n\t* List blocks iterator.\n\t*\n\t* Iterates over all blocks of a list.\n\t*/\n\t[Symbol.iterator]() {\n\t\treturn new SiblingListBlocksIterator(this._listHead);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* The list item ID generator.\n*\n* @internal\n*/\nvar ListItemUid = class {\n\t/**\n\t* Returns the next ID.\n\t*\n\t* @internal\n\t*/\n\t/* istanbul ignore next: static function definition -- @preserve */\n\tstatic next() {\n\t\treturn uid();\n\t}\n};\n/**\n* Returns true if the given model node is a list item block.\n*\n* @internal\n*/\nfunction isListItemBlock(node) {\n\treturn !!node && node.is(\"element\") && node.hasAttribute(\"listItemId\");\n}\n/**\n* Returns an array with all elements that represents the same list item.\n*\n* It means that values for `listIndent`, and `listItemId` for all items are equal.\n*\n* @internal\n* @param listItem Starting list item element.\n* @param options.higherIndent Whether blocks with a higher indent level than the start block should be included\n* in the result.\n*/\nfunction getAllListItemBlocks(listItem, options = {}) {\n\treturn [...getListItemBlocks(listItem, {\n\t\t...options,\n\t\tdirection: \"backward\"\n\t}), ...getListItemBlocks(listItem, {\n\t\t...options,\n\t\tdirection: \"forward\"\n\t})];\n}\n/**\n* Returns an array with elements that represents the same list item in the specified direction.\n*\n* It means that values for `listIndent` and `listItemId` for all items are equal.\n*\n* **Note**: For backward search the provided item is not included, but for forward search it is included in the result.\n*\n* @internal\n* @param listItem Starting list item element.\n* @param options.direction Walking direction.\n* @param options.higherIndent Whether blocks with a higher indent level than the start block should be included in the result.\n*/\nfunction getListItemBlocks(listItem, options = {}) {\n\tconst isForward = options.direction == \"forward\";\n\tconst items = Array.from(new ListWalker(listItem, {\n\t\t...options,\n\t\tincludeSelf: isForward,\n\t\tsameIndent: true,\n\t\tsameAttributes: \"listItemId\"\n\t}));\n\treturn isForward ? items : items.reverse();\n}\n/**\n* Returns a list items nested inside the given list item.\n*\n* @internal\n*/\nfunction getNestedListBlocks(listItem) {\n\treturn Array.from(new ListWalker(listItem, {\n\t\tdirection: \"forward\",\n\t\thigherIndent: true\n\t}));\n}\n/**\n* Returns array of all blocks/items of the same list as given block (same indent, same type and properties).\n*\n* @internal\n* @param listItem Starting list item element.\n* @param options Additional list walker options to modify the range of returned list items.\n*/\nfunction getListItems(listItem, options) {\n\tconst backwardBlocks = new ListWalker(listItem, {\n\t\tsameIndent: true,\n\t\tsameAttributes: \"listType\",\n\t\t...options\n\t});\n\tconst forwardBlocks = new ListWalker(listItem, {\n\t\tsameIndent: true,\n\t\tsameAttributes: \"listType\",\n\t\tincludeSelf: true,\n\t\tdirection: \"forward\",\n\t\t...options\n\t});\n\treturn [...Array.from(backwardBlocks).reverse(), ...forwardBlocks];\n}\n/**\n* Check if the given block is the first in the list item.\n*\n* @internal\n* @param listBlock The list block element.\n*/\nfunction isFirstBlockOfListItem(listBlock) {\n\tif (!ListWalker.first(listBlock, {\n\t\tsameIndent: true,\n\t\tsameAttributes: \"listItemId\"\n\t})) return true;\n\treturn false;\n}\n/**\n* Check if the given block is the last in the list item.\n*\n* @internal\n*/\nfunction isLastBlockOfListItem(listBlock) {\n\tif (!ListWalker.first(listBlock, {\n\t\tdirection: \"forward\",\n\t\tsameIndent: true,\n\t\tsameAttributes: \"listItemId\"\n\t})) return true;\n\treturn false;\n}\n/**\n* Expands the given list of selected blocks to include the leading and tailing blocks of partially selected list items.\n*\n* @internal\n* @param blocks The list of selected blocks.\n* @param options.withNested Whether should include nested list items.\n*/\nfunction expandListBlocksToCompleteItems(blocks, options = {}) {\n\tblocks = toArray(blocks);\n\tconst higherIndent = options.withNested !== false;\n\tconst allBlocks = /* @__PURE__ */ new Set();\n\tfor (const block of blocks) for (const itemBlock of getAllListItemBlocks(block, { higherIndent })) allBlocks.add(itemBlock);\n\treturn sortBlocks(allBlocks);\n}\n/**\n* Expands the given list of selected blocks to include all the items of the lists they're in.\n*\n* @internal\n* @param blocks The list of selected blocks.\n*/\nfunction expandListBlocksToCompleteList(blocks) {\n\tblocks = toArray(blocks);\n\tconst allBlocks = /* @__PURE__ */ new Set();\n\tfor (const block of blocks) for (const itemBlock of getListItems(block)) allBlocks.add(itemBlock);\n\treturn sortBlocks(allBlocks);\n}\n/**\n* Splits the list item just before the provided list block.\n*\n* @internal\n* @param listBlock The list block element.\n* @param writer The model writer.\n* @returns The array of updated blocks.\n*/\nfunction splitListItemBefore(listBlock, writer) {\n\tconst blocks = getListItemBlocks(listBlock, { direction: \"forward\" });\n\tconst id = ListItemUid.next();\n\tfor (const block of blocks) writer.setAttribute(\"listItemId\", id, block);\n\treturn blocks;\n}\n/**\n* Merges the list item with the parent list item.\n*\n* @internal\n* @param listBlock The list block element.\n* @param parentBlock The list block element to merge with.\n* @param writer The model writer.\n* @returns The array of updated blocks.\n*/\nfunction mergeListItemBefore(listBlock, parentBlock, writer) {\n\tconst attributes = {};\n\tfor (const [key, value] of parentBlock.getAttributes()) if (key.startsWith(\"list\")) attributes[key] = value;\n\tconst blocks = getListItemBlocks(listBlock, { direction: \"forward\" });\n\tfor (const block of blocks) writer.setAttributes(attributes, block);\n\treturn blocks;\n}\n/**\n* Increases indentation of given list blocks.\n*\n* @internal\n* @param blocks The block or iterable of blocks.\n* @param writer The model writer.\n* @param options Additional options.\n* @param options.expand Whether should expand the list of blocks to include complete list items.\n* @param options.indentBy The number of levels the indentation should change (could be negative).\n* @param options.attributeNames List of attribute names to remove when a block leaves the list (when blockIndent < 0).\n*/\nfunction indentBlocks(blocks, writer, { expand, indentBy = 1, attributeNames }) {\n\tblocks = toArray(blocks);\n\tconst allBlocks = expand ? expandListBlocksToCompleteItems(blocks) : blocks;\n\tfor (const block of allBlocks) {\n\t\tconst blockIndent = block.getAttribute(\"listIndent\") + indentBy;\n\t\tif (blockIndent < 0) removeListAttributes(block, writer, attributeNames);\n\t\telse writer.setAttribute(\"listIndent\", blockIndent, block);\n\t}\n\treturn allBlocks;\n}\n/**\n* Decreases indentation of given list of blocks. If the indentation of some blocks matches the indentation\n* of surrounding blocks, they get merged together.\n*\n* @internal\n* @param blocks The block or iterable of blocks.\n* @param writer The model writer.\n* @param options Additional options.\n* @param options.attributeNames List of attribute names to remove when a block leaves the list (when blockIndent < 0).\n*/\nfunction outdentBlocksWithMerge(blocks, writer, { attributeNames }) {\n\tblocks = toArray(blocks);\n\tconst allBlocks = expandListBlocksToCompleteItems(blocks);\n\tconst visited = /* @__PURE__ */ new Set();\n\tconst referenceIndent = Math.min(...allBlocks.map((block) => block.getAttribute(\"listIndent\")));\n\tconst parentBlocks = /* @__PURE__ */ new Map();\n\tfor (const block of allBlocks) parentBlocks.set(block, ListWalker.first(block, { lowerIndent: true }));\n\tfor (const block of allBlocks) {\n\t\tif (visited.has(block)) continue;\n\t\tvisited.add(block);\n\t\tconst blockIndent = block.getAttribute(\"listIndent\") - 1;\n\t\tif (blockIndent < 0) {\n\t\t\tremoveListAttributes(block, writer, attributeNames);\n\t\t\tcontinue;\n\t\t}\n\t\tif (block.getAttribute(\"listIndent\") == referenceIndent && parentBlocks.get(block)) {\n\t\t\tconst mergedBlocks = mergeListItemIfNotLast(block, parentBlocks.get(block), writer);\n\t\t\tfor (const mergedBlock of mergedBlocks) visited.add(mergedBlock);\n\t\t\tif (mergedBlocks.length) continue;\n\t\t}\n\t\twriter.setAttribute(\"listIndent\", blockIndent, block);\n\t}\n\treturn sortBlocks(visited);\n}\n/**\n* Removes all list attributes from the given blocks.\n*\n* @internal\n* @param blocks The block or iterable of blocks.\n* @param writer The model writer.\n* @param attributeNames List of attribute names to remove.\n* @returns Array of altered blocks.\n*/\nfunction removeListAttributes(blocks, writer, attributeNames) {\n\tblocks = toArray(blocks);\n\tfor (const block of blocks) if (block.is(\"element\", \"listItem\")) writer.rename(block, \"paragraph\");\n\tfor (const block of blocks) for (const attributeKey of block.getAttributeKeys()) if (attributeNames.includes(attributeKey)) writer.removeAttribute(attributeKey, block);\n\treturn blocks;\n}\n/**\n* Checks whether the given blocks are related to a single list item.\n*\n* @internal\n* @param blocks The list block elements.\n*/\nfunction isSingleListItem(blocks) {\n\tif (!blocks.length) return false;\n\tconst firstItemId = blocks[0].getAttribute(\"listItemId\");\n\tif (!firstItemId) return false;\n\treturn !blocks.some((item) => item.getAttribute(\"listItemId\") != firstItemId);\n}\n/**\n* Modifies the indents of list blocks following the given list block so the indentation is valid after\n* the given block is no longer a list item.\n*\n* @internal\n* @param lastBlock The last list block that has become a non-list element.\n* @param writer The model writer.\n* @returns Array of altered blocks.\n*/\nfunction outdentFollowingItems(lastBlock, writer) {\n\tconst changedBlocks = [];\n\tlet currentIndent = Number.POSITIVE_INFINITY;\n\tfor (const { node } of new SiblingListBlocksIterator(lastBlock.nextSibling)) {\n\t\tconst indent = node.getAttribute(\"listIndent\");\n\t\tif (indent == 0) break;\n\t\tif (indent < currentIndent) currentIndent = indent;\n\t\tconst newIndent = indent - currentIndent;\n\t\twriter.setAttribute(\"listIndent\", newIndent, node);\n\t\tchangedBlocks.push(node);\n\t}\n\treturn changedBlocks;\n}\n/**\n* Returns the array of given blocks sorted by model indexes (document order).\n*\n* @internal\n*/\nfunction sortBlocks(blocks) {\n\treturn Array.from(blocks).filter((block) => block.root.rootName !== \"$graveyard\").sort((a, b) => a.index - b.index);\n}\n/**\n* Returns a selected block object. If a selected object is inline or when there is no selected\n* object, `null` is returned.\n*\n* @internal\n* @param model The instance of editor model.\n* @returns Selected block object or `null`.\n*/\nfunction getSelectedBlockObject(model) {\n\tconst selectedElement = model.document.selection.getSelectedElement();\n\tif (!selectedElement) return null;\n\tif (model.schema.isObject(selectedElement) && model.schema.isBlock(selectedElement)) return selectedElement;\n\treturn null;\n}\n/**\n* Checks whether the given block can be replaced by a listItem.\n*\n* Note that this is possible only when multiBlock = false option is set in feature config.\n*\n* @param block A block to be tested.\n* @param schema The schema of the document.\n* @internal\n*/\nfunction canBecomeSimpleListItem(block, schema) {\n\treturn schema.checkChild(block.parent, \"listItem\") && schema.checkChild(block, \"$text\") && !schema.isObject(block);\n}\n/**\n* Returns true if listType is of type `numbered` or `customNumbered`.\n*\n* @internal\n*/\nfunction isNumberedListType(listType) {\n\treturn listType == \"numbered\" || listType == \"customNumbered\";\n}\n/**\n* Checks if the given list item block is the first block of the first item in its list at the given indent.\n*\n* Walks back over previous siblings and returns:\n* - `true` if it reaches a non-list block or a list block at a lower indent (a new list begins here),\n* - `false` if it finds a same-indent block of the same `listItemId` (a continuation of the current item) or of the same\n* `listType` (the visible list already has earlier items),\n* - `true` if it finds a same-indent block of a different `listType` and a different `listItemId` (a different list ends; ours\n* starts here),\n* - `false` if the loop ends (it reaches the first non-list-item block, or no more previous siblings) while passing only\n* higher-indent blocks (those blocks live inside an intermediate skip-level `<li style=\"list-style-type:none\">` wrapper\n* at our indent).\n*\n* For example, in the model:\n*\n* ```\n* ' # aaa'\n* '# bbb'\n* ```\n*\n* `bbb` is preceded by a higher-indent block `aaa`, which in the view is rendered inside an intermediate\n* skip-level wrapper at indent 0:\n*\n* ```html\n* <ol>\n* <li style=\"list-style-type:none\">\n* <ol>\n* <li>aaa</li>\n* </ol>\n* </li>\n* <li>bbb</li>\n* </ol>\n* ```\n*\n* So `bbb` is the second visible item in the outer list and the function returns `false`.\n*/\nfunction isFirstListItemInList(listItem) {\n\tconst itemIndent = listItem.getAttribute(\"listIndent\");\n\tconst itemListType = listItem.getAttribute(\"listType\");\n\tconst itemListItemId = listItem.getAttribute(\"listItemId\");\n\tlet previous = listItem.previousSibling;\n\tlet sawHigherIndent = false;\n\twhile (isListItemBlock(previous)) {\n\t\tconst previousIndent = previous.getAttribute(\"listIndent\");\n\t\tif (previousIndent < itemIndent) return true;\n\t\tif (previousIndent === itemIndent) {\n\t\t\tif (previous.getAttribute(\"listItemId\") === itemListItemId) return false;\n\t\t\treturn previous.getAttribute(\"listType\") !== itemListType;\n\t\t}\n\t\tsawHigherIndent = true;\n\t\tprevious = previous.previousSibling;\n\t}\n\treturn !sawHigherIndent;\n}\n/**\n* Merges a given block to the given parent block if parent is a list item and there is no more blocks in the same item.\n*/\nfunction mergeListItemIfNotLast(block, parentBlock, writer) {\n\tif (getListItemBlocks(parentBlock, { direction: \"forward\" }).pop().index > block.index) return mergeListItemBefore(block, parentBlock, writer);\n\treturn [];\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/list/listindentcommand\n*/\n/**\n* The document list indent command. It is used by the {@link module:list/list~List list feature}.\n*/\nvar ListIndentCommand = class extends Command {\n\t/**\n\t* Determines by how much the command will change the list item's indent attribute.\n\t*/\n\t_direction;\n\t/**\n\t* Creates an instance of the command.\n\t*\n\t* @param editor The editor instance.\n\t* @param indentDirection The direction of indent. If it is equal to `backward`, the command\n\t* will outdent a list item.\n\t*/\n\tconstructor(editor, indentDirection) {\n\t\tsuper(editor);\n\t\tthis._direction = indentDirection;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\t/**\n\t* Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t*\n\t* @fires execute\n\t* @fires afterExecute\n\t*/\n\texecute() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst blocks = getSelectedListBlocks(model.document.selection);\n\t\tconst attributeNames = editor.plugins.get(\"ListEditing\").getListAttributeNames();\n\t\tmodel.change((writer) => {\n\t\t\tconst changedBlocks = [];\n\t\t\tif (isSingleListItem(blocks) && !isFirstBlockOfListItem(blocks[0])) {\n\t\t\t\tif (this._direction == \"forward\") changedBlocks.push(...indentBlocks(blocks, writer, { attributeNames }));\n\t\t\t\tchangedBlocks.push(...splitListItemBefore(blocks[0], writer));\n\t\t\t} else if (this._direction == \"forward\") changedBlocks.push(...indentBlocks(blocks, writer, {\n\t\t\t\texpand: true,\n\t\t\t\tattributeNames\n\t\t\t}));\n\t\t\telse changedBlocks.push(...outdentBlocksWithMerge(blocks, writer, { attributeNames }));\n\t\t\tfor (const block of changedBlocks) {\n\t\t\t\tif (!block.hasAttribute(\"listType\")) continue;\n\t\t\t\tconst previousItemBlock = ListWalker.first(block, { sameIndent: true });\n\t\t\t\tif (previousItemBlock) writer.setAttribute(\"listType\", previousItemBlock.getAttribute(\"listType\"), block);\n\t\t\t}\n\t\t\tthis._fireAfterExecute(changedBlocks);\n\t\t});\n\t}\n\t/**\n\t* Fires the `afterExecute` event.\n\t*\n\t* @param changedBlocks The changed list elements.\n\t*/\n\t_fireAfterExecute(changedBlocks) {\n\t\tthis.fire(\"afterExecute\", sortBlocks(new Set(changedBlocks)));\n\t}\n\t/**\n\t* Checks whether the command can be enabled in the current context.\n\t*\n\t* @returns Whether the command should be enabled.\n\t*/\n\t_checkEnabled() {\n\t\tlet blocks = getSelectedListBlocks(this.editor.model.document.selection);\n\t\tlet firstBlock = blocks[0];\n\t\tif (!firstBlock) return false;\n\t\tif (this._direction == \"backward\") return true;\n\t\tif (isSingleListItem(blocks) && !isFirstBlockOfListItem(blocks[0])) return true;\n\t\tif (this.editor.config.get(\"list.enableSkipLevelLists\")) return true;\n\t\tblocks = expandListBlocksToCompleteItems(blocks);\n\t\tfirstBlock = blocks[0];\n\t\tconst siblingItem = ListWalker.first(firstBlock, { sameIndent: true });\n\t\tif (!siblingItem) return false;\n\t\tif (siblingItem.getAttribute(\"listType\") == firstBlock.getAttribute(\"listType\")) return true;\n\t\treturn false;\n\t}\n};\n/**\n* Returns an array of selected blocks truncated to the first non list block element.\n*/\nfunction getSelectedListBlocks(selection) {\n\tconst blocks = Array.from(selection.getSelectedBlocks());\n\tconst firstNonListBlockIndex = blocks.findIndex((block) => !isListItemBlock(block));\n\tif (firstNonListBlockIndex != -1) blocks.length = firstNonListBlockIndex;\n\treturn blocks;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* The list command. It is used by the {@link module:list/list~List list feature}.\n*/\nvar ListCommand = class extends Command {\n\t/**\n\t* The type of the list created by the command.\n\t*/\n\ttype;\n\t/**\n\t* List Walker options that change the range of the list items to be changed when the selection is collapsed within a list item.\n\t*\n\t* In a multi-level list, when the selection is collapsed within a list item, instead of changing only the list items of the same list\n\t* type and current indent level, the entire list structure is changed (all list items at all indent levels of any list type).\n\t*/\n\t_listWalkerOptions;\n\t/**\n\t* Creates an instance of the command.\n\t*\n\t* @param editor The editor instance.\n\t* @param type List type that will be handled by this command.\n\t*/\n\tconstructor(editor, type, options = {}) {\n\t\tsuper(editor);\n\t\tthis.type = type;\n\t\tthis._listWalkerOptions = options.multiLevel ? {\n\t\t\thigherIndent: true,\n\t\t\tlowerIndent: true,\n\t\t\tsameAttributes: []\n\t\t} : void 0;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\t/**\n\t* Executes the list command.\n\t*\n\t* @fires execute\n\t* @fires afterExecute\n\t* @param options Command options.\n\t* @param options.forceValue If set, it will force the command behavior. If `true`, the command will try to convert the\n\t* selected items and potentially the neighbor elements to the proper list items. If set to `false` it will convert selected elements\n\t* to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.\n\t* @param options.additionalAttributes Additional attributes that are set for list items when the command is executed.\n\t*/\n\texecute(options = {}) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst selectedBlockObject = getSelectedBlockObject(model);\n\t\tconst blocks = Array.from(document.selection.getSelectedBlocks()).filter((block) => model.schema.checkAttribute(block, \"listType\") || canBecomeSimpleListItem(block, model.schema));\n\t\tconst turnOff = options.forceValue !== void 0 ? !options.forceValue : this.value;\n\t\tmodel.change((writer) => {\n\t\t\tif (turnOff) {\n\t\t\t\tconst lastBlock = blocks[blocks.length - 1];\n\t\t\t\tconst attributeNames = this.editor.plugins.get(\"ListEditing\").getListAttributeNames();\n\t\t\t\tconst itemBlocks = getListItemBlocks(lastBlock, { direction: \"forward\" });\n\t\t\t\tconst changedBlocks = [];\n\t\t\t\tif (itemBlocks.length > 1) changedBlocks.push(...splitListItemBefore(itemBlocks[1], writer));\n\t\t\t\tchangedBlocks.push(...removeListAttributes(blocks, writer, attributeNames));\n\t\t\t\tchangedBlocks.push(...outdentFollowingItems(lastBlock, writer));\n\t\t\t\tthis._fireAfterExecute(changedBlocks);\n\t\t\t} else if ((selectedBlockObject || document.selection.isCollapsed) && isListItemBlock(blocks[0])) {\n\t\t\t\tconst changedBlocks = getListItems(selectedBlockObject || blocks[0], this._listWalkerOptions);\n\t\t\t\tfor (const block of changedBlocks) writer.setAttributes({\n\t\t\t\t\t...options.additionalAttributes,\n\t\t\t\t\tlistType: this.type\n\t\t\t\t}, block);\n\t\t\t\tthis._fireAfterExecute(changedBlocks);\n\t\t\t} else {\n\t\t\t\tconst changedBlocks = [];\n\t\t\t\tfor (const block of blocks) if (!block.hasAttribute(\"listType\")) {\n\t\t\t\t\tif (!block.is(\"element\", \"listItem\") && canBecomeSimpleListItem(block, model.schema)) writer.rename(block, \"listItem\");\n\t\t\t\t\twriter.setAttributes({\n\t\t\t\t\t\t...options.additionalAttributes,\n\t\t\t\t\t\tlistIndent: 0,\n\t\t\t\t\t\tlistItemId: ListItemUid.next(),\n\t\t\t\t\t\tlistType: this.type\n\t\t\t\t\t}, block);\n\t\t\t\t\tchangedBlocks.push(block);\n\t\t\t\t} else for (const node of expandListBlocksToCompleteItems(block, { withNested: false })) if (node.getAttribute(\"listType\") != this.type) {\n\t\t\t\t\twriter.setAttributes({\n\t\t\t\t\t\t...options.additionalAttributes,\n\t\t\t\t\t\tlistType: this.type\n\t\t\t\t\t}, node);\n\t\t\t\t\tchangedBlocks.push(node);\n\t\t\t\t}\n\t\t\t\tthis._fireAfterExecute(changedBlocks);\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* Fires the `afterExecute` event.\n\t*\n\t* @param changedBlocks The changed list elements.\n\t*/\n\t_fireAfterExecute(changedBlocks) {\n\t\tthis.fire(\"afterExecute\", sortBlocks(new Set(changedBlocks)));\n\t}\n\t/**\n\t* Checks the command's {@link #value}.\n\t*\n\t* @returns The current value.\n\t*/\n\t_getValue() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst blocks = Array.from(selection.getSelectedBlocks());\n\t\tif (!blocks.length) return false;\n\t\tfor (const block of blocks) if (block.getAttribute(\"listType\") != this.type) return false;\n\t\treturn true;\n\t}\n\t/**\n\t* Checks whether the command can be enabled in the current context.\n\t*\n\t* @returns Whether the command should be enabled.\n\t*/\n\t_checkEnabled() {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\t\tconst blocks = Array.from(selection.getSelectedBlocks());\n\t\tif (!blocks.length) return false;\n\t\tif (this.value) return true;\n\t\tfor (const block of blocks) if (schema.checkAttribute(block, \"listType\") || canBecomeSimpleListItem(block, schema)) return true;\n\t\treturn false;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/list/listmergecommand\n*/\n/**\n* The document list merge command. It is used by the {@link module:list/list~List list feature}.\n*/\nvar ListMergeCommand = class extends Command {\n\t/**\n\t* Whether list item should be merged before or after the selected block.\n\t*/\n\t_direction;\n\t/**\n\t* Creates an instance of the command.\n\t*\n\t* @param editor The editor instance.\n\t* @param direction Whether list item should be merged before or after the selected block.\n\t*/\n\tconstructor(editor, direction) {\n\t\tsuper(editor);\n\t\tthis._direction = direction;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\t/**\n\t* Merges list blocks together (depending on the {@link #constructor}'s `direction` parameter).\n\t*\n\t* @fires execute\n\t* @fires afterExecute\n\t* @param options Command options.\n\t* @param options.shouldMergeOnBlocksContentLevel When set `true`, merging will be performed together\n\t* with {@link module:engine/model/model~Model#deleteContent} to get rid of the inline content in the selection or take advantage\n\t* of the heuristics in `deleteContent()` that helps convert lists into paragraphs in certain cases.\n\t*/\n\texecute({ shouldMergeOnBlocksContentLevel = false } = {}) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst changedBlocks = [];\n\t\tconst attributeNames = editor.plugins.get(\"ListEditing\").getListAttributeNames();\n\t\tmodel.change((writer) => {\n\t\t\tconst { firstElement, lastElement } = this._getMergeSubjectElements(selection, shouldMergeOnBlocksContentLevel);\n\t\t\tif (!firstElement || !lastElement) return;\n\t\t\tconst firstIndent = firstElement.getAttribute(\"listIndent\") || 0;\n\t\t\tconst lastIndent = lastElement.getAttribute(\"listIndent\");\n\t\t\tconst lastElementId = lastElement.getAttribute(\"listItemId\");\n\t\t\tif (firstIndent != lastIndent) {\n\t\t\t\tconst nestedLastElementBlocks = getNestedListBlocks(lastElement);\n\t\t\t\tchangedBlocks.push(...indentBlocks([lastElement, ...nestedLastElementBlocks], writer, {\n\t\t\t\t\tindentBy: firstIndent - lastIndent,\n\t\t\t\t\texpand: firstIndent < lastIndent,\n\t\t\t\t\tattributeNames\n\t\t\t\t}));\n\t\t\t}\n\t\t\tif (shouldMergeOnBlocksContentLevel) {\n\t\t\t\tlet sel = selection;\n\t\t\t\tif (selection.isCollapsed) sel = writer.createSelection(writer.createRange(writer.createPositionAt(firstElement, \"end\"), writer.createPositionAt(lastElement, 0)));\n\t\t\t\tmodel.deleteContent(sel, { doNotResetEntireContent: selection.isCollapsed });\n\t\t\t\tconst lastElementAfterDelete = sel.getLastPosition().parent;\n\t\t\t\tconst nextSibling = lastElementAfterDelete.nextSibling;\n\t\t\t\tchangedBlocks.push(lastElementAfterDelete);\n\t\t\t\tif (nextSibling && nextSibling !== lastElement && nextSibling.getAttribute(\"listItemId\") == lastElementId) changedBlocks.push(...mergeListItemBefore(nextSibling, lastElementAfterDelete, writer));\n\t\t\t} else changedBlocks.push(...mergeListItemBefore(lastElement, firstElement, writer));\n\t\t\tthis._fireAfterExecute(changedBlocks);\n\t\t});\n\t}\n\t/**\n\t* Fires the `afterExecute` event.\n\t*\n\t* @param changedBlocks The changed list elements.\n\t*/\n\t_fireAfterExecute(changedBlocks) {\n\t\tthis.fire(\"afterExecute\", sortBlocks(new Set(changedBlocks)));\n\t}\n\t/**\n\t* Checks whether the command can be enabled in the current context.\n\t*\n\t* @returns Whether the command should be enabled.\n\t*/\n\t_checkEnabled() {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst selectedBlockObject = getSelectedBlockObject(model);\n\t\tif (selection.isCollapsed || selectedBlockObject) {\n\t\t\tconst positionParent = selectedBlockObject || selection.getFirstPosition().parent;\n\t\t\tif (!isListItemBlock(positionParent)) return false;\n\t\t\tconst siblingNode = this._direction == \"backward\" ? positionParent.previousSibling : positionParent.nextSibling;\n\t\t\tif (!siblingNode) return false;\n\t\t\tif (isSingleListItem([positionParent, siblingNode])) return false;\n\t\t} else {\n\t\t\tconst lastPosition = selection.getLastPosition();\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\t\t\tif (lastPosition.parent === firstPosition.parent) return false;\n\t\t\tif (!isListItemBlock(lastPosition.parent)) return false;\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Returns the boundary elements the merge should be executed for. These are not necessarily selection's first\n\t* and last position parents but sometimes sibling or even further blocks depending on the context.\n\t*\n\t* @param selection The selection the merge is executed for.\n\t* @param shouldMergeOnBlocksContentLevel When `true`, merge is performed together with\n\t* {@link module:engine/model/model~Model#deleteContent} to remove the inline content within the selection.\n\t*/\n\t_getMergeSubjectElements(selection, shouldMergeOnBlocksContentLevel) {\n\t\tconst model = this.editor.model;\n\t\tconst selectedBlockObject = getSelectedBlockObject(model);\n\t\tlet firstElement, lastElement;\n\t\tif (selection.isCollapsed || selectedBlockObject) {\n\t\t\tconst positionParent = selectedBlockObject || selection.getFirstPosition().parent;\n\t\t\tconst isFirstBlock = isFirstBlockOfListItem(positionParent);\n\t\t\tif (this._direction == \"backward\") {\n\t\t\t\tlastElement = positionParent;\n\t\t\t\tif (isFirstBlock && !shouldMergeOnBlocksContentLevel) {\n\t\t\t\t\tfirstElement = ListWalker.first(positionParent, {\n\t\t\t\t\t\tsameIndent: true,\n\t\t\t\t\t\tlowerIndent: true\n\t\t\t\t\t});\n\t\t\t\t\tif (!firstElement && isListItemBlock(positionParent.previousSibling)) firstElement = positionParent.previousSibling;\n\t\t\t\t} else firstElement = positionParent.previousSibling;\n\t\t\t} else {\n\t\t\t\tfirstElement = positionParent;\n\t\t\t\tlastElement = positionParent.nextSibling;\n\t\t\t}\n\t\t} else {\n\t\t\tfirstElement = selection.getFirstPosition().parent;\n\t\t\tlastElement = selection.getLastPosition().parent;\n\t\t}\n\t\treturn {\n\t\t\tfirstElement,\n\t\t\tlastElement\n\t\t};\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* The document list split command that splits the list item at the selection.\n*\n* It is used by the {@link module:list/list~List list feature}.\n*/\nvar ListSplitCommand = class extends Command {\n\t/**\n\t* Whether list item should be split before or after the selected block.\n\t*/\n\t_direction;\n\t/**\n\t* Creates an instance of the command.\n\t*\n\t* @param editor The editor instance.\n\t* @param direction Whether list item should be split before or after the selected block.\n\t*/\n\tconstructor(editor, direction) {\n\t\tsuper(editor);\n\t\tthis._direction = direction;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\t/**\n\t* Splits the list item at the selection.\n\t*\n\t* @fires execute\n\t* @fires afterExecute\n\t*/\n\texecute() {\n\t\tthis.editor.model.change((writer) => {\n\t\t\tconst changedBlocks = splitListItemBefore(this._getStartBlock(), writer);\n\t\t\tthis._fireAfterExecute(changedBlocks);\n\t\t});\n\t}\n\t/**\n\t* Fires the `afterExecute` event.\n\t*\n\t* @param changedBlocks The changed list elements.\n\t*/\n\t_fireAfterExecute(changedBlocks) {\n\t\tthis.fire(\"afterExecute\", sortBlocks(new Set(changedBlocks)));\n\t}\n\t/**\n\t* Checks whether the command can be enabled in the current context.\n\t*\n\t* @returns Whether the command should be enabled.\n\t*/\n\t_checkEnabled() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst block = this._getStartBlock();\n\t\treturn selection.isCollapsed && isListItemBlock(block) && !isFirstBlockOfListItem(block);\n\t}\n\t/**\n\t* Returns the model element that is the main focus of the command (according to the current selection and command direction).\n\t*/\n\t_getStartBlock() {\n\t\tconst positionParent = this.editor.model.document.selection.getFirstPosition().parent;\n\t\treturn this._direction == \"before\" ? positionParent : positionParent.nextSibling;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listformatting/listitemboldintegration\n*/\n/**\n* The list item bold integration plugin.\n*/\nvar ListItemBoldIntegration = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListItemBoldIntegration\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [ListEditing];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst ListFormatting = editor.plugins.get(\"ListFormatting\");\n\t\tconst listEditing = editor.plugins.get(ListEditing);\n\t\tif (!editor.plugins.has(\"BoldEditing\") || !this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tListFormatting.registerFormatAttribute(\"bold\", \"listItemBold\");\n\t\tlistEditing.registerDowncastStrategy({\n\t\t\tscope: \"item\",\n\t\t\tattributeName: \"listItemBold\",\n\t\t\tsetAttributeOnDowncast(writer, value, viewElement, options) {\n\t\t\t\t/* v8 ignore next -- Downcast callbacks are only registered for meaningful list marker formatting values. */\n\t\t\t\tif (value) {\n\t\t\t\t\twriter.addClass(\"ck-list-marker-bold\", viewElement);\n\t\t\t\t\tif (env.isSafari && !(options && options.dataPipeline)) writer.setStyle(\"--ck-content-list-marker-dummy-bold\", \"0\", viewElement);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tif (!editor.plugins.has(\"BoldEditing\") || !this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tmodel.schema.extend(\"$listItem\", { allowAttributes: \"listItemBold\" });\n\t\tmodel.schema.setAttributeProperties(\"listItemBold\", { isFormatting: true });\n\t\tmodel.schema.addAttributeCheck((context) => {\n\t\t\tif (!context.last.getAttribute(\"listItemId\")) return false;\n\t\t}, \"listItemBold\");\n\t\teditor.conversion.for(\"upcast\").attributeToAttribute({\n\t\t\tmodel: \"listItemBold\",\n\t\t\tview: {\n\t\t\t\tname: \"li\",\n\t\t\t\tclasses: \"ck-list-marker-bold\"\n\t\t\t}\n\t\t});\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listformatting/listitemitalicintegration\n*/\n/**\n* The list item italic integration plugin.\n*/\nvar ListItemItalicIntegration = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListItemItalicIntegration\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [ListEditing];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst ListFormatting = editor.plugins.get(\"ListFormatting\");\n\t\tconst listEditing = editor.plugins.get(ListEditing);\n\t\tif (!editor.plugins.has(\"ItalicEditing\") || !this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tListFormatting.registerFormatAttribute(\"italic\", \"listItemItalic\");\n\t\tlistEditing.registerDowncastStrategy({\n\t\t\tscope: \"item\",\n\t\t\tattributeName: \"listItemItalic\",\n\t\t\tsetAttributeOnDowncast(writer, value, viewElement, options) {\n\t\t\t\t/* v8 ignore next -- Downcast callbacks are only registered for meaningful list marker formatting values. */\n\t\t\t\tif (value) {\n\t\t\t\t\twriter.addClass(\"ck-list-marker-italic\", viewElement);\n\t\t\t\t\tif (env.isSafari && !(options && options.dataPipeline)) writer.setStyle(\"--ck-content-list-marker-dummy-italic\", \"0\", viewElement);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tif (!editor.plugins.has(\"ItalicEditing\") || !this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tmodel.schema.extend(\"$listItem\", { allowAttributes: \"listItemItalic\" });\n\t\tmodel.schema.setAttributeProperties(\"listItemItalic\", { isFormatting: true });\n\t\tmodel.schema.addAttributeCheck((context) => {\n\t\t\tif (!context.last.getAttribute(\"listItemId\")) return false;\n\t\t}, \"listItemItalic\");\n\t\teditor.conversion.for(\"upcast\").attributeToAttribute({\n\t\t\tmodel: \"listItemItalic\",\n\t\t\tview: {\n\t\t\t\tname: \"li\",\n\t\t\t\tclasses: \"ck-list-marker-italic\"\n\t\t\t}\n\t\t});\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listformatting/listitemfontsizeintegration\n*/\n/**\n* The list item font size integration plugin.\n*/\nvar ListItemFontSizeIntegration = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListItemFontSizeIntegration\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [ListEditing];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst ListFormatting = editor.plugins.get(\"ListFormatting\");\n\t\tconst listEditing = editor.plugins.get(ListEditing);\n\t\tif (!editor.plugins.has(\"FontSizeEditing\") || !this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tconst normalizedFontSizeOptions = _normalizeFontSizeOptions(editor.config.get(\"fontSize.options\"));\n\t\tListFormatting.registerFormatAttribute(\"fontSize\", \"listItemFontSize\");\n\t\tlistEditing.registerDowncastStrategy({\n\t\t\tscope: \"item\",\n\t\t\tattributeName: \"listItemFontSize\",\n\t\t\tsetAttributeOnDowncast(writer, value, viewElement, options) {\n\t\t\t\t/* v8 ignore next -- Downcast callbacks are only registered for meaningful list marker formatting values. */\n\t\t\t\tif (value) {\n\t\t\t\t\tconst fontSizeOption = normalizedFontSizeOptions.find((option) => option.model == value);\n\t\t\t\t\tif (fontSizeOption && fontSizeOption.view && typeof fontSizeOption.view != \"string\") {\n\t\t\t\t\t\tif (fontSizeOption.view.styles) {\n\t\t\t\t\t\t\twriter.addClass(\"ck-list-marker-font-size\", viewElement);\n\t\t\t\t\t\t\twriter.setStyle(\"--ck-content-list-marker-font-size\", fontSizeOption.view.styles[\"font-size\"], viewElement);\n\t\t\t\t\t\t} else if (fontSizeOption.view.classes) {\n\t\t\t\t\t\t\twriter.addClass(`ck-list-marker-font-size-${value}`, viewElement);\n\t\t\t\t\t\t\tif (env.isSafari && !(options && options.dataPipeline)) writer.setStyle(\"--ck-content-list-marker-dummy-font-size\", \"0\", viewElement);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.addClass(\"ck-list-marker-font-size\", viewElement);\n\t\t\t\t\t\twriter.setStyle(\"--ck-content-list-marker-font-size\", value, viewElement);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tif (!editor.plugins.has(\"FontSizeEditing\") || !this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tmodel.schema.extend(\"$listItem\", { allowAttributes: \"listItemFontSize\" });\n\t\tmodel.schema.setAttributeProperties(\"listItemFontSize\", { isFormatting: true });\n\t\tmodel.schema.addAttributeCheck((context) => {\n\t\t\tif (!context.last.getAttribute(\"listItemId\")) return false;\n\t\t}, \"listItemFontSize\");\n\t\teditor.conversion.for(\"upcast\").elementToAttribute({\n\t\t\tmodel: {\n\t\t\t\tkey: \"listItemFontSize\",\n\t\t\t\tvalue: (viewElement) => viewElement.getStyle(\"--ck-content-list-marker-font-size\")\n\t\t\t},\n\t\t\tview: {\n\t\t\t\tname: \"li\",\n\t\t\t\tclasses: \"ck-list-marker-font-size\",\n\t\t\t\tstyles: { \"--ck-content-list-marker-font-size\": /.*/ }\n\t\t\t}\n\t\t});\n\t\tconst fontSizeOptions = _normalizeFontSizeOptions(editor.config.get(\"fontSize.options\"));\n\t\tfor (const option of fontSizeOptions)\n /* v8 ignore next -- Normalized font size options used by the integration provide model and view values. */\n\t\tif (option.model && option.view) editor.conversion.for(\"upcast\").elementToAttribute({\n\t\t\tmodel: {\n\t\t\t\tkey: \"listItemFontSize\",\n\t\t\t\tvalue: option.model\n\t\t\t},\n\t\t\tview: {\n\t\t\t\tname: \"li\",\n\t\t\t\tclasses: `ck-list-marker-font-size-${option.model}`\n\t\t\t}\n\t\t});\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listformatting/listitemfontcolorintegration\n*/\n/**\n* The list item font color integration plugin.\n*/\nvar ListItemFontColorIntegration = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListItemFontColorIntegration\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [ListEditing];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst ListFormatting = editor.plugins.get(\"ListFormatting\");\n\t\tconst listEditing = editor.plugins.get(ListEditing);\n\t\tif (!editor.plugins.has(\"FontColorEditing\") || !this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tListFormatting.registerFormatAttribute(\"fontColor\", \"listItemFontColor\");\n\t\tlistEditing.registerDowncastStrategy({\n\t\t\tscope: \"item\",\n\t\t\tattributeName: \"listItemFontColor\",\n\t\t\tsetAttributeOnDowncast(writer, value, viewElement) {\n\t\t\t\t/* v8 ignore next -- Downcast callbacks are only registered for meaningful list marker formatting values. */\n\t\t\t\tif (value) {\n\t\t\t\t\twriter.addClass(\"ck-list-marker-color\", viewElement);\n\t\t\t\t\twriter.setStyle(\"--ck-content-list-marker-color\", value, viewElement);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tif (!editor.plugins.has(\"FontColorEditing\") || !this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tmodel.schema.extend(\"$listItem\", { allowAttributes: \"listItemFontColor\" });\n\t\tmodel.schema.setAttributeProperties(\"listItemFontColor\", { isFormatting: true });\n\t\tmodel.schema.addAttributeCheck((context) => {\n\t\t\tif (!context.last.getAttribute(\"listItemId\")) return false;\n\t\t}, \"listItemFontColor\");\n\t\teditor.conversion.for(\"upcast\").attributeToAttribute({\n\t\t\tmodel: {\n\t\t\t\tkey: \"listItemFontColor\",\n\t\t\t\tvalue: (viewElement) => {\n\t\t\t\t\treturn viewElement.getStyle(\"--ck-content-list-marker-color\");\n\t\t\t\t}\n\t\t\t},\n\t\t\tview: {\n\t\t\t\tname: \"li\",\n\t\t\t\tclasses: \"ck-list-marker-color\",\n\t\t\t\tstyles: { \"--ck-content-list-marker-color\": /.*/ }\n\t\t\t}\n\t\t});\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listformatting/listitemfontfamilyintegration\n*/\n/**\n* The list item font family integration plugin.\n*/\nvar ListItemFontFamilyIntegration = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListItemFontFamilyIntegration\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [ListEditing];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst ListFormatting = editor.plugins.get(\"ListFormatting\");\n\t\tconst listEditing = editor.plugins.get(ListEditing);\n\t\tif (!editor.plugins.has(\"FontFamilyEditing\") || !this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tListFormatting.registerFormatAttribute(\"fontFamily\", \"listItemFontFamily\");\n\t\tlistEditing.registerDowncastStrategy({\n\t\t\tscope: \"item\",\n\t\t\tattributeName: \"listItemFontFamily\",\n\t\t\tsetAttributeOnDowncast(writer, value, viewElement) {\n\t\t\t\t/* v8 ignore next -- Downcast callbacks are only registered for meaningful list marker formatting values. */\n\t\t\t\tif (value) {\n\t\t\t\t\twriter.addClass(\"ck-list-marker-font-family\", viewElement);\n\t\t\t\t\twriter.setStyle(\"--ck-content-list-marker-font-family\", value, viewElement);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tif (!editor.plugins.has(\"FontFamilyEditing\") || !this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tmodel.schema.extend(\"$listItem\", { allowAttributes: \"listItemFontFamily\" });\n\t\tmodel.schema.setAttributeProperties(\"listItemFontFamily\", { isFormatting: true });\n\t\tmodel.schema.addAttributeCheck((context) => {\n\t\t\tif (!context.last.getAttribute(\"listItemId\")) return false;\n\t\t}, \"listItemFontFamily\");\n\t\teditor.conversion.for(\"upcast\").attributeToAttribute({\n\t\t\tmodel: {\n\t\t\t\tkey: \"listItemFontFamily\",\n\t\t\t\tvalue: (viewElement) => {\n\t\t\t\t\treturn viewElement.getStyle(\"--ck-content-list-marker-font-family\");\n\t\t\t\t}\n\t\t\t},\n\t\t\tview: {\n\t\t\t\tname: \"li\",\n\t\t\t\tclasses: \"ck-list-marker-font-family\",\n\t\t\t\tstyles: { \"--ck-content-list-marker-font-family\": /.*/ }\n\t\t\t}\n\t\t});\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listformatting\n*/\n/**\n* The list formatting plugin.\n*\n* It enables integration with formatting plugins to style the list marker.\n* The list marker is styled based on the consistent formatting applied to the content of the list item.\n*\n* The list of supported formatting plugins includes:\n* * Font color.\n* * Font size.\n* * Font family.\n* * Bold.\n* * Italic.\n*/\nvar ListFormatting = class extends Plugin {\n\t/**\n\t* The list of loaded formatting.\n\t*/\n\t_loadedFormatting = {};\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListFormatting\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [\n\t\t\tListItemBoldIntegration,\n\t\t\tListItemItalicIntegration,\n\t\t\tListItemFontSizeIntegration,\n\t\t\tListItemFontColorIntegration,\n\t\t\tListItemFontFamilyIntegration\n\t\t];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(editor) {\n\t\tsuper(editor);\n\t\teditor.config.define(\"list.enableListItemMarkerFormatting\", true);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tafterInit() {\n\t\tif (!this.editor.config.get(\"list.enableListItemMarkerFormatting\")) return;\n\t\tthis._registerPostfixerForListItemFormatting();\n\t}\n\t/**\n\t* Registers a postfixer that ensures that the list item formatting attribute is consistent with the formatting\n\t* applied to the content of the list item.\n\t*/\n\t_registerPostfixerForListItemFormatting() {\n\t\tconst model = this.editor.model;\n\t\tmodel.document.registerPostFixer((writer) => {\n\t\t\tconst changes = model.document.differ.getChanges();\n\t\t\tconst modifiedListItems = /* @__PURE__ */ new Set();\n\t\t\tlet returnValue = false;\n\t\t\tfor (const entry of changes) if (entry.type === \"attribute\") {\n\t\t\t\tif (entry.attributeKey == \"listItemId\" || entry.attributeKey == \"listType\" || this._isInlineOrSelectionFormatting(entry.attributeKey) || Object.values(this._loadedFormatting).includes(entry.attributeKey)) {\n\t\t\t\t\tif (isListItemBlock(entry.range.start.nodeAfter)) modifiedListItems.add(entry.range.start.nodeAfter);\n\t\t\t\t\telse if (isListItemBlock(entry.range.start.parent)) modifiedListItems.add(entry.range.start.parent);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (isListItemBlock(entry.position.nodeAfter)) modifiedListItems.add(entry.position.nodeAfter);\n\t\t\t\tif (isListItemBlock(entry.position.nodeBefore)) modifiedListItems.add(entry.position.nodeBefore);\n\t\t\t\tif (isListItemBlock(entry.position.parent)) modifiedListItems.add(entry.position.parent);\n\t\t\t\tif (entry.type == \"insert\" && entry.name != \"$text\") {\n\t\t\t\t\tconst range = writer.createRangeIn(entry.position.nodeAfter);\n\t\t\t\t\tfor (const item of range.getItems()) if (isListItemBlock(item)) modifiedListItems.add(item);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const listItem of modifiedListItems) {\n\t\t\t\tconst formats = getListItemConsistentFormat(model, listItem, Object.keys(this._loadedFormatting));\n\t\t\t\tfor (const [formatAttributeName, formatValue] of Object.entries(formats)) {\n\t\t\t\t\tconst listItemFormatAttributeName = this._loadedFormatting[formatAttributeName];\n\t\t\t\t\tif (formatValue && setFormattingToListItem(writer, listItem, listItemFormatAttributeName, formatValue)) returnValue = true;\n\t\t\t\t\telse if (!formatValue && removeFormattingFromListItem(writer, listItem, listItemFormatAttributeName)) returnValue = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn returnValue;\n\t\t});\n\t}\n\t/**\n\t* Registers an integration between a default attribute (e.g., `fontFamily`) and a new attribute\n\t* intended specifically for list item elements (e.g., `listItemFontFamily`).\n\t*\n\t* These attributes are later used by the postfixer logic to determine whether to add the new attribute\n\t* to the list item element, based on whether there is a consistent default formatting attribute\n\t* applied within its content.\n\t*/\n\tregisterFormatAttribute(formatAttribute, listItemFormatAttribute) {\n\t\tthis._loadedFormatting[formatAttribute] = listItemFormatAttribute;\n\t}\n\t/**\n\t* Returns true if the given model attribute name is a supported inline formatting attribute.\n\t*/\n\t_isInlineOrSelectionFormatting(attributeKey) {\n\t\treturn attributeKey.replace(/^selection:/, \"\") in this._loadedFormatting;\n\t}\n};\n/**\n* Returns the consistent format of the list item element.\n* If the list item contains multiple blocks, it checks only the first block.\n*/\nfunction getListItemConsistentFormat(model, listItem, attributeKeys) {\n\tif (isFirstBlockOfListItem(listItem)) return getSingleListItemConsistentFormat(model, listItem, attributeKeys);\n\treturn getSingleListItemConsistentFormat(model, getAllListItemBlocks(listItem)[0], attributeKeys);\n}\n/**\n* Returns the consistent format of a single list item element.\n*/\nfunction getSingleListItemConsistentFormat(model, listItem, attributeKeys) {\n\tif (!isNumberedOrBulletedList(listItem) || model.schema.isLimit(listItem)) return Object.fromEntries(attributeKeys.map((attributeKey) => [attributeKey]));\n\tif (listItem.isEmpty) return Object.fromEntries(attributeKeys.map((attributeKey) => [attributeKey, listItem.getAttribute(`selection:${attributeKey}`)]));\n\tconst attributesToCheck = new Set(attributeKeys);\n\tconst valuesMap = {};\n\tconst walker = model.createRangeIn(listItem).getWalker({ ignoreElementEnd: true });\n\tfor (const { item } of walker) {\n\t\tfor (const attributeKey of attributesToCheck) if (model.schema.checkAttribute(item, attributeKey)) {\n\t\t\tconst formatAttribute = item.getAttribute(attributeKey);\n\t\t\tif (formatAttribute === void 0) {\n\t\t\t\tattributesToCheck.delete(attributeKey);\n\t\t\t\tvaluesMap[attributeKey] = void 0;\n\t\t\t} else if (valuesMap[attributeKey] === void 0) valuesMap[attributeKey] = formatAttribute;\n\t\t\telse if (valuesMap[attributeKey] !== formatAttribute) {\n\t\t\t\tattributesToCheck.delete(attributeKey);\n\t\t\t\tvaluesMap[attributeKey] = void 0;\n\t\t\t}\n\t\t} else if (!(attributeKey in valuesMap)) valuesMap[attributeKey] = void 0;\n\t\tif (!attributesToCheck.size) break;\n\t\tif (model.schema.isLimit(item)) walker.jumpTo(model.createPositionAfter(item));\n\t}\n\treturn valuesMap;\n}\n/**\n* Adds the specified formatting attribute to the list item element.\n*/\nfunction setFormattingToListItem(writer, listItem, attributeKey, attributeValue) {\n\tconst listItemBlocks = getAllListItemBlocks(listItem);\n\tlet wasChanged = false;\n\tfor (const listItem of listItemBlocks) if (!listItem.hasAttribute(attributeKey) || listItem.getAttribute(attributeKey) !== attributeValue) {\n\t\twriter.setAttribute(attributeKey, attributeValue, listItem);\n\t\twasChanged = true;\n\t}\n\treturn wasChanged;\n}\n/**\n* Removes the specified formatting attribute from the list item element.\n*/\nfunction removeFormattingFromListItem(writer, listItem, attributeKey) {\n\tconst listItemBlocks = getAllListItemBlocks(listItem);\n\tlet wasChanged = false;\n\tfor (const listItem of listItemBlocks) if (listItem.hasAttribute(attributeKey)) {\n\t\twriter.removeAttribute(attributeKey, listItem);\n\t\twasChanged = true;\n\t}\n\treturn wasChanged;\n}\n/**\n* Checks if the given list type is a numbered or bulleted list.\n*/\nfunction isNumberedOrBulletedList(listItem) {\n\treturn [\n\t\t\"numbered\",\n\t\t\"bulleted\",\n\t\t\"customNumbered\",\n\t\t\"customBulleted\"\n\t].includes(listItem.getAttribute(\"listType\"));\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* A set of helpers related to document lists.\n*/\nvar ListUtils = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListUtils\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* Expands the given list of selected blocks to include all the items of the lists they're in.\n\t*\n\t* @param blocks The list of selected blocks.\n\t*/\n\texpandListBlocksToCompleteList(blocks) {\n\t\treturn expandListBlocksToCompleteList(blocks);\n\t}\n\t/**\n\t* Check if the given block is the first in the list item.\n\t*\n\t* @param listBlock The list block element.\n\t*/\n\tisFirstBlockOfListItem(listBlock) {\n\t\treturn isFirstBlockOfListItem(listBlock);\n\t}\n\t/**\n\t* Returns true if the given model node is a list item block.\n\t*\n\t* @param node A model node.\n\t*/\n\tisListItemBlock(node) {\n\t\treturn isListItemBlock(node);\n\t}\n\t/**\n\t* Expands the given list of selected blocks to include the leading and tailing blocks of partially selected list items.\n\t*\n\t* @param blocks The list of selected blocks.\n\t* @param options.withNested Whether should include nested list items.\n\t*/\n\texpandListBlocksToCompleteItems(blocks, options = {}) {\n\t\treturn expandListBlocksToCompleteItems(blocks, options);\n\t}\n\t/**\n\t* Returns true if listType is of type `numbered` or `customNumbered`.\n\t*/\n\tisNumberedListType(listType) {\n\t\treturn isNumberedListType(listType);\n\t}\n\t/**\n\t* Returns true if the given list item is the first item in the list.\n\t*/\n\tisFirstListItemInList(listItem) {\n\t\treturn isFirstListItemInList(listItem);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Checks if view element is a list type (ul or ol).\n*\n* @internal\n*/\nfunction isListView(viewElement) {\n\treturn viewElement.is(\"element\", \"ol\") || viewElement.is(\"element\", \"ul\");\n}\n/**\n* Checks if view element is a list item (li).\n*\n* @internal\n*/\nfunction isListItemView(viewElement) {\n\treturn viewElement.is(\"element\", \"li\");\n}\n/**\n* Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.\n*\n* Also, fixes non HTML compliant lists indents:\n*\n* ```\n* before: fixed list:\n* OL OL\n* |-> LI (parent LIs: 0) |-> LI (indent: 0)\n* |-> OL |-> OL\n* |-> OL |\n* | |-> OL |\n* | |-> OL |\n* | |-> LI (parent LIs: 1) |-> LI (indent: 1)\n* |-> LI (parent LIs: 1) |-> LI (indent: 1)\n*\n* before: fixed list:\n* OL OL\n* |-> OL |\n* |-> OL |\n* |-> OL |\n* |-> LI (parent LIs: 0) |-> LI (indent: 0)\n*\n* before: fixed list:\n* OL OL\n* |-> LI (parent LIs: 0) |-> LI (indent: 0)\n* |-> OL |-> OL\n* |-> LI (parent LIs: 0) |-> LI (indent: 1)\n* ```\n*\n* @internal\n*/\nfunction getIndent(listItem) {\n\tlet indent = 0;\n\tlet parent = listItem.parent;\n\twhile (parent) {\n\t\tif (isListItemView(parent)) indent++;\n\t\telse {\n\t\t\tconst previousSibling = parent.previousSibling;\n\t\t\tif (previousSibling && isListItemView(previousSibling)) indent++;\n\t\t}\n\t\tparent = parent.parent;\n\t}\n\treturn indent;\n}\n/**\n* Creates a list attribute element (ol or ul).\n*\n* @internal\n*/\nfunction createListElement(writer, indent, type, id = getViewElementIdForListType(type, indent)) {\n\treturn writer.createAttributeElement(getViewElementNameForListType(type), null, {\n\t\tpriority: 2 * indent / 100 - 100,\n\t\tid\n\t});\n}\n/**\n* Creates a list item attribute element (li).\n*\n* @internal\n*/\nfunction createListItemElement(writer, indent, id) {\n\treturn writer.createAttributeElement(\"li\", null, {\n\t\tpriority: (2 * indent + 1) / 100 - 100,\n\t\tid\n\t});\n}\n/**\n* Returns a view element name for the given list type.\n*\n* @internal\n*/\nfunction getViewElementNameForListType(type) {\n\treturn type == \"numbered\" || type == \"customNumbered\" ? \"ol\" : \"ul\";\n}\n/**\n* Returns a view element ID for the given list type and indent.\n*\n* @internal\n*/\nfunction getViewElementIdForListType(type, indent) {\n\treturn `list-${type}-${indent}`;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Based on the provided positions looks for the list head and stores it in the provided map.\n*\n* @internal\n* @param position The search starting position.\n* @param itemToListHead The map from list item element to the list head element.\n* @param visited A set of elements that were already visited.\n*/\nfunction findAndAddListHeadToMap(position, itemToListHead, visited) {\n\tconst previousNode = position.nodeBefore;\n\tif (!isListItemBlock(previousNode)) {\n\t\tconst item = position.nodeAfter;\n\t\tif (isListItemBlock(item)) itemToListHead.add(item);\n\t} else {\n\t\tlet listHead = previousNode;\n\t\tfor (const { node } of new SiblingListBlocksIterator(listHead, \"backward\")) {\n\t\t\tlistHead = node;\n\t\t\tif (visited.has(listHead)) return;\n\t\t\tvisited.add(listHead);\n\t\t\tif (itemToListHead.has(previousNode)) return;\n\t\t}\n\t\titemToListHead.add(listHead);\n\t}\n}\n/**\n* Scans the list starting from the given list head element and fixes items' indentation.\n*\n* @internal\n* @param listNodes The iterable of list nodes.\n* @param writer The model writer.\n* @returns Whether the model was modified.\n*/\nfunction fixListIndents(listNodes, writer) {\n\tlet maxIndent = 0;\n\tlet prevIndent = -1;\n\tlet fixBy = null;\n\tlet applied = false;\n\tfor (const { node } of listNodes) {\n\t\tconst itemIndent = node.getAttribute(\"listIndent\");\n\t\tif (itemIndent > maxIndent) {\n\t\t\tlet newIndent;\n\t\t\tif (fixBy === null) {\n\t\t\t\tfixBy = itemIndent - maxIndent;\n\t\t\t\tnewIndent = maxIndent;\n\t\t\t} else {\n\t\t\t\tif (fixBy > itemIndent) fixBy = itemIndent;\n\t\t\t\tnewIndent = itemIndent - fixBy;\n\t\t\t}\n\t\t\tif (newIndent > prevIndent + 1) newIndent = prevIndent + 1;\n\t\t\twriter.setAttribute(\"listIndent\", newIndent, node);\n\t\t\tapplied = true;\n\t\t\tprevIndent = newIndent;\n\t\t} else {\n\t\t\tfixBy = null;\n\t\t\tmaxIndent = itemIndent + 1;\n\t\t\tprevIndent = itemIndent;\n\t\t}\n\t}\n\treturn applied;\n}\n/**\n* Scans the list starting from the given list head element and fixes items' types.\n*\n* @internal\n* @param listNodes The iterable of list nodes.\n* @param seenIds The set of already known IDs.\n* @param writer The model writer.\n* @returns Whether the model was modified.\n*/\nfunction fixListItemIds(listNodes, seenIds, writer) {\n\tconst visited = /* @__PURE__ */ new Set();\n\tlet applied = false;\n\tfor (const { node } of listNodes) {\n\t\tif (visited.has(node)) continue;\n\t\tlet listType = node.getAttribute(\"listType\");\n\t\tlet listItemId = node.getAttribute(\"listItemId\");\n\t\tif (seenIds.has(listItemId)) listItemId = ListItemUid.next();\n\t\tseenIds.add(listItemId);\n\t\tif (node.is(\"element\", \"listItem\")) {\n\t\t\tif (node.getAttribute(\"listItemId\") != listItemId) {\n\t\t\t\twriter.setAttribute(\"listItemId\", listItemId, node);\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const block of getListItemBlocks(node, { direction: \"forward\" })) {\n\t\t\tvisited.add(block);\n\t\t\tif (block.getAttribute(\"listType\") != listType) {\n\t\t\t\tlistItemId = ListItemUid.next();\n\t\t\t\tlistType = block.getAttribute(\"listType\");\n\t\t\t}\n\t\t\tif (block.getAttribute(\"listItemId\") != listItemId) {\n\t\t\t\twriter.setAttribute(\"listItemId\", listItemId, block);\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t}\n\t}\n\treturn applied;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Returns a consuming upcast converter for skip-level list item wrappers. It detects intermediate `<li>` elements\n* with `list-style-type:none` (generated by the skip-level downcast or by external sources) and consumes them\n* without producing a model element, so they don't end up as empty list items in the model.\n*\n* The wrapper `<li>` is consumed, but its children (nested lists) are converted normally. Because `getIndent()`\n* counts all ancestor `<li>` elements (including the consumed wrapper), nested items receive the correct indent\n* values that reflect the skip-level gap.\n*\n* Only `<li>` elements whose sole meaningful content is a nested `<ul>`/`<ol>` are treated as intermediate wrappers.\n* Anything else (text, paragraphs, custom elements, even an empty `<li>` with `list-style-type:none` carrying only\n* attributes) falls through to the regular list item upcast, so its data and attributes can be preserved by GHS\n* or other plugins.\n*\n* @internal\n*/\nfunction listItemSkipLevelConsumer() {\n\treturn (evt, data, conversionApi) => {\n\t\tconst viewItem = data.viewItem;\n\t\tif (viewItem.getStyle(\"list-style-type\") !== \"none\") return;\n\t\tif (!isSkipLevelWrapper(viewItem)) return;\n\t\tif (!conversionApi.consumable.consume(viewItem, { name: true })) return;\n\t\tconst { modelRange, modelCursor } = conversionApi.convertChildren(viewItem, data.modelCursor);\n\t\tdata.modelRange = modelRange;\n\t\tdata.modelCursor = modelCursor;\n\t};\n}\n/**\n* Checks whether a `<li>` view element is a skip-level intermediate wrapper, i.e. its only child is a nested\n* `<ul>`/`<ol>`. Any other content (text, `<br>`, `<p>`, custom elements, NBSP, etc.) disqualifies the element,\n* so it is upcast as a regular list item.\n*/\nfunction isSkipLevelWrapper(viewItem) {\n\tlet hasNestedList = false;\n\tfor (const child of viewItem.getChildren()) {\n\t\tif (child.is(\"element\", \"ul\") || child.is(\"element\", \"ol\")) {\n\t\t\thasNestedList = true;\n\t\t\tcontinue;\n\t\t}\n\t\treturn false;\n\t}\n\treturn hasNestedList;\n}\n/**\n* Returns the upcast converter for list items. It's supposed to work after the block converters (content inside list items) are converted.\n*\n* @internal\n*/\nfunction listItemUpcastConverter() {\n\treturn (evt, data, conversionApi) => {\n\t\tconst { writer, schema } = conversionApi;\n\t\tif (!data.modelRange) return;\n\t\tconst items = Array.from(data.modelRange.getItems({ shallow: true })).filter((item) => schema.checkAttribute(item, \"listItemId\"));\n\t\tif (!items.length) return;\n\t\tif (items.every((item) => item.hasAttribute(\"listItemId\"))) return;\n\t\tconst listItemId = data.viewItem.getAttribute(\"data-list-item-id\") || ListItemUid.next();\n\t\tconversionApi.consumable.consume(data.viewItem, { attributes: \"data-list-item-id\" });\n\t\tconst listIndent = getIndent(data.viewItem);\n\t\tlet listType = data.viewItem.parent && data.viewItem.parent.is(\"element\", \"ol\") ? \"numbered\" : \"bulleted\";\n\t\tconst firstItemListType = items[0].getAttribute(\"listType\");\n\t\tif (firstItemListType) listType = firstItemListType;\n\t\tconst attributes = {\n\t\t\tlistItemId,\n\t\t\tlistIndent,\n\t\t\tlistType\n\t\t};\n\t\tfor (const item of items) if (!item.hasAttribute(\"listItemId\")) writer.setAttributes(attributes, item);\n\t\tif (items.length > 1) {\n\t\t\tif (items[1].getAttribute(\"listItemId\") != attributes.listItemId) conversionApi.keepEmptyElement(items[0]);\n\t\t}\n\t};\n}\n/**\n* Returns a model document change:data event listener that triggers conversion of related items if needed.\n*\n* @internal\n* @param model The editor model.\n* @param editing The editing controller.\n* @param attributeNames The list of all model list attributes (including registered strategies).\n* @param listEditing The document list editing plugin.\n*/\nfunction reconvertItemsOnDataChange(model, editing, attributeNames, listEditing) {\n\treturn () => {\n\t\tconst changes = model.document.differ.getChanges();\n\t\tconst itemsToRefresh = [];\n\t\tconst itemToListHead = /* @__PURE__ */ new Set();\n\t\tconst changedItems = /* @__PURE__ */ new Set();\n\t\tconst visited = /* @__PURE__ */ new Set();\n\t\tfor (const entry of changes) if (entry.type == \"insert\" && entry.name != \"$text\") {\n\t\t\tfindAndAddListHeadToMap(entry.position, itemToListHead, visited);\n\t\t\tif (!entry.attributes.has(\"listItemId\")) findAndAddListHeadToMap(entry.position.getShiftedBy(entry.length), itemToListHead, visited);\n\t\t\telse changedItems.add(entry.position.nodeAfter);\n\t\t} else if (entry.type == \"remove\" && entry.attributes.has(\"listItemId\")) findAndAddListHeadToMap(entry.position, itemToListHead, visited);\n\t\telse if (entry.type == \"attribute\") {\n\t\t\tconst item = entry.range.start.nodeAfter;\n\t\t\tif (attributeNames.includes(entry.attributeKey)) {\n\t\t\t\tfindAndAddListHeadToMap(entry.range.start, itemToListHead, visited);\n\t\t\t\tif (entry.attributeNewValue === null) {\n\t\t\t\t\tfindAndAddListHeadToMap(entry.range.start.getShiftedBy(1), itemToListHead, visited);\n\t\t\t\t\tif (doesItemBlockRequiresRefresh(item)) itemsToRefresh.push(item);\n\t\t\t\t} else changedItems.add(item);\n\t\t\t} else if (isListItemBlock(item)) {\n\t\t\t\tif (doesItemBlockRequiresRefresh(item)) itemsToRefresh.push(item);\n\t\t\t}\n\t\t}\n\t\tfor (const listHead of itemToListHead.values()) itemsToRefresh.push(...collectListItemsToRefresh(listHead, changedItems));\n\t\tfor (const item of new Set(itemsToRefresh)) editing.reconvertItem(item);\n\t};\n\tfunction collectListItemsToRefresh(listHead, changedItems) {\n\t\tconst itemsToRefresh = [];\n\t\tconst visited = /* @__PURE__ */ new Set();\n\t\tconst stack = [];\n\t\tfor (const { node, previous } of new SiblingListBlocksIterator(listHead)) {\n\t\t\tif (visited.has(node)) continue;\n\t\t\tconst itemIndent = node.getAttribute(\"listIndent\");\n\t\t\tif (previous && itemIndent < previous.getAttribute(\"listIndent\")) stack.length = itemIndent + 1;\n\t\t\tstack[itemIndent] = {\n\t\t\t\tmodelAttributes: getListModelAttributes(node),\n\t\t\t\tmodelElement: node\n\t\t\t};\n\t\t\tfillStackForIntermediates(node, itemIndent, stack);\n\t\t\tconst blocks = getListItemBlocks(node, { direction: \"forward\" });\n\t\t\tfor (const block of blocks) {\n\t\t\t\tvisited.add(block);\n\t\t\t\tif (doesItemBlockRequiresRefresh(block, blocks)) itemsToRefresh.push(block);\n\t\t\t\telse if (doesItemWrappingRequiresRefresh(block, stack, changedItems)) itemsToRefresh.push(block);\n\t\t\t}\n\t\t}\n\t\treturn itemsToRefresh;\n\t}\n\tfunction getListModelAttributes(item) {\n\t\treturn Object.fromEntries(Array.from(item.getAttributes()).filter(([key]) => attributeNames.includes(key)));\n\t}\n\tfunction fillStackForIntermediates(node, itemIndent, stack) {\n\t\tfor (let i = itemIndent - 1; i >= 0; i--) {\n\t\t\tif (stack[i]) break;\n\t\t\tconst siblingAtIndent = findSiblingListItemAt(node, i);\n\t\t\tlet ancestorAtLowerIndent = null;\n\t\t\tif (!siblingAtIndent) {\n\t\t\t\tfor (let k = i - 1; k >= 0; k--) if (stack[k]) {\n\t\t\t\t\tancestorAtLowerIndent = stack[k].modelElement;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst referenceItem = siblingAtIndent || ancestorAtLowerIndent || node;\n\t\t\tstack[i] = {\n\t\t\t\tmodelAttributes: {\n\t\t\t\t\t...getListModelAttributes(referenceItem),\n\t\t\t\t\tlistItemId: `list-item-skip-${i}`,\n\t\t\t\t\tlistIndent: i\n\t\t\t\t},\n\t\t\t\tmodelElement: referenceItem\n\t\t\t};\n\t\t}\n\t}\n\tfunction doesItemBlockRequiresRefresh(item, blocks) {\n\t\tconst viewElement = editing.mapper.toViewElement(item);\n\t\tif (!viewElement) return false;\n\t\tif (isItemBlockInsideStructureSlot(viewElement)) return true;\n\t\tif (listEditing.fire(\"checkElement\", {\n\t\t\tmodelElement: item,\n\t\t\tviewElement\n\t\t})) return true;\n\t\tif (!item.is(\"element\", \"paragraph\") && !item.is(\"element\", \"listItem\")) return false;\n\t\tconst useBogus = shouldUseBogusParagraph(item, attributeNames, blocks);\n\t\tif (useBogus && viewElement.is(\"element\", \"p\")) return true;\n\t\telse if (!useBogus && viewElement.is(\"element\", \"span\")) return true;\n\t\treturn false;\n\t}\n\tfunction isItemBlockInsideStructureSlot(viewElement) {\n\t\tviewElement = viewElement.parent;\n\t\twhile (viewElement.is(\"attributeElement\") && [\n\t\t\t\"ol\",\n\t\t\t\"ul\",\n\t\t\t\"li\"\n\t\t].includes(viewElement.name)) viewElement = viewElement.parent;\n\t\tif (viewElement.getCustomProperty(\"$structureSlotParent\") && !editing.mapper.toModelElement(viewElement)) return true;\n\t\treturn false;\n\t}\n\tfunction doesItemWrappingRequiresRefresh(item, stack, changedItems) {\n\t\tif (changedItems.has(item)) return false;\n\t\tconst viewElement = editing.mapper.toViewElement(item);\n\t\tlet indent = stack.length - 1;\n\t\tfor (let element = viewElement.parent; !element.is(\"editableElement\"); element = element.parent) {\n\t\t\tconst isListItemElement = isListItemView(element);\n\t\t\tconst isListElement = isListView(element);\n\t\t\tif (!isListElement && !isListItemElement) continue;\n\t\t\t/* v8 ignore next -- Defensive guard for transient skip-level list stack gaps. */\n\t\t\tif (stack[indent]) {\n\t\t\t\tconst eventName = `checkAttributes:${isListItemElement ? \"item\" : \"list\"}`;\n\t\t\t\tif (listEditing.fire(eventName, {\n\t\t\t\t\tviewElement: element,\n\t\t\t\t\tmodelAttributes: stack[indent].modelAttributes,\n\t\t\t\t\tmodelReferenceElement: stack[indent].modelElement\n\t\t\t\t})) break;\n\t\t\t}\n\t\t\tif (isListElement) {\n\t\t\t\tindent--;\n\t\t\t\tif (indent < 0) return false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n/**\n* Returns the list item downcast converter.\n*\n* @internal\n* @param attributeNames A list of attribute names that should be converted if they are set.\n* @param strategies The strategies.\n* @param model The model.\n*/\nfunction listItemDowncastConverter(attributeNames, strategies, model, { dataPipeline, enableSkipLevelLists }) {\n\tconst consumer = createAttributesConsumer(attributeNames, strategies);\n\treturn (evt, data, conversionApi) => {\n\t\tconst { writer, mapper, consumable } = conversionApi;\n\t\tconst listItem = data.item;\n\t\tif (!attributeNames.includes(data.attributeKey)) return;\n\t\tif (!consumer(listItem, consumable)) return;\n\t\tconst options = {\n\t\t\t...conversionApi.options,\n\t\t\tdataPipeline,\n\t\t\tenableSkipLevelLists\n\t\t};\n\t\tconst viewElement = findMappedViewElement(listItem, mapper, model, writer);\n\t\tremoveCustomMarkerElements(viewElement, writer, mapper);\n\t\tunwrapListItemBlock(viewElement, writer);\n\t\twrapListItemBlock(listItem, insertCustomMarkerElements(listItem, viewElement, strategies, writer, options), strategies, writer, options);\n\t};\n}\n/**\n* The 'remove' downcast converter for custom markers.\n*\n* @internal\n*/\nfunction listItemDowncastRemoveConverter(schema) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst { writer, mapper } = conversionApi;\n\t\tconst elementName = evt.name.split(\":\")[1];\n\t\tif (!schema.checkAttribute(elementName, \"listItemId\")) return;\n\t\tconst viewStart = mapper.toViewPosition(data.position);\n\t\tconst modelEnd = data.position.getShiftedBy(data.length);\n\t\tconst viewEnd = mapper.toViewPosition(modelEnd, { isPhantom: true });\n\t\tconst viewElement = writer.createRange(viewStart, viewEnd).getTrimmed().end.nodeBefore;\n\t\t/* istanbul ignore next -- @preserve */\n\t\tif (!viewElement) return;\n\t\tremoveCustomMarkerElements(viewElement, writer, mapper);\n\t};\n}\n/**\n* Returns the bogus paragraph view element creator. A bogus paragraph is used if a list item contains only a single block or nested list.\n*\n* @internal\n* @param attributeNames The list of all model list attributes (including registered strategies).\n*/\nfunction bogusParagraphCreator(attributeNames, { dataPipeline } = {}) {\n\treturn (modelElement, { writer }) => {\n\t\tif (!shouldUseBogusParagraph(modelElement, attributeNames)) return null;\n\t\tif (!dataPipeline) return writer.createContainerElement(\"span\", { class: \"ck-list-bogus-paragraph\" });\n\t\tconst viewElement = writer.createContainerElement(\"p\");\n\t\twriter.setCustomProperty(\"dataPipeline:transparentRendering\", true, viewElement);\n\t\treturn viewElement;\n\t};\n}\n/**\n* Helper for mapping mode to view elements. It's using positions mapping instead of mapper.toViewElement( element )\n* to find outermost view element. This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n*\n* @internal\n* @param element The model element.\n* @param mapper The mapper instance.\n* @param model The model.\n* @param writer The view downcast writer.\n*/\nfunction findMappedViewElement(element, mapper, model, writer) {\n\tconst modelRange = model.createRangeOn(element);\n\tconst viewWalker = mapper.toViewRange(modelRange).getTrimmed().getWalker();\n\tfor (const { item } of viewWalker) if (item.is(\"element\") && item.getCustomProperty(\"listItemMarker\")) viewWalker.jumpTo(writer.createPositionAfter(item));\n\telse if (item.is(\"element\") && !item.getCustomProperty(\"listItemWrapper\")) return item;\n}\n/**\n* The model to view custom position mapping for cases when marker is injected at the beginning of a block.\n*\n* @internal\n*/\nfunction createModelToViewPositionMapper(strategies, view) {\n\treturn (evt, data) => {\n\t\tif (data.modelPosition.offset > 0) return;\n\t\tconst positionParent = data.modelPosition.parent;\n\t\tif (!isListItemBlock(positionParent)) return;\n\t\tif (!strategies.some((strategy) => strategy.scope == \"itemMarker\" && strategy.canInjectMarkerIntoElement && strategy.canInjectMarkerIntoElement(positionParent))) return;\n\t\tconst viewElement = data.mapper.toViewElement(positionParent);\n\t\tconst viewRange = view.createRangeIn(viewElement);\n\t\tconst viewWalker = viewRange.getWalker();\n\t\tlet positionAfterLastMarker = viewRange.start;\n\t\tfor (const { item } of viewWalker) {\n\t\t\tif (item.is(\"element\") && data.mapper.toModelElement(item) || item.is(\"$textProxy\")) break;\n\t\t\t/* v8 ignore next -- Depends on custom marker internals in mapper position translation. */\n\t\t\tif (item.is(\"element\") && item.getCustomProperty(\"listItemMarker\")) {\n\t\t\t\tpositionAfterLastMarker = view.createPositionAfter(item);\n\t\t\t\tviewWalker.skip(({ previousPosition }) => !previousPosition.isEqual(positionAfterLastMarker));\n\t\t\t}\n\t\t}\n\t\tdata.viewPosition = positionAfterLastMarker;\n\t};\n}\n/**\n* Removes a custom marker elements and item wrappers related to that marker.\n*/\nfunction removeCustomMarkerElements(viewElement, viewWriter, mapper) {\n\twhile (viewElement.parent.is(\"attributeElement\") && viewElement.parent.getCustomProperty(\"listItemWrapper\")) viewWriter.unwrap(viewWriter.createRangeOn(viewElement), viewElement.parent);\n\tconst markersToRemove = [];\n\tcollectMarkersToRemove(viewWriter.createPositionBefore(viewElement).getWalker({ direction: \"backward\" }));\n\tcollectMarkersToRemove(viewWriter.createRangeIn(viewElement).getWalker());\n\tfor (const marker of markersToRemove) viewWriter.remove(marker);\n\tfunction collectMarkersToRemove(viewWalker) {\n\t\tfor (const { item } of viewWalker) {\n\t\t\tif (item.is(\"element\") && mapper.toModelElement(item)) break;\n\t\t\tif (item.is(\"element\") && item.getCustomProperty(\"listItemMarker\")) markersToRemove.push(item);\n\t\t}\n\t}\n}\n/**\n* Inserts a custom marker elements and wraps first block of a list item if marker requires it.\n*/\nfunction insertCustomMarkerElements(listItem, viewElement, strategies, writer, { dataPipeline }) {\n\tlet viewRange = writer.createRangeOn(viewElement);\n\tif (!isFirstBlockOfListItem(listItem)) return viewRange;\n\tfor (const strategy of strategies) {\n\t\tif (strategy.scope != \"itemMarker\") continue;\n\t\tconst markerElement = strategy.createElement(writer, listItem, { dataPipeline });\n\t\tif (!markerElement) continue;\n\t\twriter.setCustomProperty(\"listItemMarker\", true, markerElement);\n\t\tif (strategy.canInjectMarkerIntoElement && strategy.canInjectMarkerIntoElement(listItem)) writer.insert(writer.createPositionAt(viewElement, 0), markerElement);\n\t\telse {\n\t\t\twriter.insert(viewRange.start, markerElement);\n\t\t\tviewRange = writer.createRange(writer.createPositionBefore(markerElement), writer.createPositionAfter(viewElement));\n\t\t}\n\t\tif (!strategy.createWrapperElement || !strategy.canWrapElement) continue;\n\t\tconst wrapper = strategy.createWrapperElement(writer, listItem, { dataPipeline });\n\t\twriter.setCustomProperty(\"listItemWrapper\", true, wrapper);\n\t\tif (strategy.canWrapElement(listItem)) viewRange = writer.wrap(viewRange, wrapper);\n\t\telse {\n\t\t\tviewRange = writer.wrap(writer.createRangeOn(markerElement), wrapper);\n\t\t\tviewRange = writer.createRange(viewRange.start, writer.createPositionAfter(viewElement));\n\t\t}\n\t}\n\treturn viewRange;\n}\n/**\n* Unwraps all ol, ul, and li attribute elements that are wrapping the provided view element.\n*/\nfunction unwrapListItemBlock(viewElement, viewWriter) {\n\tlet attributeElement = viewElement.parent;\n\twhile (attributeElement.is(\"attributeElement\") && [\n\t\t\"ul\",\n\t\t\"ol\",\n\t\t\"li\"\n\t].includes(attributeElement.name)) {\n\t\tconst parentElement = attributeElement.parent;\n\t\tviewWriter.unwrap(viewWriter.createRangeOn(viewElement), attributeElement);\n\t\tattributeElement = parentElement;\n\t}\n}\n/**\n* Wraps the given list item with appropriate attribute elements for ul, ol, and li.\n*\n* For skip-level lists (where indent gaps exist, e.g. indent 0 → indent 2), this function\n* generates intermediate wrapper pairs (ul/ol + li) at each missing level. These intermediate\n* wrappers are invisible (`list-style-type: none` on the li). Scope `'list'` strategies are\n* applied so the wrapper element (ul/ol) carries the same classes and styles as real list\n* wrappers, while scope `'item'` strategies are skipped since there is no model element\n* backing the intermediate level.\n*/\nfunction wrapListItemBlock(listItem, viewRange, strategies, writer, options) {\n\tif (!listItem.hasAttribute(\"listIndent\")) return;\n\tconst listItemIndent = listItem.getAttribute(\"listIndent\");\n\tconst enableSkipLevelLists = options.enableSkipLevelLists;\n\tlet currentListItem = listItem;\n\tfor (let indent = listItemIndent; indent >= 0; indent--) {\n\t\tconst isIntermediate = currentListItem.getAttribute(\"listIndent\") !== indent;\n\t\tif (isIntermediate) {\n\t\t\tconst referenceItem = findSiblingListItemAt(listItem, indent) || currentListItem;\n\t\t\tconst listType = referenceItem.getAttribute(\"listType\");\n\t\t\tconst listItemViewElement = createListItemElement(writer, indent, `list-item-skip-${indent}`);\n\t\t\tconst listViewElement = createListElement(writer, indent, listType);\n\t\t\twriter.setStyle(\"list-style-type\", \"none\", listItemViewElement);\n\t\t\tfor (const strategy of strategies) if (strategy.scope == \"list\" && referenceItem.hasAttribute(strategy.attributeName)) strategy.setAttributeOnDowncast(writer, referenceItem.getAttribute(strategy.attributeName), listViewElement, options, referenceItem);\n\t\t\tviewRange = writer.wrap(viewRange, listItemViewElement);\n\t\t\tviewRange = writer.wrap(viewRange, listViewElement);\n\t\t} else {\n\t\t\tconst listItemViewElement = createListItemElement(writer, indent, currentListItem.getAttribute(\"listItemId\"));\n\t\t\tconst listViewElement = createListElement(writer, indent, currentListItem.getAttribute(\"listType\"));\n\t\t\tfor (const strategy of strategies) if ((strategy.scope == \"list\" || strategy.scope == \"item\") && currentListItem.hasAttribute(strategy.attributeName)) strategy.setAttributeOnDowncast(writer, currentListItem.getAttribute(strategy.attributeName), strategy.scope == \"list\" ? listViewElement : listItemViewElement, options, currentListItem);\n\t\t\tviewRange = writer.wrap(viewRange, listItemViewElement);\n\t\t\tviewRange = writer.wrap(viewRange, listViewElement);\n\t\t}\n\t\tif (indent == 0) break;\n\t\tif (!isIntermediate) {\n\t\t\tconst nextListItem = ListWalker.first(currentListItem, { lowerIndent: true });\n\t\t\tif (nextListItem) currentListItem = nextListItem;\n\t\t\telse if (!enableSkipLevelLists) break;\n\t\t}\n\t}\n}\n/**\n* Walks forward from the given list item through model siblings to find the first list item block\n* at exactly the specified indent level. Stops when it encounters a non-list block or a list item\n* at a lower indent (which means we left the current subtree).\n*/\nfunction findSiblingListItemAt(listItem, targetIndent) {\n\tlet node = listItem.nextSibling;\n\twhile (node && isListItemBlock(node)) {\n\t\tconst indent = node.getAttribute(\"listIndent\");\n\t\tif (indent < targetIndent) return null;\n\t\tif (indent === targetIndent) return node;\n\t\tnode = node.nextSibling;\n\t}\n\treturn null;\n}\nfunction createAttributesConsumer(attributeNames, strategies) {\n\tconst nonConsumingAttributes = strategies.filter((strategy) => strategy.consume === false).map((strategy) => strategy.attributeName);\n\treturn (node, consumable) => {\n\t\tconst events = [];\n\t\tfor (const attributeName of attributeNames) if (node.hasAttribute(attributeName) && !nonConsumingAttributes.includes(attributeName)) events.push(`attribute:${attributeName}`);\n\t\tif (!events.every((event) => consumable.test(node, event) !== false)) return false;\n\t\tevents.forEach((event) => consumable.consume(node, event));\n\t\treturn true;\n\t};\n}\nfunction shouldUseBogusParagraph(item, attributeNames, blocks = getAllListItemBlocks(item)) {\n\tif (!isListItemBlock(item)) return false;\n\tfor (const attributeKey of item.getAttributeKeys()) {\n\t\tif (attributeKey.startsWith(\"selection:\") || attributeKey == \"htmlEmptyBlock\") continue;\n\t\tif (!attributeNames.includes(attributeKey)) return false;\n\t}\n\treturn blocks.length < 2;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/list/listediting\n*/\n/**\n* A list of base list model attributes.\n*/\nconst LIST_BASE_ATTRIBUTES = [\n\t\"listType\",\n\t\"listIndent\",\n\t\"listItemId\"\n];\n/**\n* The editing part of the document-list feature. It handles creating, editing and removing lists and list items.\n*/\nvar ListEditing = class extends Plugin {\n\t/**\n\t* The list of registered downcast strategies.\n\t*/\n\t_downcastStrategies = [];\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListEditing\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [\n\t\t\tEnter,\n\t\t\tDelete,\n\t\t\tListUtils,\n\t\t\tClipboardPipeline,\n\t\t\tListFormatting\n\t\t];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(editor) {\n\t\tsuper(editor);\n\t\teditor.config.define(\"list.multiBlock\", true);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst multiBlock = editor.config.get(\"list.multiBlock\");\n\t\tif (editor.plugins.has(\"LegacyListEditing\"))\n /**\n\t\t* The `List` feature cannot be loaded together with the `LegacyList` plugin.\n\t\t*\n\t\t* @error list-feature-conflict\n\t\t* @param {string} conflictPlugin Name of the plugin.\n\t\t*/\n\t\tthrow new CKEditorError(\"list-feature-conflict\", this, { conflictPlugin: \"LegacyListEditing\" });\n\t\tmodel.schema.register(\"$listItem\", { allowAttributes: LIST_BASE_ATTRIBUTES });\n\t\tif (multiBlock) {\n\t\t\tmodel.schema.extend(\"$container\", { allowAttributesOf: \"$listItem\" });\n\t\t\tmodel.schema.extend(\"$block\", { allowAttributesOf: \"$listItem\" });\n\t\t\tmodel.schema.extend(\"$blockObject\", { allowAttributesOf: \"$listItem\" });\n\t\t} else model.schema.register(\"listItem\", {\n\t\t\tinheritAllFrom: \"$block\",\n\t\t\tallowAttributesOf: \"$listItem\"\n\t\t});\n\t\tfor (const attribute of LIST_BASE_ATTRIBUTES) model.schema.setAttributeProperties(attribute, { copyOnReplace: true });\n\t\teditor.commands.add(\"numberedList\", new ListCommand(editor, \"numbered\"));\n\t\teditor.commands.add(\"bulletedList\", new ListCommand(editor, \"bulleted\"));\n\t\teditor.commands.add(\"customNumberedList\", new ListCommand(editor, \"customNumbered\", { multiLevel: true }));\n\t\teditor.commands.add(\"customBulletedList\", new ListCommand(editor, \"customBulleted\", { multiLevel: true }));\n\t\teditor.commands.add(\"indentList\", new ListIndentCommand(editor, \"forward\"));\n\t\teditor.commands.add(\"outdentList\", new ListIndentCommand(editor, \"backward\"));\n\t\teditor.commands.add(\"splitListItemBefore\", new ListSplitCommand(editor, \"before\"));\n\t\teditor.commands.add(\"splitListItemAfter\", new ListSplitCommand(editor, \"after\"));\n\t\tif (multiBlock) {\n\t\t\teditor.commands.add(\"mergeListItemBackward\", new ListMergeCommand(editor, \"backward\"));\n\t\t\teditor.commands.add(\"mergeListItemForward\", new ListMergeCommand(editor, \"forward\"));\n\t\t}\n\t\tthis._setupDeleteIntegration();\n\t\tthis._setupEnterIntegration();\n\t\tthis._setupTabIntegration();\n\t\tthis._setupClipboardIntegration();\n\t\tthis._setupAccessibilityIntegration();\n\t\tthis._setupListItemIdConversionStrategy();\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tafterInit() {\n\t\tconst commands = this.editor.commands;\n\t\tconst indent = commands.get(\"indent\");\n\t\tconst outdent = commands.get(\"outdent\");\n\t\tif (indent) indent.registerChildCommand(commands.get(\"indentList\"), { priority: \"high\" });\n\t\tif (outdent) outdent.registerChildCommand(commands.get(\"outdentList\"), { priority: \"lowest\" });\n\t\tthis._setupModelPostFixing();\n\t\tthis._setupConversion();\n\t}\n\t/**\n\t* Registers a downcast strategy.\n\t*\n\t* **Note**: Strategies must be registered in the `Plugin#init()` phase so that it can be applied\n\t* in the `ListEditing#afterInit()`.\n\t*\n\t* @param strategy The downcast strategy to register.\n\t*/\n\tregisterDowncastStrategy(strategy) {\n\t\tthis._downcastStrategies.push(strategy);\n\t}\n\t/**\n\t* Returns list of model attribute names that should affect downcast conversion.\n\t*/\n\tgetListAttributeNames() {\n\t\treturn [...LIST_BASE_ATTRIBUTES, ...this._downcastStrategies.map((strategy) => strategy.attributeName)];\n\t}\n\t/**\n\t* Attaches the listener to the {@link module:engine/view/document~ViewDocument#event:delete} event and handles backspace/delete\n\t* keys in and around document lists.\n\t*/\n\t_setupDeleteIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst mergeBackwardCommand = editor.commands.get(\"mergeListItemBackward\");\n\t\tconst mergeForwardCommand = editor.commands.get(\"mergeListItemForward\");\n\t\tthis.listenTo(editor.editing.view.document, \"delete\", (evt, data) => {\n\t\t\tconst selection = editor.model.document.selection;\n\t\t\tif (getSelectedBlockObject(editor.model)) return;\n\t\t\teditor.model.change(() => {\n\t\t\t\tconst firstPosition = selection.getFirstPosition();\n\t\t\t\tif (selection.isCollapsed && data.direction == \"backward\") {\n\t\t\t\t\tif (!firstPosition.isAtStart) return;\n\t\t\t\t\tconst positionParent = firstPosition.parent;\n\t\t\t\t\tif (!isListItemBlock(positionParent)) return;\n\t\t\t\t\tconst previousBlock = ListWalker.first(positionParent, {\n\t\t\t\t\t\tsameAttributes: \"listType\",\n\t\t\t\t\t\tsameIndent: true\n\t\t\t\t\t});\n\t\t\t\t\tconst hasNoMergeTarget = positionParent.getAttribute(\"listIndent\") === 0 || !isListItemBlock(positionParent.previousSibling);\n\t\t\t\t\tif (!previousBlock && hasNoMergeTarget) {\n\t\t\t\t\t\tif (!isLastBlockOfListItem(positionParent)) editor.execute(\"splitListItemAfter\");\n\t\t\t\t\t\teditor.execute(\"outdentList\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!mergeBackwardCommand || !mergeBackwardCommand.isEnabled) return;\n\t\t\t\t\t\tmergeBackwardCommand.execute({ shouldMergeOnBlocksContentLevel: shouldMergeOnBlocksContentLevel(editor.model, \"backward\") });\n\t\t\t\t\t}\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t} else {\n\t\t\t\t\tif (selection.isCollapsed && !selection.getLastPosition().isAtEnd) return;\n\t\t\t\t\tif (!mergeForwardCommand || !mergeForwardCommand.isEnabled) return;\n\t\t\t\t\tmergeForwardCommand.execute({ shouldMergeOnBlocksContentLevel: shouldMergeOnBlocksContentLevel(editor.model, \"forward\") });\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t});\n\t\t}, { context: \"li\" });\n\t}\n\t/**\n\t* Attaches a listener to the {@link module:engine/view/document~ViewDocument#event:enter} event and handles enter key press\n\t* in document lists.\n\t*/\n\t_setupEnterIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst commands = editor.commands;\n\t\tconst enterCommand = commands.get(\"enter\");\n\t\tthis.listenTo(editor.editing.view.document, \"enter\", (evt, data) => {\n\t\t\tconst doc = model.document;\n\t\t\tconst positionParent = doc.selection.getFirstPosition().parent;\n\t\t\tif (doc.selection.isCollapsed && isListItemBlock(positionParent) && positionParent.isEmpty && !data.isSoft) {\n\t\t\t\tconst isFirstBlock = isFirstBlockOfListItem(positionParent);\n\t\t\t\tconst isLastBlock = isLastBlockOfListItem(positionParent);\n\t\t\t\tif (isFirstBlock && isLastBlock) {\n\t\t\t\t\teditor.execute(\"outdentList\");\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t} else if (isFirstBlock && !isLastBlock) {\n\t\t\t\t\teditor.execute(\"splitListItemAfter\");\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t} else if (isLastBlock) {\n\t\t\t\t\teditor.execute(\"splitListItemBefore\");\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t}, { context: \"li\" });\n\t\tthis.listenTo(enterCommand, \"afterExecute\", () => {\n\t\t\tconst splitCommand = commands.get(\"splitListItemBefore\");\n\t\t\tsplitCommand.refresh();\n\t\t\tif (!splitCommand.isEnabled) return;\n\t\t\tconst positionParent = editor.model.document.selection.getLastPosition().parent;\n\t\t\tif (getAllListItemBlocks(positionParent).length === 2) splitCommand.execute();\n\t\t});\n\t}\n\t/**\n\t* Attaches a listener to the {@link module:engine/view/document~ViewDocument#event:tab} event and handles tab key and tab+shift keys\n\t* presses in document lists.\n\t*/\n\t_setupTabIntegration() {\n\t\tconst editor = this.editor;\n\t\tthis.listenTo(editor.editing.view.document, \"tab\", (evt, data) => {\n\t\t\tconst commandName = data.shiftKey ? \"outdentList\" : \"indentList\";\n\t\t\tif (this.editor.commands.get(commandName).isEnabled) {\n\t\t\t\teditor.execute(commandName);\n\t\t\t\tdata.stopPropagation();\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: \"li\" });\n\t}\n\t/**\n\t* Registers the conversion helpers for the document-list feature.\n\t*/\n\t_setupConversion() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst attributeNames = this.getListAttributeNames();\n\t\tconst multiBlock = editor.config.get(\"list.multiBlock\");\n\t\tconst elementName = multiBlock ? \"paragraph\" : \"listItem\";\n\t\tconst enableSkipLevelLists = !!editor.config.get(\"list.enableSkipLevelLists\");\n\t\teditor.conversion.for(\"upcast\").elementToElement({\n\t\t\tview: \"li\",\n\t\t\tmodel: (viewElement, { writer }) => writer.createElement(elementName, { listType: \"\" })\n\t\t}).elementToElement({\n\t\t\tview: \"p\",\n\t\t\tmodel: (viewElement, { writer }) => {\n\t\t\t\tif (viewElement.parent && viewElement.parent.is(\"element\", \"li\")) return writer.createElement(elementName, { listType: \"\" });\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\tconverterPriority: \"high\"\n\t\t}).add((dispatcher) => {\n\t\t\tdispatcher.on(\"element:p\", (evt, data, conversionApi) => {\n\t\t\t\tconst viewElement = data.viewItem;\n\t\t\t\tif (!viewElement.parent || !viewElement.parent.is(\"element\", \"li\")) return;\n\t\t\t\tif (viewElement.isEmpty) return;\n\t\t\t\tif (!viewElement.getAttributeKeys().next().done) return;\n\t\t\t\tfor (const sibling of viewElement.parent.getChildren()) {\n\t\t\t\t\tif (sibling === viewElement) continue;\n\t\t\t\t\tif (sibling.is(\"element\", \"ol\") || sibling.is(\"element\", \"ul\")) continue;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconversionApi.consumable.consume(viewElement, { name: true });\n\t\t\t\tconst { modelRange, modelCursor } = conversionApi.convertChildren(viewElement, data.modelCursor);\n\t\t\t\tdata.modelRange = modelRange;\n\t\t\t\tdata.modelCursor = modelCursor;\n\t\t\t}, { priority: \"highest\" });\n\t\t\tif (enableSkipLevelLists) dispatcher.on(\"element:li\", listItemSkipLevelConsumer(), { priority: \"high\" });\n\t\t\tdispatcher.on(\"element:li\", listItemUpcastConverter());\n\t\t});\n\t\tif (!multiBlock) editor.conversion.for(\"downcast\").elementToElement({\n\t\t\tmodel: \"listItem\",\n\t\t\tview: \"p\"\n\t\t});\n\t\teditor.conversion.for(\"editingDowncast\").elementToElement({\n\t\t\tmodel: elementName,\n\t\t\tview: bogusParagraphCreator(attributeNames),\n\t\t\tconverterPriority: \"high\"\n\t\t}).add((dispatcher) => {\n\t\t\tdispatcher.on(\"attribute\", listItemDowncastConverter(attributeNames, this._downcastStrategies, model, { enableSkipLevelLists }));\n\t\t\tdispatcher.on(\"remove\", listItemDowncastRemoveConverter(model.schema));\n\t\t});\n\t\teditor.conversion.for(\"dataDowncast\").elementToElement({\n\t\t\tmodel: elementName,\n\t\t\tview: bogusParagraphCreator(attributeNames, { dataPipeline: true }),\n\t\t\tconverterPriority: \"high\"\n\t\t}).add((dispatcher) => {\n\t\t\tdispatcher.on(\"attribute\", listItemDowncastConverter(attributeNames, this._downcastStrategies, model, {\n\t\t\t\tdataPipeline: true,\n\t\t\t\tenableSkipLevelLists\n\t\t\t}));\n\t\t});\n\t\tconst modelToViewPositionMapper = createModelToViewPositionMapper(this._downcastStrategies, editor.editing.view);\n\t\teditor.editing.mapper.on(\"modelToViewPosition\", modelToViewPositionMapper);\n\t\teditor.data.mapper.on(\"modelToViewPosition\", modelToViewPositionMapper);\n\t\tthis.listenTo(model.document, \"change:data\", reconvertItemsOnDataChange(model, editor.editing, attributeNames, this), { priority: \"high\" });\n\t\tthis.on(\"checkAttributes:item\", (evt, { viewElement, modelAttributes }) => {\n\t\t\tif (viewElement.id != modelAttributes.listItemId) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t});\n\t\tthis.on(\"checkAttributes:list\", (evt, { viewElement, modelAttributes }) => {\n\t\t\tif (viewElement.name != getViewElementNameForListType(modelAttributes.listType) || viewElement.id != getViewElementIdForListType(modelAttributes.listType, modelAttributes.listIndent)) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* Registers model post-fixers.\n\t*/\n\t_setupModelPostFixing() {\n\t\tconst model = this.editor.model;\n\t\tconst attributeNames = this.getListAttributeNames();\n\t\tmodel.document.registerPostFixer((writer) => modelChangePostFixer$1(model, writer, attributeNames, this));\n\t\tif (!this.editor.config.get(\"list.enableSkipLevelLists\")) this.on(\"postFixer\", (evt, { listNodes, writer }) => {\n\t\t\tevt.return = fixListIndents(listNodes, writer) || evt.return;\n\t\t}, { priority: \"high\" });\n\t\tthis.on(\"postFixer\", (evt, { listNodes, writer, seenIds }) => {\n\t\t\tevt.return = fixListItemIds(listNodes, seenIds, writer) || evt.return;\n\t\t}, { priority: \"high\" });\n\t}\n\t/**\n\t* Integrates the feature with the clipboard via {@link module:engine/model/model~Model#insertContent} and\n\t* {@link module:engine/model/model~Model#getSelectedContent}.\n\t*/\n\t_setupClipboardIntegration() {\n\t\tconst model = this.editor.model;\n\t\tconst clipboardPipeline = this.editor.plugins.get(\"ClipboardPipeline\");\n\t\tthis.listenTo(model, \"insertContent\", createModelIndentPasteFixer(model), { priority: \"high\" });\n\t\tthis.listenTo(clipboardPipeline, \"outputTransformation\", (evt, data) => {\n\t\t\tmodel.change((writer) => {\n\t\t\t\tconst allContentChildren = Array.from(data.content.getChildren());\n\t\t\t\tconst lastItem = allContentChildren[allContentChildren.length - 1];\n\t\t\t\tif (allContentChildren.length > 1 && lastItem.is(\"element\") && lastItem.isEmpty) {\n\t\t\t\t\tif (allContentChildren.slice(0, -1).every(isListItemBlock)) writer.remove(lastItem);\n\t\t\t\t}\n\t\t\t\tif (data.method == \"copy\" || data.method == \"cut\") {\n\t\t\t\t\tconst allChildren = Array.from(data.content.getChildren());\n\t\t\t\t\t/* v8 ignore next -- Clipboard output normally reaches this cleanup only for selected single list items. */\n\t\t\t\t\tif (isSingleListItem(allChildren)) removeListAttributes(allChildren, writer, this.getListAttributeNames());\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\t/**\n\t* Informs editor accessibility features about keystrokes brought by the plugin.\n\t*/\n\t_setupAccessibilityIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\teditor.accessibility.addKeystrokeInfoGroup({\n\t\t\tid: \"list\",\n\t\t\tlabel: t(\"Keystrokes that can be used in a list\"),\n\t\t\tkeystrokes: [{\n\t\t\t\tlabel: t(\"Increase list item indent\"),\n\t\t\t\tkeystroke: \"Tab\"\n\t\t\t}, {\n\t\t\t\tlabel: t(\"Decrease list item indent\"),\n\t\t\t\tkeystroke: \"Shift+Tab\"\n\t\t\t}]\n\t\t});\n\t}\n\t/**\n\t* Convert `listItemId` attribute to `data-list-item-id` attribute on the view element in both downcast pipelines.\n\t*/\n\t_setupListItemIdConversionStrategy() {\n\t\tthis.registerDowncastStrategy({\n\t\t\tscope: \"item\",\n\t\t\tattributeName: \"listItemId\",\n\t\t\tsetAttributeOnDowncast(writer, attributeValue, viewElement, options) {\n\t\t\t\tif (options && (options.skipListItemIds || options.isClipboardPipeline)) return;\n\t\t\t\twriter.setAttribute(\"data-list-item-id\", attributeValue, viewElement);\n\t\t\t}\n\t\t});\n\t}\n};\n/**\n* Post-fixer that reacts to changes on document and fixes incorrect model states (invalid `listItemId` and `listIndent` values).\n*\n* In the example below, there is a correct list structure.\n* Then the middle element is removed so the list structure will become incorrect:\n*\n* ```xml\n* <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n* <paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=1>Item 2</paragraph> <--- this is removed.\n* <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>Item 3</paragraph>\n* ```\n*\n* The list structure after the middle element is removed:\n*\n* ```xml\n* <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n* <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>Item 3</paragraph>\n* ```\n*\n* Should become:\n*\n* ```xml\n* <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n* <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=1>Item 3</paragraph> <--- note that indent got post-fixed.\n* ```\n*\n* @param model The data model.\n* @param writer The writer to do changes with.\n* @param attributeNames The list of all model list attributes (including registered strategies).\n* @param ListEditing The document list editing plugin.\n* @returns `true` if any change has been applied, `false` otherwise.\n*/\nfunction modelChangePostFixer$1(model, writer, attributeNames, listEditing) {\n\tconst changes = model.document.differ.getChanges();\n\tconst visited = /* @__PURE__ */ new Set();\n\tconst itemToListHead = /* @__PURE__ */ new Set();\n\tconst multiBlock = listEditing.editor.config.get(\"list.multiBlock\");\n\tlet applied = false;\n\tfor (const entry of changes) {\n\t\tif (entry.type == \"insert\" && entry.name != \"$text\") {\n\t\t\tconst item = entry.position.nodeAfter;\n\t\t\tif (!model.schema.checkAttribute(item, \"listItemId\")) {\n\t\t\t\tfor (const attributeName of Array.from(item.getAttributeKeys())) if (attributeNames.includes(attributeName)) {\n\t\t\t\t\twriter.removeAttribute(attributeName, item);\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfindAndAddListHeadToMap(entry.position, itemToListHead, visited);\n\t\t\tif (!entry.attributes.has(\"listItemId\")) findAndAddListHeadToMap(entry.position.getShiftedBy(entry.length), itemToListHead, visited);\n\t\t\tfor (const { item: innerItem, previousPosition } of model.createRangeIn(item)) if (isListItemBlock(innerItem)) findAndAddListHeadToMap(previousPosition, itemToListHead, visited);\n\t\t} else if (entry.type == \"remove\") findAndAddListHeadToMap(entry.position, itemToListHead, visited);\n\t\telse if (entry.type == \"attribute\" && attributeNames.includes(entry.attributeKey)) {\n\t\t\tfindAndAddListHeadToMap(entry.range.start, itemToListHead, visited);\n\t\t\tif (entry.attributeNewValue === null) findAndAddListHeadToMap(entry.range.start.getShiftedBy(1), itemToListHead, visited);\n\t\t}\n\t\tif (!multiBlock && entry.type == \"attribute\" && LIST_BASE_ATTRIBUTES.includes(entry.attributeKey)) {\n\t\t\tconst element = entry.range.start.nodeAfter;\n\t\t\tif (entry.attributeNewValue === null && element && element.is(\"element\", \"listItem\")) {\n\t\t\t\twriter.rename(element, \"paragraph\");\n\t\t\t\tapplied = true;\n\t\t\t} else if (entry.attributeOldValue === null && element && element.is(\"element\") && element.name != \"listItem\") {\n\t\t\t\twriter.rename(element, \"listItem\");\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t}\n\t}\n\tconst seenIds = /* @__PURE__ */ new Set();\n\tfor (const listHead of itemToListHead.values()) applied = listEditing.fire(\"postFixer\", {\n\t\tlistNodes: new ListBlocksIterable(listHead),\n\t\tlistHead,\n\t\twriter,\n\t\tseenIds\n\t}) || applied;\n\treturn applied;\n}\n/**\n* A fixer for pasted content that includes list items.\n*\n* It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n*\n* Example:\n*\n* ```xml\n* <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=\"0\">A</paragraph>\n* <paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=\"1\">B^</paragraph>\n* // At ^ paste: <paragraph listType=\"numbered\" listItemId=\"x\" listIndent=\"0\">X</paragraph>\n* // <paragraph listType=\"numbered\" listItemId=\"y\" listIndent=\"1\">Y</paragraph>\n* <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=\"2\">C</paragraph>\n* ```\n*\n* Should become:\n*\n* ```xml\n* <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=\"0\">A</paragraph>\n* <paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=\"1\">BX</paragraph>\n* <paragraph listType=\"bulleted\" listItemId=\"y\" listIndent=\"2\">Y/paragraph>\n* <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=\"2\">C</paragraph>\n* ```\n*/\nfunction createModelIndentPasteFixer(model) {\n\treturn (evt, [content, selectable]) => {\n\t\tconst items = (content.is(\"documentFragment\") ? Array.from(content.getChildren()) : [content]).filter((item) => !model.schema.isInline(item));\n\t\tif (!items.length) return;\n\t\tconst position = (selectable ? model.createSelection(selectable) : model.document.selection).getFirstPosition();\n\t\tlet refItem;\n\t\tif (isListItemBlock(position.parent)) refItem = position.parent;\n\t\telse if (isListItemBlock(position.nodeBefore) && isListItemBlock(position.nodeAfter)) refItem = position.nodeBefore;\n\t\telse return;\n\t\tmodel.change((writer) => {\n\t\t\tconst refType = refItem.getAttribute(\"listType\");\n\t\t\tconst refIndent = refItem.getAttribute(\"listIndent\");\n\t\t\tconst firstElementIndent = items[0].getAttribute(\"listIndent\") || 0;\n\t\t\tconst indentDiff = Math.max(refIndent - firstElementIndent, 0);\n\t\t\tfor (const item of items) {\n\t\t\t\tconst isListItem = isListItemBlock(item);\n\t\t\t\tif (refItem.is(\"element\", \"listItem\") && item.is(\"element\", \"paragraph\"))\n /**\n\t\t\t\t* When paragraphs or a plain text list is pasted into a simple list, convert\n\t\t\t\t* the `<paragraphs>' to `<listItem>' to avoid breaking the target list.\n\t\t\t\t*\n\t\t\t\t* See https://github.com/ckeditor/ckeditor5/issues/13826.\n\t\t\t\t*/\n\t\t\t\twriter.rename(item, \"listItem\");\n\t\t\t\twriter.setAttributes({\n\t\t\t\t\tlistIndent: (isListItem ? item.getAttribute(\"listIndent\") : 0) + indentDiff,\n\t\t\t\t\tlistItemId: isListItem ? item.getAttribute(\"listItemId\") : ListItemUid.next(),\n\t\t\t\t\tlistType: refType\n\t\t\t\t}, item);\n\t\t\t}\n\t\t});\n\t};\n}\n/**\n* Decides whether the merge should be accompanied by the model's `deleteContent()`, for instance, to get rid of the inline\n* content in the selection or take advantage of the heuristics in `deleteContent()` that helps convert lists into paragraphs\n* in certain cases.\n*/\nfunction shouldMergeOnBlocksContentLevel(model, direction) {\n\tconst selection = model.document.selection;\n\tif (!selection.isCollapsed) return !getSelectedBlockObject(model);\n\tif (direction === \"forward\") return true;\n\tconst positionParent = selection.getFirstPosition().parent;\n\tconst previousSibling = positionParent.previousSibling;\n\tif (model.schema.isObject(previousSibling)) return false;\n\tif (previousSibling.isEmpty) return true;\n\treturn isSingleListItem([positionParent, previousSibling]);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Helper method for creating toolbar and menu buttons and linking them with an appropriate command.\n*\n* @internal\n* @param editor The editor instance to which the UI component will be added.\n* @param commandName The name of the command.\n* @param label The button label.\n* @param icon The source of the icon.\n*/\nfunction createUIComponents(editor, commandName, label, icon) {\n\teditor.ui.componentFactory.add(commandName, () => {\n\t\tconst buttonView = _createButton(ButtonView, editor, commandName, label, icon);\n\t\tbuttonView.set({\n\t\t\ttooltip: true,\n\t\t\tisToggleable: true\n\t\t});\n\t\treturn buttonView;\n\t});\n\teditor.ui.componentFactory.add(`menuBar:${commandName}`, () => {\n\t\tconst buttonView = _createButton(MenuBarMenuListItemButtonView, editor, commandName, label, icon);\n\t\tbuttonView.set({\n\t\t\trole: \"menuitemcheckbox\",\n\t\t\tisToggleable: true\n\t\t});\n\t\treturn buttonView;\n\t});\n}\n/**\n* Creates a button to use either in toolbar or in menu bar.\n*/\nfunction _createButton(ButtonClass, editor, commandName, label, icon) {\n\tconst command = editor.commands.get(commandName);\n\tconst view = new ButtonClass(editor.locale);\n\tview.set({\n\t\tlabel,\n\t\ticon\n\t});\n\tview.bind(\"isOn\", \"isEnabled\").to(command, \"value\", \"isEnabled\");\n\tview.on(\"execute\", () => {\n\t\teditor.execute(commandName);\n\t\teditor.editing.view.focus();\n\t});\n\treturn view;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/list/listui\n*/\n/**\n* The list UI feature. It introduces the `'numberedList'` and `'bulletedList'` buttons that\n* allow to convert paragraphs to and from list items and indent or outdent them.\n*/\nvar ListUI = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListUI\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst t = this.editor.t;\n\t\tif (!this.editor.ui.componentFactory.has(\"numberedList\")) createUIComponents(this.editor, \"numberedList\", t(\"Numbered List\"), IconNumberedList);\n\t\tif (!this.editor.ui.componentFactory.has(\"bulletedList\")) createUIComponents(this.editor, \"bulletedList\", t(\"Bulleted List\"), IconBulletedList);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/list\n*/\n/**\n* The list feature.\n*\n* This is a \"glue\" plugin that loads the {@link module:list/list/listediting~ListEditing list\n* editing feature} and {@link module:list/list/listui~ListUI list UI feature}.\n*/\nvar List = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [ListEditing, ListUI];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"List\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listproperties/liststartcommand\n*/\n/**\n* The list start index command. It changes the `listStart` attribute of the selected list items,\n* letting the user to choose the starting point of an ordered list.\n* It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n*/\nvar ListStartCommand = class extends Command {\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tconst value = this._getValue();\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\t/**\n\t* Executes the command.\n\t*\n\t* @fires execute\n\t* @param options Execute options.\n\t* @param options.startIndex The list start index.\n\t*/\n\texecute({ startIndex = 1 } = {}) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tlet blocks = Array.from(document.selection.getSelectedBlocks()).filter((block) => isListItemBlock(block) && isNumberedListType(block.getAttribute(\"listType\")));\n\t\tblocks = expandListBlocksToCompleteList(blocks);\n\t\tmodel.change((writer) => {\n\t\t\tfor (const block of blocks) writer.setAttribute(\"listStart\", startIndex >= 0 ? startIndex : 1, block);\n\t\t});\n\t}\n\t/**\n\t* Checks the command's {@link #value}.\n\t*\n\t* @returns The current value.\n\t*/\n\t_getValue() {\n\t\tconst document = this.editor.model.document;\n\t\tconst block = first(document.selection.getSelectedBlocks());\n\t\tif (block && isListItemBlock(block) && isNumberedListType(block.getAttribute(\"listType\"))) return block.getAttribute(\"listStart\");\n\t\treturn null;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listproperties/utils/style\n*/\nconst LIST_STYLE_TO_LIST_TYPE = {};\nconst LIST_STYLE_TO_TYPE_ATTRIBUTE = {};\nconst TYPE_ATTRIBUTE_TO_LIST_STYLE = {};\nconst LIST_STYLE_TYPES = [\n\t{\n\t\tlistStyle: \"disc\",\n\t\ttypeAttribute: \"disc\",\n\t\tlistType: \"bulleted\"\n\t},\n\t{\n\t\tlistStyle: \"circle\",\n\t\ttypeAttribute: \"circle\",\n\t\tlistType: \"bulleted\"\n\t},\n\t{\n\t\tlistStyle: \"square\",\n\t\ttypeAttribute: \"square\",\n\t\tlistType: \"bulleted\"\n\t},\n\t{\n\t\tlistStyle: \"decimal\",\n\t\ttypeAttribute: \"1\",\n\t\tlistType: \"numbered\"\n\t},\n\t{\n\t\tlistStyle: \"decimal-leading-zero\",\n\t\ttypeAttribute: null,\n\t\tlistType: \"numbered\"\n\t},\n\t{\n\t\tlistStyle: \"lower-roman\",\n\t\ttypeAttribute: \"i\",\n\t\tlistType: \"numbered\"\n\t},\n\t{\n\t\tlistStyle: \"upper-roman\",\n\t\ttypeAttribute: \"I\",\n\t\tlistType: \"numbered\"\n\t},\n\t{\n\t\tlistStyle: \"lower-alpha\",\n\t\ttypeAttribute: \"a\",\n\t\tlistType: \"numbered\"\n\t},\n\t{\n\t\tlistStyle: \"upper-alpha\",\n\t\ttypeAttribute: \"A\",\n\t\tlistType: \"numbered\"\n\t},\n\t{\n\t\tlistStyle: \"lower-latin\",\n\t\ttypeAttribute: \"a\",\n\t\tlistType: \"numbered\"\n\t},\n\t{\n\t\tlistStyle: \"upper-latin\",\n\t\ttypeAttribute: \"A\",\n\t\tlistType: \"numbered\"\n\t},\n\t{\n\t\tlistStyle: \"arabic-indic\",\n\t\ttypeAttribute: null,\n\t\tlistType: \"numbered\"\n\t}\n];\nfor (const { listStyle, typeAttribute, listType } of LIST_STYLE_TYPES) {\n\tLIST_STYLE_TO_LIST_TYPE[listStyle] = listType;\n\tLIST_STYLE_TO_TYPE_ATTRIBUTE[listStyle] = typeAttribute;\n\tif (typeAttribute) TYPE_ATTRIBUTE_TO_LIST_STYLE[typeAttribute] = listStyle;\n}\n/**\n* Gets all the style types supported by given list type.\n*\n* @internal\n*/\nfunction getAllSupportedStyleTypes() {\n\treturn LIST_STYLE_TYPES.map((x) => x.listStyle);\n}\n/**\n* Checks whether the given list-style-type is supported by numbered or bulleted list.\n*\n* @internal\n*/\nfunction getListTypeFromListStyleType(listStyleType) {\n\treturn LIST_STYLE_TO_LIST_TYPE[listStyleType] || null;\n}\n/**\n* Converts `type` attribute of `<ul>` or `<ol>` elements to `list-style-type` equivalent.\n*\n* @internal\n*/\nfunction getListStyleTypeFromTypeAttribute(value) {\n\treturn TYPE_ATTRIBUTE_TO_LIST_STYLE[value] || null;\n}\n/**\n* Converts `list-style-type` style to `type` attribute of `<ul>` or `<ol>` elements.\n*\n* @internal\n*/\nfunction getTypeAttributeFromListStyleType(value) {\n\treturn LIST_STYLE_TO_TYPE_ATTRIBUTE[value] || null;\n}\n/**\n* Normalizes list style by converting aliases to their canonical form.\n*\n* @internal\n* @param listStyle The list style value to normalize.\n* @returns The canonical form of the list style.\n*\n* @example\n* normalizeListStyle( 'lower-alpha' ); // Returns 'lower-latin'\n* normalizeListStyle( 'upper-alpha' ); // Returns 'upper-latin'\n* normalizeListStyle( 'disc' ); // Returns 'disc'\n*/\nfunction normalizeListStyle(listStyle) {\n\tswitch (listStyle) {\n\t\tcase \"lower-alpha\": return \"lower-latin\";\n\t\tcase \"upper-alpha\": return \"upper-latin\";\n\t\tdefault: return listStyle;\n\t}\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listproperties/liststylecommand\n*/\n/**\n* The list style command. It changes `listStyle` attribute of the selected list items,\n* letting the user choose styles for the list item markers.\n* It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n*/\nvar ListStyleCommand = class extends Command {\n\t/**\n\t* The default type of the list style.\n\t*/\n\tdefaultType;\n\t/**\n\t* The list of supported style types by this command.\n\t*/\n\t_supportedTypes;\n\t/**\n\t* Creates an instance of the command.\n\t*\n\t* @param editor The editor instance.\n\t* @param defaultType The list type that will be used by default if the value was not specified during\n\t* the command execution.\n\t* @param supportedTypes The list of supported style types by this command.\n\t*/\n\tconstructor(editor, defaultType, supportedTypes) {\n\t\tsuper(editor);\n\t\tthis.defaultType = defaultType;\n\t\tthis._supportedTypes = supportedTypes;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\t/**\n\t* Executes the command.\n\t*\n\t* @fires execute\n\t* @param options.type The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default\n\t* style will be applied.\n\t*/\n\texecute(options = {}) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tmodel.change((writer) => {\n\t\t\tthis._tryToConvertItemsToList(options);\n\t\t\tlet blocks = Array.from(document.selection.getSelectedBlocks()).filter((block) => block.hasAttribute(\"listType\"));\n\t\t\tif (!blocks.length) return;\n\t\t\tblocks = expandListBlocksToCompleteList(blocks);\n\t\t\tfor (const block of blocks) writer.setAttribute(\"listStyle\", options.type || this.defaultType, block);\n\t\t});\n\t}\n\t/**\n\t* Checks if the given style type is supported by this plugin.\n\t*/\n\tisStyleTypeSupported(value) {\n\t\tif (!this._supportedTypes) return true;\n\t\treturn this._supportedTypes.includes(value);\n\t}\n\t/**\n\t* Checks the command's {@link #value}.\n\t*\n\t* @returns The current value.\n\t*/\n\t_getValue() {\n\t\tconst listItem = first(this.editor.model.document.selection.getSelectedBlocks());\n\t\tif (isListItemBlock(listItem)) return listItem.getAttribute(\"listStyle\");\n\t\treturn null;\n\t}\n\t/**\n\t* Checks whether the command can be enabled in the current context.\n\t*\n\t* @returns Whether the command should be enabled.\n\t*/\n\t_checkEnabled() {\n\t\tconst editor = this.editor;\n\t\tconst numberedList = editor.commands.get(\"numberedList\");\n\t\tconst bulletedList = editor.commands.get(\"bulletedList\");\n\t\treturn numberedList.isEnabled || bulletedList.isEnabled;\n\t}\n\t/**\n\t* Check if the provided list style is valid. Also change the selection to a list if it's not set yet.\n\t*\n\t* @param options.type The type of the list style. If `null` is specified, the function does nothing.\n\t*/\n\t_tryToConvertItemsToList(options) {\n\t\tif (!options.type) return;\n\t\tconst listType = getListTypeFromListStyleType(options.type);\n\t\tif (!listType) return;\n\t\tconst editor = this.editor;\n\t\tconst commandName = `${listType}List`;\n\t\tif (!editor.commands.get(commandName).value) editor.execute(commandName);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listproperties/listreversedcommand\n*/\n/**\n* The list reversed command. It changes the `listReversed` attribute of the selected list items,\n* letting the user to choose the order of an ordered list.\n* It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n*/\nvar ListReversedCommand = class extends Command {\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tconst value = this._getValue();\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\t/**\n\t* Executes the command.\n\t*\n\t* @fires execute\n\t* @param options.reversed Whether the list should be reversed.\n\t*/\n\texecute(options = {}) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tlet blocks = Array.from(document.selection.getSelectedBlocks()).filter((block) => isListItemBlock(block) && block.getAttribute(\"listType\") == \"numbered\");\n\t\tblocks = expandListBlocksToCompleteList(blocks);\n\t\tmodel.change((writer) => {\n\t\t\tfor (const block of blocks) writer.setAttribute(\"listReversed\", !!options.reversed, block);\n\t\t});\n\t}\n\t/**\n\t* Checks the command's {@link #value}.\n\t*/\n\t_getValue() {\n\t\tconst document = this.editor.model.document;\n\t\tconst block = first(document.selection.getSelectedBlocks());\n\t\tif (isListItemBlock(block) && block.getAttribute(\"listType\") == \"numbered\") return block.getAttribute(\"listReversed\");\n\t\treturn null;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* Returns a converter that consumes the `style`, `reversed`, and `start` attributes.\n* In `style`, it searches for the `list-style-type` definition.\n* If not found, the `\"default\"` value will be used.\n*\n* @internal\n* @param strategy\n*/\nfunction listPropertiesUpcastConverter(strategy) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst { writer, schema, consumable } = conversionApi;\n\t\tif (consumable.test(data.viewItem, strategy.viewConsumables) === false) return;\n\t\tif (!data.modelRange) Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));\n\t\tlet applied = false;\n\t\tfor (const item of data.modelRange.getItems({ shallow: true })) {\n\t\t\tif (!schema.checkAttribute(item, strategy.attributeName)) continue;\n\t\t\tif (!strategy.appliesToListItem(item)) continue;\n\t\t\tif (item.hasAttribute(strategy.attributeName)) continue;\n\t\t\twriter.setAttribute(strategy.attributeName, strategy.getAttributeOnUpcast(data.viewItem), item);\n\t\t\tapplied = true;\n\t\t}\n\t\tif (applied) consumable.consume(data.viewItem, strategy.viewConsumables);\n\t};\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listproperties/listpropertiesutils\n*/\n/**\n* A set of helpers related to document lists.\n*/\nvar ListPropertiesUtils = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListPropertiesUtils\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* Gets all the style types supported by given list type.\n\t*/\n\tgetAllSupportedStyleTypes() {\n\t\treturn getAllSupportedStyleTypes();\n\t}\n\t/**\n\t* Checks whether the given list-style-type is supported by numbered or bulleted list.\n\t*/\n\tgetListTypeFromListStyleType(listStyleType) {\n\t\treturn getListTypeFromListStyleType(listStyleType);\n\t}\n\t/**\n\t* Converts `type` attribute of `<ul>` or `<ol>` elements to `list-style-type` equivalent.\n\t*/\n\tgetListStyleTypeFromTypeAttribute(value) {\n\t\treturn getListStyleTypeFromTypeAttribute(value);\n\t}\n\t/**\n\t* Converts `list-style-type` style to `type` attribute of `<ul>` or `<ol>` elements.\n\t*/\n\tgetTypeAttributeFromListStyleType(value) {\n\t\treturn getTypeAttributeFromListStyleType(value);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listproperties/utils/config\n*/\n/**\n* Normalizes {@link module:list/listconfig~ListPropertiesConfig} in the configuration of the list properties feature.\n* The structure of normalized list properties options looks as follows:\n*\n* ```ts\n* {\n* \tstyles: {\n* \t\tlistTypes: [ 'bulleted', 'numbered' ],\n* \t\tuseAttribute: false\n* \t},\n* \tstartIndex: true,\n* \treversed: true\n* }\n* ```\n*\n* @internal\n* @param config The list properties {@link module:list/listconfig~ListPropertiesConfig config}.\n* @returns An object with normalized list properties options.\n*/\nfunction getNormalizedConfig(config) {\n\tconst { startIndex, reversed, styles } = config;\n\treturn {\n\t\tstyles: getNormalizedStylesConfig(styles),\n\t\tstartIndex: startIndex || false,\n\t\treversed: reversed || false\n\t};\n}\n/**\n* Normalizes styles in the configuration of the list properties feature.\n* The structure of normalized list properties options looks as follows:\n*\n* ```ts\n* {\n* \tlistTypes: [ 'bulleted', 'numbered' ],\n* \tuseAttribute: false\n* }\n* ```\n*\n* @param styles The list properties styles.\n* @returns An object with normalized list properties styles.\n*/\nfunction getNormalizedStylesConfig(styles) {\n\tconst normalizedConfig = {\n\t\tlistTypes: [\"bulleted\", \"numbered\"],\n\t\tuseAttribute: false,\n\t\tlistStyleTypes: {\n\t\t\tnumbered: [\n\t\t\t\t\"decimal\",\n\t\t\t\t\"decimal-leading-zero\",\n\t\t\t\t\"lower-roman\",\n\t\t\t\t\"upper-roman\",\n\t\t\t\t\"lower-latin\",\n\t\t\t\t\"upper-latin\"\n\t\t\t],\n\t\t\tbulleted: [\n\t\t\t\t\"disc\",\n\t\t\t\t\"circle\",\n\t\t\t\t\"square\"\n\t\t\t]\n\t\t}\n\t};\n\tif (styles === true) return normalizedConfig;\n\tif (!styles) {\n\t\tnormalizedConfig.listTypes = [];\n\t\tnormalizedConfig.listStyleTypes = {};\n\t} else if (Array.isArray(styles) || typeof styles == \"string\") {\n\t\tnormalizedConfig.listTypes = toArray(styles);\n\t\tnormalizedConfig.listStyleTypes = pick(normalizedConfig.listStyleTypes, normalizedConfig.listTypes);\n\t} else {\n\t\tnormalizedConfig.listTypes = styles.listTypes ? toArray(styles.listTypes) : normalizedConfig.listTypes;\n\t\tnormalizedConfig.useAttribute = !!styles.useAttribute;\n\t\tif (styles.listStyleTypes) normalizedConfig.listStyleTypes = styles.listStyleTypes;\n\t\telse normalizedConfig.listStyleTypes = pick(normalizedConfig.listStyleTypes, normalizedConfig.listTypes);\n\t}\n\treturn normalizedConfig;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listproperties/listpropertiesediting\n*/\nconst DEFAULT_LIST_TYPE$1 = \"default\";\n/**\n* The document list properties engine feature.\n*\n* It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.\n* Read more in {@link module:list/listconfig~ListPropertiesConfig}.\n*/\nvar ListPropertiesEditing = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [ListEditing, ListPropertiesUtils];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListPropertiesEditing\";\n\t}\n\t/**\n\t* @inheritDoc\n\t* @internal\n\t*/\n\tstatic get licenseFeatureCode() {\n\t\treturn \"LP\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isPremiumPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(editor) {\n\t\tsuper(editor);\n\t\teditor.config.define(\"list.properties\", {\n\t\t\tstyles: true,\n\t\t\tstartIndex: false,\n\t\t\treversed: false\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst listEditing = editor.plugins.get(ListEditing);\n\t\tconst strategies = createAttributeStrategies$1(editor.config.get(\"list.properties\"));\n\t\tfor (const strategy of strategies) {\n\t\t\tstrategy.addCommand(editor);\n\t\t\tmodel.schema.extend(\"$listItem\", { allowAttributes: strategy.attributeName });\n\t\t\tlistEditing.registerDowncastStrategy({\n\t\t\t\tscope: \"list\",\n\t\t\t\tattributeName: strategy.attributeName,\n\t\t\t\tsetAttributeOnDowncast(writer, attributeValue, viewElement) {\n\t\t\t\t\tstrategy.setAttributeOnDowncast(writer, attributeValue, viewElement);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\teditor.conversion.for(\"upcast\").add((dispatcher) => {\n\t\t\tfor (const strategy of strategies) {\n\t\t\t\tdispatcher.on(\"element:ol\", listPropertiesUpcastConverter(strategy));\n\t\t\t\tdispatcher.on(\"element:ul\", listPropertiesUpcastConverter(strategy));\n\t\t\t}\n\t\t});\n\t\tlistEditing.on(\"checkAttributes:list\", (evt, { viewElement, modelAttributes, modelReferenceElement }) => {\n\t\t\tfor (const strategy of strategies) {\n\t\t\t\tif (!strategy.appliesToListItem(modelReferenceElement)) continue;\n\t\t\t\tif (strategy.getAttributeOnUpcast(viewElement) != modelAttributes[strategy.attributeName]) {\n\t\t\t\t\tevt.return = true;\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.listenTo(editor.commands.get(\"indentList\"), \"afterExecute\", (evt, changedBlocks) => {\n\t\t\tmodel.change((writer) => {\n\t\t\t\tfor (const node of changedBlocks) for (const strategy of strategies) if (strategy.appliesToListItem(node)) writer.setAttribute(strategy.attributeName, strategy.defaultValue, node);\n\t\t\t});\n\t\t});\n\t\tlistEditing.on(\"postFixer\", (evt, { listNodes, writer }) => {\n\t\t\tfor (const { node } of listNodes) for (const strategy of strategies) {\n\t\t\t\tif (strategy.hasValidAttribute(node)) continue;\n\t\t\t\tif (strategy.appliesToListItem(node)) writer.setAttribute(strategy.attributeName, strategy.defaultValue, node);\n\t\t\t\telse writer.removeAttribute(strategy.attributeName, node);\n\t\t\t\tevt.return = true;\n\t\t\t}\n\t\t});\n\t\tlistEditing.on(\"postFixer\", (evt, { listNodes, writer }) => {\n\t\t\tfor (const { node, previousNodeInList } of listNodes) {\n\t\t\t\tif (!previousNodeInList) continue;\n\t\t\t\tif (previousNodeInList.getAttribute(\"listType\") != node.getAttribute(\"listType\")) continue;\n\t\t\t\tfor (const strategy of strategies) {\n\t\t\t\t\tconst { attributeName } = strategy;\n\t\t\t\t\tif (!strategy.appliesToListItem(node)) continue;\n\t\t\t\t\tconst value = previousNodeInList.getAttribute(attributeName);\n\t\t\t\t\tif (node.getAttribute(attributeName) != value) {\n\t\t\t\t\t\twriter.setAttribute(attributeName, value, node);\n\t\t\t\t\t\tevt.return = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n/**\n* Creates an array of strategies for dealing with enabled listItem attributes.\n*/\nfunction createAttributeStrategies$1(enabledProperties) {\n\tconst strategies = [];\n\tconst normalizedConfig = getNormalizedConfig(enabledProperties);\n\tif (enabledProperties.styles) {\n\t\tconst useAttribute = normalizedConfig.styles.useAttribute;\n\t\tstrategies.push({\n\t\t\tattributeName: \"listStyle\",\n\t\t\tdefaultValue: DEFAULT_LIST_TYPE$1,\n\t\t\tviewConsumables: { styles: \"list-style-type\" },\n\t\t\taddCommand(editor) {\n\t\t\t\tlet supportedTypes = getAllSupportedStyleTypes();\n\t\t\t\tif (useAttribute) supportedTypes = supportedTypes.filter((styleType) => !!getTypeAttributeFromListStyleType(styleType));\n\t\t\t\teditor.commands.add(\"listStyle\", new ListStyleCommand(editor, DEFAULT_LIST_TYPE$1, supportedTypes));\n\t\t\t},\n\t\t\tappliesToListItem(item) {\n\t\t\t\treturn item.getAttribute(\"listType\") == \"numbered\" || item.getAttribute(\"listType\") == \"bulleted\";\n\t\t\t},\n\t\t\thasValidAttribute(item) {\n\t\t\t\tif (!this.appliesToListItem(item)) return !item.hasAttribute(\"listStyle\");\n\t\t\t\tif (!item.hasAttribute(\"listStyle\")) return false;\n\t\t\t\tconst value = item.getAttribute(\"listStyle\");\n\t\t\t\tif (value == DEFAULT_LIST_TYPE$1) return true;\n\t\t\t\treturn getListTypeFromListStyleType(value) == item.getAttribute(\"listType\");\n\t\t\t},\n\t\t\tsetAttributeOnDowncast(writer, listStyle, element) {\n\t\t\t\tif (listStyle && listStyle !== DEFAULT_LIST_TYPE$1) if (useAttribute) {\n\t\t\t\t\tconst value = getTypeAttributeFromListStyleType(listStyle);\n\t\t\t\t\tif (value) {\n\t\t\t\t\t\twriter.setAttribute(\"type\", value, element);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\twriter.setStyle(\"list-style-type\", listStyle, element);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\twriter.removeStyle(\"list-style-type\", element);\n\t\t\t\twriter.removeAttribute(\"type\", element);\n\t\t\t},\n\t\t\tgetAttributeOnUpcast(listParent) {\n\t\t\t\tconst style = listParent.getStyle(\"list-style-type\");\n\t\t\t\tif (style) return normalizeListStyle(style);\n\t\t\t\tconst attribute = listParent.getAttribute(\"type\");\n\t\t\t\tif (attribute) return getListStyleTypeFromTypeAttribute(attribute);\n\t\t\t\treturn DEFAULT_LIST_TYPE$1;\n\t\t\t}\n\t\t});\n\t}\n\tif (enabledProperties.reversed) strategies.push({\n\t\tattributeName: \"listReversed\",\n\t\tdefaultValue: false,\n\t\tviewConsumables: { attributes: \"reversed\" },\n\t\taddCommand(editor) {\n\t\t\teditor.commands.add(\"listReversed\", new ListReversedCommand(editor));\n\t\t},\n\t\tappliesToListItem(item) {\n\t\t\treturn item.getAttribute(\"listType\") == \"numbered\";\n\t\t},\n\t\thasValidAttribute(item) {\n\t\t\treturn this.appliesToListItem(item) == item.hasAttribute(\"listReversed\");\n\t\t},\n\t\tsetAttributeOnDowncast(writer, listReversed, element) {\n\t\t\tif (listReversed) writer.setAttribute(\"reversed\", \"reversed\", element);\n\t\t\telse writer.removeAttribute(\"reversed\", element);\n\t\t},\n\t\tgetAttributeOnUpcast(listParent) {\n\t\t\treturn listParent.hasAttribute(\"reversed\");\n\t\t}\n\t});\n\tif (enabledProperties.startIndex) strategies.push({\n\t\tattributeName: \"listStart\",\n\t\tdefaultValue: 1,\n\t\tviewConsumables: { attributes: \"start\" },\n\t\taddCommand(editor) {\n\t\t\teditor.commands.add(\"listStart\", new ListStartCommand(editor));\n\t\t},\n\t\tappliesToListItem(item) {\n\t\t\treturn isNumberedListType(item.getAttribute(\"listType\"));\n\t\t},\n\t\thasValidAttribute(item) {\n\t\t\treturn this.appliesToListItem(item) == item.hasAttribute(\"listStart\");\n\t\t},\n\t\tsetAttributeOnDowncast(writer, listStart, element) {\n\t\t\tif (listStart == 0 || listStart > 1) writer.setAttribute(\"start\", listStart, element);\n\t\t\telse writer.removeAttribute(\"start\", element);\n\t\t},\n\t\tgetAttributeOnUpcast(listParent) {\n\t\t\tconst startAttributeValue = listParent.getAttribute(\"start\");\n\t\t\treturn startAttributeValue >= 0 ? startAttributeValue : 1;\n\t\t}\n\t});\n\treturn strategies;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listproperties/ui/listpropertiesview\n*/\n/**\n* The list properties view to be displayed in the list dropdown.\n*\n* Contains a grid of available list styles and, for numbered list, also the list start index and reversed fields.\n*\n* @internal\n*/\nvar ListPropertiesView = class extends View {\n\t/**\n\t* A collection of the child views.\n\t*/\n\tchildren;\n\t/**\n\t* A view that renders the grid of list styles.\n\t*/\n\tstylesView = null;\n\t/**\n\t* A collapsible view that hosts additional list property fields ({@link #startIndexFieldView} and\n\t* {@link #reversedSwitchButtonView}) to visually separate them from the {@link #stylesView grid of styles}.\n\t*\n\t* **Note**: Only present when:\n\t* * the view represents **numbered** list properties,\n\t* * and the {@link #stylesView} is rendered,\n\t* * and either {@link #startIndexFieldView} or {@link #reversedSwitchButtonView} is rendered.\n\t*\n\t* @readonly\n\t*/\n\tadditionalPropertiesCollapsibleView = null;\n\t/**\n\t* A labeled number field allowing the user to set the start index of the list.\n\t*\n\t* **Note**: Only present when the view represents **numbered** list properties.\n\t*\n\t* @readonly\n\t*/\n\tstartIndexFieldView = null;\n\t/**\n\t* A switch button allowing the user to make the edited list reversed.\n\t*\n\t* **Note**: Only present when the view represents **numbered** list properties.\n\t*\n\t* @readonly\n\t*/\n\treversedSwitchButtonView = null;\n\t/**\n\t* Tracks information about the DOM focus in the view.\n\t*/\n\tfocusTracker = new FocusTracker();\n\t/**\n\t* An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t*/\n\tkeystrokes = new KeystrokeHandler();\n\t/**\n\t* A collection of views that can be focused in the properties view.\n\t*/\n\tfocusables = new ViewCollection();\n\t/**\n\t* Helps cycling over {@link #focusables} in the view.\n\t*/\n\tfocusCycler;\n\t/**\n\t* Creates an instance of the list properties view.\n\t*\n\t* @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t* @param options Options of the view.\n\t* @param options.enabledProperties An object containing the configuration of enabled list property names.\n\t* Allows conditional rendering the sub-components of the properties view.\n\t* @param options.styleButtonViews A list of style buttons to be rendered\n\t* inside the styles grid. The grid will not be rendered when `enabledProperties` does not include the `'styles'` key.\n\t* @param options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).\n\t*/\n\tconstructor(locale, { enabledProperties, styleButtonViews, styleGridAriaLabel }) {\n\t\tsuper(locale);\n\t\tconst elementCssClasses = [\"ck\", \"ck-list-properties\"];\n\t\tthis.children = this.createCollection();\n\t\tthis.focusCycler = new FocusCycler({\n\t\t\tfocusables: this.focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\tfocusPrevious: \"shift + tab\",\n\t\t\t\tfocusNext: \"tab\"\n\t\t\t}\n\t\t});\n\t\tif (styleButtonViews && styleButtonViews.length) {\n\t\t\tthis.stylesView = this._createStylesView(styleButtonViews, styleGridAriaLabel);\n\t\t\tthis.children.add(this.stylesView);\n\t\t} else elementCssClasses.push(\"ck-list-properties_without-styles\");\n\t\tif (enabledProperties.startIndex || enabledProperties.reversed) {\n\t\t\tthis._addNumberedListPropertyViews(enabledProperties);\n\t\t\telementCssClasses.push(\"ck-list-properties_with-numbered-properties\");\n\t\t}\n\t\tthis.setTemplate({\n\t\t\ttag: \"div\",\n\t\t\tattributes: { class: elementCssClasses },\n\t\t\tchildren: this.children\n\t\t});\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\trender() {\n\t\tsuper.render();\n\t\tif (this.stylesView) {\n\t\t\tthis.focusables.add(this.stylesView);\n\t\t\tthis.focusTracker.add(this.stylesView.element);\n\t\t\tif (this.startIndexFieldView || this.reversedSwitchButtonView) {\n\t\t\t\tthis.focusables.add(this.children.last.buttonView);\n\t\t\t\tthis.focusTracker.add(this.children.last.buttonView.element);\n\t\t\t}\n\t\t\tfor (const item of this.stylesView.children) this.stylesView.focusTracker.add(item.element);\n\t\t\taddKeyboardHandlingForGrid({\n\t\t\t\tkeystrokeHandler: this.stylesView.keystrokes,\n\t\t\t\tfocusTracker: this.stylesView.focusTracker,\n\t\t\t\tgridItems: this.stylesView.children,\n\t\t\t\tnumberOfColumns: () => global.window.getComputedStyle(this.stylesView.element).getPropertyValue(\"grid-template-columns\").split(\" \").length,\n\t\t\t\tuiLanguageDirection: this.locale && this.locale.uiLanguageDirection\n\t\t\t});\n\t\t}\n\t\tif (this.startIndexFieldView) {\n\t\t\tthis.focusables.add(this.startIndexFieldView);\n\t\t\tthis.focusTracker.add(this.startIndexFieldView.element);\n\t\t\tconst stopPropagation = (data) => data.stopPropagation();\n\t\t\tthis.keystrokes.set(\"arrowright\", stopPropagation);\n\t\t\tthis.keystrokes.set(\"arrowleft\", stopPropagation);\n\t\t\tthis.keystrokes.set(\"arrowup\", stopPropagation);\n\t\t\tthis.keystrokes.set(\"arrowdown\", stopPropagation);\n\t\t}\n\t\tif (this.reversedSwitchButtonView) {\n\t\t\tthis.focusables.add(this.reversedSwitchButtonView);\n\t\t\tthis.focusTracker.add(this.reversedSwitchButtonView.element);\n\t\t}\n\t\tthis.keystrokes.listenTo(this.element);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tfocus() {\n\t\tthis.focusCycler.focusFirst();\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tfocusLast() {\n\t\tthis.focusCycler.focusLast();\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tdestroy() {\n\t\tsuper.destroy();\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\t/**\n\t* Creates the list styles grid.\n\t*\n\t* @param styleButtons Buttons to be placed in the grid.\n\t* @param styleGridAriaLabel The assistive technology label of the grid.\n\t*/\n\t_createStylesView(styleButtons, styleGridAriaLabel) {\n\t\tconst stylesView = new View(this.locale);\n\t\tstylesView.children = stylesView.createCollection();\n\t\tstylesView.children.addMany(styleButtons);\n\t\tstylesView.setTemplate({\n\t\t\ttag: \"div\",\n\t\t\tattributes: {\n\t\t\t\t\"aria-label\": styleGridAriaLabel,\n\t\t\t\tclass: [\"ck\", \"ck-list-styles-list\"]\n\t\t\t},\n\t\t\tchildren: stylesView.children\n\t\t});\n\t\tstylesView.children.delegate(\"execute\").to(this);\n\t\tstylesView.focus = function() {\n\t\t\tfor (const child of this.children) if (child instanceof ButtonView && child.isOn) {\n\t\t\t\tchild.focus();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.children.first.focus();\n\t\t};\n\t\tstylesView.focusTracker = new FocusTracker();\n\t\tstylesView.keystrokes = new KeystrokeHandler();\n\t\tstylesView.render();\n\t\tstylesView.keystrokes.listenTo(stylesView.element);\n\t\treturn stylesView;\n\t}\n\t/**\n\t* Renders {@link #startIndexFieldView} and/or {@link #reversedSwitchButtonView} depending on the configuration of the properties view.\n\t*\n\t* @param enabledProperties An object containing the configuration of enabled list property names\n\t* (see {@link #constructor}).\n\t*/\n\t_addNumberedListPropertyViews(enabledProperties) {\n\t\tconst t = this.locale.t;\n\t\tconst numberedPropertyViews = [];\n\t\tif (enabledProperties.startIndex) {\n\t\t\tthis.startIndexFieldView = this._createStartIndexField();\n\t\t\tnumberedPropertyViews.push(this.startIndexFieldView);\n\t\t}\n\t\tif (enabledProperties.reversed) {\n\t\t\tthis.reversedSwitchButtonView = this._createReversedSwitchButton();\n\t\t\tnumberedPropertyViews.push(this.reversedSwitchButtonView);\n\t\t}\n\t\tif (this.stylesView) {\n\t\t\tthis.additionalPropertiesCollapsibleView = new CollapsibleView(this.locale, numberedPropertyViews);\n\t\t\tthis.additionalPropertiesCollapsibleView.set({\n\t\t\t\tlabel: t(\"List properties\"),\n\t\t\t\tisCollapsed: true\n\t\t\t});\n\t\t\tthis.additionalPropertiesCollapsibleView.buttonView.bind(\"isEnabled\").toMany(numberedPropertyViews, \"isEnabled\", (...areEnabled) => areEnabled.some((isEnabled) => isEnabled));\n\t\t\tthis.additionalPropertiesCollapsibleView.buttonView.on(\"change:isEnabled\", (evt, data, isEnabled) => {\n\t\t\t\tif (!isEnabled) this.additionalPropertiesCollapsibleView.isCollapsed = true;\n\t\t\t});\n\t\t\tthis.children.add(this.additionalPropertiesCollapsibleView);\n\t\t} else this.children.addMany(numberedPropertyViews);\n\t}\n\t/**\n\t* Creates the list start index labeled field.\n\t*/\n\t_createStartIndexField() {\n\t\tconst t = this.locale.t;\n\t\tconst startIndexFieldView = new LabeledFieldView(this.locale, createLabeledInputNumber);\n\t\tstartIndexFieldView.set({\n\t\t\tlabel: t(\"Start at\"),\n\t\t\tclass: \"ck-numbered-list-properties__start-index\"\n\t\t});\n\t\tstartIndexFieldView.fieldView.set({\n\t\t\tmin: 0,\n\t\t\tstep: 1,\n\t\t\tvalue: 1,\n\t\t\tinputMode: \"numeric\"\n\t\t});\n\t\tstartIndexFieldView.fieldView.on(\"input\", () => {\n\t\t\tconst inputElement = startIndexFieldView.fieldView.element;\n\t\t\tconst startIndex = inputElement.valueAsNumber;\n\t\t\tif (Number.isNaN(startIndex)) {\n\t\t\t\tstartIndexFieldView.errorText = t(\"Invalid start index value.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!inputElement.checkValidity()) startIndexFieldView.errorText = t(\"Start index must be greater than 0.\");\n\t\t\telse this.fire(\"listStart\", { startIndex });\n\t\t});\n\t\treturn startIndexFieldView;\n\t}\n\t/**\n\t* Creates the reversed list switch button.\n\t*/\n\t_createReversedSwitchButton() {\n\t\tconst t = this.locale.t;\n\t\tconst reversedButtonView = new SwitchButtonView(this.locale);\n\t\treversedButtonView.set({\n\t\t\twithText: true,\n\t\t\tlabel: t(\"Reversed order\"),\n\t\t\tclass: \"ck-numbered-list-properties__reversed-order\"\n\t\t});\n\t\treversedButtonView.delegate(\"execute\").to(this, \"listReversed\");\n\t\treturn reversedButtonView;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listproperties/listpropertiesui\n*/\n/**\n* The list properties UI plugin. It introduces the extended `'bulletedList'` and `'numberedList'` toolbar\n* buttons that allow users to control such aspects of list as the marker, start index or order.\n*\n* **Note**: Buttons introduced by this plugin override implementations from the {@link module:list/list/listui~ListUI}\n* (because they share the same names).\n*/\nvar ListPropertiesUI = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListPropertiesUI\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\t\tconst propertiesConfig = editor.config.get(\"list.properties\");\n\t\tconst normalizedConfig = getNormalizedConfig(propertiesConfig);\n\t\tconst stylesListTypes = normalizedConfig.styles.listTypes;\n\t\tif (stylesListTypes.includes(\"bulleted\")) {\n\t\t\tconst styleDefinitions = [\n\t\t\t\t{\n\t\t\t\t\tlabel: t(\"Toggle the disc list style\"),\n\t\t\t\t\ttooltip: t(\"Disc\"),\n\t\t\t\t\ttype: \"disc\",\n\t\t\t\t\ticon: IconListStyleDisc\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t(\"Toggle the circle list style\"),\n\t\t\t\t\ttooltip: t(\"Circle\"),\n\t\t\t\t\ttype: \"circle\",\n\t\t\t\t\ticon: IconListStyleCircle\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t(\"Toggle the square list style\"),\n\t\t\t\t\ttooltip: t(\"Square\"),\n\t\t\t\t\ttype: \"square\",\n\t\t\t\t\ticon: IconListStyleSquare\n\t\t\t\t}\n\t\t\t];\n\t\t\tconst buttonLabel = t(\"Bulleted List\");\n\t\t\tconst styleGridAriaLabel = t(\"Bulleted list styles toolbar\");\n\t\t\tconst commandName = \"bulletedList\";\n\t\t\teditor.ui.componentFactory.add(commandName, getDropdownViewCreator({\n\t\t\t\teditor,\n\t\t\t\tnormalizedConfig,\n\t\t\t\tparentCommandName: commandName,\n\t\t\t\tbuttonLabel,\n\t\t\t\tbuttonIcon: IconBulletedList,\n\t\t\t\tstyleGridAriaLabel,\n\t\t\t\tstyleDefinitions\n\t\t\t}));\n\t\t\teditor.ui.componentFactory.add(`menuBar:${commandName}`, getMenuBarStylesMenuCreator({\n\t\t\t\teditor,\n\t\t\t\tnormalizedConfig,\n\t\t\t\tparentCommandName: commandName,\n\t\t\t\tbuttonLabel,\n\t\t\t\tstyleGridAriaLabel,\n\t\t\t\tstyleDefinitions\n\t\t\t}));\n\t\t}\n\t\tif (stylesListTypes.includes(\"numbered\") || propertiesConfig.startIndex || propertiesConfig.reversed) {\n\t\t\tconst styleDefinitions = [\n\t\t\t\t{\n\t\t\t\t\tlabel: t(\"Toggle the decimal list style\"),\n\t\t\t\t\ttooltip: t(\"Decimal\"),\n\t\t\t\t\ttype: \"decimal\",\n\t\t\t\t\ticon: IconListStyleDecimal\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t(\"Toggle the decimal with leading zero list style\"),\n\t\t\t\t\ttooltip: t(\"Decimal with leading zero\"),\n\t\t\t\t\ttype: \"decimal-leading-zero\",\n\t\t\t\t\ticon: IconListStyleDecimalLeadingZero\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t(\"Toggle the lower–roman list style\"),\n\t\t\t\t\ttooltip: t(\"Lower–roman\"),\n\t\t\t\t\ttype: \"lower-roman\",\n\t\t\t\t\ticon: IconListStyleLowerRoman\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t(\"Toggle the upper–roman list style\"),\n\t\t\t\t\ttooltip: t(\"Upper-roman\"),\n\t\t\t\t\ttype: \"upper-roman\",\n\t\t\t\t\ticon: IconListStyleUpperRoman\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t(\"Toggle the lower–latin list style\"),\n\t\t\t\t\ttooltip: t(\"Lower-latin\"),\n\t\t\t\t\ttype: \"lower-latin\",\n\t\t\t\t\ticon: IconListStyleLowerLatin\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t(\"Toggle the upper–latin list style\"),\n\t\t\t\t\ttooltip: t(\"Upper-latin\"),\n\t\t\t\t\ttype: \"upper-latin\",\n\t\t\t\t\ticon: IconListStyleUpperLatin\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t(\"Toggle the arabic-indic list style\"),\n\t\t\t\t\ttooltip: t(\"Arabic-indic\"),\n\t\t\t\t\ttype: \"arabic-indic\",\n\t\t\t\t\ticon: IconListStyleArabicIndic\n\t\t\t\t}\n\t\t\t];\n\t\t\tconst buttonLabel = t(\"Numbered List\");\n\t\t\tconst styleGridAriaLabel = t(\"Numbered list styles toolbar\");\n\t\t\tconst commandName = \"numberedList\";\n\t\t\teditor.ui.componentFactory.add(commandName, getDropdownViewCreator({\n\t\t\t\teditor,\n\t\t\t\tnormalizedConfig,\n\t\t\t\tparentCommandName: commandName,\n\t\t\t\tbuttonLabel,\n\t\t\t\tbuttonIcon: IconNumberedList,\n\t\t\t\tstyleGridAriaLabel,\n\t\t\t\tstyleDefinitions\n\t\t\t}));\n\t\t\tif (stylesListTypes.includes(\"numbered\")) editor.ui.componentFactory.add(`menuBar:${commandName}`, getMenuBarStylesMenuCreator({\n\t\t\t\teditor,\n\t\t\t\tnormalizedConfig,\n\t\t\t\tparentCommandName: commandName,\n\t\t\t\tbuttonLabel,\n\t\t\t\tstyleGridAriaLabel,\n\t\t\t\tstyleDefinitions\n\t\t\t}));\n\t\t}\n\t}\n};\n/**\n* A helper that returns a function that creates a split button with a toolbar in the dropdown,\n* which in turn contains buttons allowing users to change list styles in the context of the current selection.\n*\n* @param options.editor\n* @param options.normalizedConfig List properties configuration.\n* @param options.parentCommandName The name of the higher-order editor command associated with\n* the set of particular list styles (e.g. \"bulletedList\" for \"disc\", \"circle\", and \"square\" styles).\n* @param options.buttonLabel Label of the main part of the split button.\n* @param options.buttonIcon The SVG string of an icon for the main part of the split button.\n* @param options.styleGridAriaLabel The ARIA label for the styles grid in the split button dropdown.\n* @param options.styleDefinitions Definitions of the style buttons.\n* @returns A function that can be passed straight into {@link module:ui/componentfactory~ComponentFactory#add}.\n*/\nfunction getDropdownViewCreator({ editor, normalizedConfig, parentCommandName, buttonLabel, buttonIcon, styleGridAriaLabel, styleDefinitions }) {\n\tconst parentCommand = editor.commands.get(parentCommandName);\n\treturn (locale) => {\n\t\tconst dropdownView = createDropdown(locale, SplitButtonView);\n\t\tconst mainButtonView = dropdownView.buttonView;\n\t\tdropdownView.bind(\"isEnabled\").to(parentCommand);\n\t\tdropdownView.class = \"ck-list-styles-dropdown\";\n\t\tmainButtonView.on(\"execute\", () => {\n\t\t\teditor.execute(parentCommandName);\n\t\t\teditor.editing.view.focus();\n\t\t});\n\t\tmainButtonView.set({\n\t\t\tlabel: buttonLabel,\n\t\t\ticon: buttonIcon,\n\t\t\ttooltip: true,\n\t\t\tisToggleable: true\n\t\t});\n\t\tmainButtonView.bind(\"isOn\").to(parentCommand, \"value\", (value) => !!value);\n\t\tdropdownView.once(\"change:isOpen\", () => {\n\t\t\tconst listPropertiesView = createListPropertiesView({\n\t\t\t\teditor,\n\t\t\t\tnormalizedConfig,\n\t\t\t\tdropdownView,\n\t\t\t\tparentCommandName,\n\t\t\t\tstyleGridAriaLabel,\n\t\t\t\tstyleDefinitions\n\t\t\t});\n\t\t\tdropdownView.panelView.children.add(listPropertiesView);\n\t\t});\n\t\tdropdownView.on(\"execute\", () => {\n\t\t\teditor.editing.view.focus();\n\t\t});\n\t\treturn dropdownView;\n\t};\n}\n/**\n* A helper that returns a function (factory) that creates individual buttons used by users to change styles\n* of lists.\n*\n* @param options.editor\n* @param options.listStyleCommand The instance of the `ListStylesCommand` class.\n* @param options.parentCommandName The name of the higher-order command associated with a\n* particular list style (e.g. \"bulletedList\" is associated with \"square\" and \"numberedList\" is associated with \"roman\").\n* @returns A function that can be passed straight into {@link module:ui/componentfactory~ComponentFactory#add}.\n*/\nfunction getStyleButtonCreator({ editor, listStyleCommand, parentCommandName }) {\n\tconst locale = editor.locale;\n\tconst parentCommand = editor.commands.get(parentCommandName);\n\treturn ({ label, type, icon, tooltip }) => {\n\t\tconst button = new ButtonView(locale);\n\t\tbutton.set({\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip\n\t\t});\n\t\tbutton.bind(\"isOn\").to(listStyleCommand, \"value\", (value) => value === type);\n\t\tbutton.on(\"execute\", () => {\n\t\t\tif (parentCommand.value) {\n\t\t\t\tif (listStyleCommand.value === type) editor.execute(parentCommandName);\n\t\t\t\telse if (listStyleCommand.value !== type) editor.execute(\"listStyle\", { type });\n\t\t\t} else editor.model.change(() => {\n\t\t\t\teditor.execute(\"listStyle\", { type });\n\t\t\t});\n\t\t});\n\t\treturn button;\n\t};\n}\n/**\n* A helper that creates the properties view for the individual style dropdown.\n*\n* @param options.editor Editor instance.\n* @param options.normalizedConfig List properties configuration.\n* @param options.dropdownView Styles dropdown view that hosts the properties view.\n* @param options.parentCommandName The name of the higher-order editor command associated with\n* the set of particular list styles (e.g. \"bulletedList\" for \"disc\", \"circle\", and \"square\" styles).\n* @param options.styleDefinitions Definitions of the style buttons.\n* @param options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).\n*/\nfunction createListPropertiesView({ editor, normalizedConfig, dropdownView, parentCommandName, styleDefinitions, styleGridAriaLabel }) {\n\tconst locale = editor.locale;\n\tconst enabledProperties = {\n\t\t...normalizedConfig,\n\t\t...parentCommandName != \"numberedList\" ? {\n\t\t\tstartIndex: false,\n\t\t\treversed: false\n\t\t} : null\n\t};\n\tconst listType = parentCommandName.replace(\"List\", \"\");\n\tlet styleButtonViews = null;\n\tif (normalizedConfig.styles.listTypes.includes(listType)) {\n\t\tconst listStyleCommand = editor.commands.get(\"listStyle\");\n\t\tconst styleButtonCreator = getStyleButtonCreator({\n\t\t\teditor,\n\t\t\tparentCommandName,\n\t\t\tlistStyleCommand\n\t\t});\n\t\tconst configuredListStylesTypes = normalizedConfig.styles.listStyleTypes;\n\t\tlet filteredDefinitions = styleDefinitions;\n\t\t/* v8 ignore next -- Normalized config always provides listStyleTypes for enabled styles. */\n\t\tif (configuredListStylesTypes) {\n\t\t\tconst allowedTypes = configuredListStylesTypes[listType];\n\t\t\tif (allowedTypes) filteredDefinitions = styleDefinitions.filter((def) => allowedTypes.includes(def.type));\n\t\t}\n\t\tconst isStyleTypeSupported = getStyleTypeSupportChecker(listStyleCommand);\n\t\tstyleButtonViews = filteredDefinitions.filter(isStyleTypeSupported).map(styleButtonCreator);\n\t}\n\tconst listPropertiesView = new ListPropertiesView(locale, {\n\t\tstyleGridAriaLabel,\n\t\tenabledProperties,\n\t\tstyleButtonViews\n\t});\n\tif (normalizedConfig.styles.listTypes.includes(listType)) focusChildOnDropdownOpen(dropdownView, () => {\n\t\treturn listPropertiesView.stylesView.children.find((child) => child.isOn);\n\t});\n\tif (enabledProperties.startIndex) {\n\t\tconst listStartCommand = editor.commands.get(\"listStart\");\n\t\tlistPropertiesView.startIndexFieldView.bind(\"isEnabled\").to(listStartCommand);\n\t\tlistPropertiesView.startIndexFieldView.fieldView.bind(\"value\").to(listStartCommand);\n\t\tlistPropertiesView.on(\"listStart\", (evt, data) => editor.execute(\"listStart\", data));\n\t}\n\tif (enabledProperties.reversed) {\n\t\tconst listReversedCommand = editor.commands.get(\"listReversed\");\n\t\tlistPropertiesView.reversedSwitchButtonView.bind(\"isEnabled\").to(listReversedCommand);\n\t\tlistPropertiesView.reversedSwitchButtonView.bind(\"isOn\").to(listReversedCommand, \"value\", (value) => !!value);\n\t\tlistPropertiesView.on(\"listReversed\", () => {\n\t\t\tconst isReversed = listReversedCommand.value;\n\t\t\teditor.execute(\"listReversed\", { reversed: !isReversed });\n\t\t});\n\t}\n\tlistPropertiesView.delegate(\"execute\").to(dropdownView);\n\treturn listPropertiesView;\n}\n/**\n* A helper that creates the list style submenu for menu bar.\n*\n* @param editor Editor instance.\n* @param normalizedConfig List properties configuration.\n* @param parentCommandName Name of the list command.\n* @param buttonLabel Label of the menu button.\n* @param styleGridAriaLabel ARIA label of the styles grid.\n*/\nfunction getMenuBarStylesMenuCreator({ editor, normalizedConfig, parentCommandName, buttonLabel, styleGridAriaLabel, styleDefinitions }) {\n\treturn (locale) => {\n\t\tconst menuView = new MenuBarMenuView(locale);\n\t\tconst listCommand = editor.commands.get(parentCommandName);\n\t\tconst listStyleCommand = editor.commands.get(\"listStyle\");\n\t\tconst isStyleTypeSupported = getStyleTypeSupportChecker(listStyleCommand);\n\t\tconst styleButtonCreator = getStyleButtonCreator({\n\t\t\teditor,\n\t\t\tparentCommandName,\n\t\t\tlistStyleCommand\n\t\t});\n\t\tconst configuredListStylesTypes = normalizedConfig.styles.listStyleTypes;\n\t\tlet filteredDefinitions = styleDefinitions;\n\t\t/* v8 ignore next -- Normalized config always provides listStyleTypes for enabled styles. */\n\t\tif (configuredListStylesTypes) {\n\t\t\tconst allowedTypes = configuredListStylesTypes[listCommand.type];\n\t\t\tif (allowedTypes) filteredDefinitions = styleDefinitions.filter((def) => allowedTypes.includes(def.type));\n\t\t}\n\t\tconst styleButtonViews = filteredDefinitions.filter(isStyleTypeSupported).map(styleButtonCreator);\n\t\tconst listPropertiesView = new ListPropertiesView(locale, {\n\t\t\tstyleGridAriaLabel,\n\t\t\tenabledProperties: {\n\t\t\t\t...normalizedConfig,\n\t\t\t\tstartIndex: false,\n\t\t\t\treversed: false\n\t\t\t},\n\t\t\tstyleButtonViews\n\t\t});\n\t\tlistPropertiesView.delegate(\"execute\").to(menuView);\n\t\tmenuView.buttonView.set({\n\t\t\tlabel: buttonLabel,\n\t\t\ticon: parentCommandName === \"bulletedList\" ? IconBulletedList : IconNumberedList\n\t\t});\n\t\tmenuView.panelView.children.add(listPropertiesView);\n\t\tmenuView.bind(\"isEnabled\").to(listCommand, \"isEnabled\");\n\t\tmenuView.on(\"execute\", () => {\n\t\t\teditor.editing.view.focus();\n\t\t});\n\t\treturn menuView;\n\t};\n}\nfunction getStyleTypeSupportChecker(listStyleCommand) {\n\tif (typeof listStyleCommand.isStyleTypeSupported == \"function\") return (styleDefinition) => listStyleCommand.isStyleTypeSupported(styleDefinition.type);\n\telse return () => true;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/listproperties\n*/\n/**\n* The list properties feature.\n*\n* This is a \"glue\" plugin that loads the\n* {@link module:list/listproperties/listpropertiesediting~ListPropertiesEditing list properties\n* editing feature} and the {@link module:list/listproperties/listpropertiesui~ListPropertiesUI list properties UI feature}.\n*/\nvar ListProperties = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [ListPropertiesEditing, ListPropertiesUI];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"ListProperties\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/todolist/checktodolistcommand\n*/\n/**\n* The check to-do command.\n*\n* The command is registered by the {@link module:list/todolist/todolistediting~TodoListEditing} as\n* the `checkTodoList` editor command.\n*/\nvar CheckTodoListCommand = class extends Command {\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(editor) {\n\t\tsuper(editor);\n\t\tthis.on(\"execute\", () => {\n\t\t\tthis.refresh();\n\t\t}, { priority: \"highest\" });\n\t}\n\t/**\n\t* Updates the command's {@link #value} and {@link #isEnabled} properties based on the current selection.\n\t*/\n\trefresh() {\n\t\tconst selectedElements = this._getSelectedItems();\n\t\tthis.value = this._getValue(selectedElements);\n\t\tthis.isEnabled = !!selectedElements.length;\n\t}\n\t/**\n\t* Executes the command.\n\t*\n\t* @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply\n\t* the attribute. Otherwise, the command will remove the attribute. If not set, the command will look for its current\n\t* value to decide what it should do.\n\t*/\n\texecute(options = {}) {\n\t\tthis.editor.model.change((writer) => {\n\t\t\tconst selectedElements = this._getSelectedItems();\n\t\t\tconst value = options.forceValue === void 0 ? !this._getValue(selectedElements) : options.forceValue;\n\t\t\tfor (const element of selectedElements) if (value) writer.setAttribute(\"todoListChecked\", true, element);\n\t\t\telse writer.removeAttribute(\"todoListChecked\", element);\n\t\t});\n\t}\n\t/**\n\t* Returns a value for the command.\n\t*/\n\t_getValue(selectedElements) {\n\t\treturn selectedElements.every((element) => element.getAttribute(\"todoListChecked\"));\n\t}\n\t/**\n\t* Gets all to-do list items selected by the {@link module:engine/model/selection~ModelSelection}.\n\t*/\n\t_getSelectedItems() {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst selectionRange = model.document.selection.getFirstRange();\n\t\tconst startElement = selectionRange.start.parent;\n\t\tconst elements = [];\n\t\tif (schema.checkAttribute(startElement, \"todoListChecked\")) elements.push(...getAllListItemBlocks(startElement));\n\t\tfor (const item of selectionRange.getItems({ shallow: true })) if (schema.checkAttribute(item, \"todoListChecked\") && !elements.includes(item)) elements.push(...getAllListItemBlocks(item));\n\t\treturn elements;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/todolist/todocheckboxchangeobserver\n*/\n/**\n* Observes all to-do list checkboxes state changes.\n*\n* Note that this observer is not available by default. To make it available it needs to be added to\n* {@link module:engine/view/view~EditingView} by {@link module:engine/view/view~EditingView#addObserver} method.\n*\n* @internal\n*/\nvar TodoCheckboxChangeObserver = class extends DomEventObserver {\n\t/**\n\t* @inheritDoc\n\t*/\n\tdomEventType = [\"change\"];\n\t/**\n\t* @inheritDoc\n\t*/\n\tonDomEvent(domEvent) {\n\t\tif (domEvent.target) {\n\t\t\tconst viewTarget = this.view.domConverter.mapDomToView(domEvent.target);\n\t\t\tif (viewTarget && viewTarget.is(\"element\", \"input\") && viewTarget.getAttribute(\"type\") == \"checkbox\" && viewTarget.findAncestor({ classes: \"todo-list__label\" })) this.fire(\"todoCheckboxChange\", domEvent);\n\t\t}\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/todolist/todolistediting\n*/\nconst ITEM_TOGGLE_KEYSTROKE$1 = /* #__PURE__ */ parseKeystroke(\"Ctrl+Enter\");\n/**\n* The engine of the to-do list feature. It handles creating, editing and removing to-do lists and their items.\n*\n* It registers the entire functionality of the {@link module:list/list/listediting~ListEditing list editing plugin}\n* and extends it with the commands:\n*\n* - `'todoList'`,\n* - `'checkTodoList'`,\n*/\nvar TodoListEditing = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"TodoListEditing\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [ListEditing];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst editing = editor.editing;\n\t\tconst listEditing = editor.plugins.get(ListEditing);\n\t\tconst elementName = editor.config.get(\"list.multiBlock\") ? \"paragraph\" : \"listItem\";\n\t\teditor.commands.add(\"todoList\", new ListCommand(editor, \"todo\"));\n\t\teditor.commands.add(\"checkTodoList\", new CheckTodoListCommand(editor));\n\t\tediting.view.addObserver(TodoCheckboxChangeObserver);\n\t\tmodel.schema.extend(\"$listItem\", { allowAttributes: \"todoListChecked\" });\n\t\tmodel.schema.addAttributeCheck((context) => {\n\t\t\tconst item = context.last;\n\t\t\tif (!item.getAttribute(\"listItemId\") || item.getAttribute(\"listType\") != \"todo\") return false;\n\t\t}, \"todoListChecked\");\n\t\teditor.conversion.for(\"upcast\").add((dispatcher) => {\n\t\t\tdispatcher.on(\"element:input\", todoItemInputConverter());\n\t\t\tdispatcher.on(\"element:li\", todoListItemUpcastConverter(), { priority: \"low\" });\n\t\t\tdispatcher.on(\"element:label\", elementUpcastConsumingConverter({\n\t\t\t\tname: \"label\",\n\t\t\t\tclasses: \"todo-list__label\"\n\t\t\t}));\n\t\t\tdispatcher.on(\"element:label\", elementUpcastConsumingConverter({\n\t\t\t\tname: \"label\",\n\t\t\t\tclasses: [\"todo-list__label\", \"todo-list__label_without-description\"]\n\t\t\t}));\n\t\t\tdispatcher.on(\"element:span\", elementUpcastConsumingConverter({\n\t\t\t\tname: \"span\",\n\t\t\t\tclasses: \"todo-list__label__description\"\n\t\t\t}));\n\t\t\tdispatcher.on(\"element:ul\", attributeUpcastConsumingConverter({\n\t\t\t\tname: \"ul\",\n\t\t\t\tclasses: \"todo-list\"\n\t\t\t}));\n\t\t});\n\t\teditor.conversion.for(\"downcast\").elementToElement({\n\t\t\tmodel: elementName,\n\t\t\tview: (element, { writer }) => {\n\t\t\t\tif (isDescriptionBlock(element, listEditing.getListAttributeNames())) return writer.createContainerElement(\"span\", { class: \"todo-list__label__description\" });\n\t\t\t},\n\t\t\tconverterPriority: \"highest\"\n\t\t});\n\t\tlistEditing.registerDowncastStrategy({\n\t\t\tscope: \"list\",\n\t\t\tattributeName: \"listType\",\n\t\t\tsetAttributeOnDowncast(writer, value, element) {\n\t\t\t\tif (value == \"todo\") writer.addClass(\"todo-list\", element);\n\t\t\t\telse writer.removeClass(\"todo-list\", element);\n\t\t\t}\n\t\t});\n\t\tlistEditing.registerDowncastStrategy({\n\t\t\tscope: \"itemMarker\",\n\t\t\tattributeName: \"todoListChecked\",\n\t\t\tcreateElement(writer, modelElement, { dataPipeline }) {\n\t\t\t\tif (modelElement.getAttribute(\"listType\") != \"todo\") return null;\n\t\t\t\tconst viewElement = writer.createUIElement(\"input\", {\n\t\t\t\t\ttype: \"checkbox\",\n\t\t\t\t\t...modelElement.getAttribute(\"todoListChecked\") ? { checked: \"checked\" } : null,\n\t\t\t\t\t...dataPipeline ? { disabled: \"disabled\" } : { tabindex: \"-1\" }\n\t\t\t\t});\n\t\t\t\tif (dataPipeline) return viewElement;\n\t\t\t\tconst wrapper = writer.createContainerElement(\"span\", { contenteditable: \"false\" }, viewElement);\n\t\t\t\twrapper.getFillerOffset = () => null;\n\t\t\t\treturn wrapper;\n\t\t\t},\n\t\t\tcanWrapElement(modelElement) {\n\t\t\t\treturn isDescriptionBlock(modelElement, listEditing.getListAttributeNames());\n\t\t\t},\n\t\t\tcreateWrapperElement(writer, modelElement, { dataPipeline }) {\n\t\t\t\tconst classes = [\"todo-list__label\"];\n\t\t\t\tif (!isDescriptionBlock(modelElement, listEditing.getListAttributeNames())) classes.push(\"todo-list__label_without-description\");\n\t\t\t\treturn writer.createAttributeElement(dataPipeline ? \"label\" : \"span\", { class: classes.join(\" \") });\n\t\t\t}\n\t\t});\n\t\tlistEditing.on(\"checkElement\", (evt, { modelElement, viewElement }) => {\n\t\t\tconst isFirstTodoModelParagraphBlock = isDescriptionBlock(modelElement, listEditing.getListAttributeNames());\n\t\t\tif (viewElement.hasClass(\"todo-list__label__description\") != isFirstTodoModelParagraphBlock) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t});\n\t\tlistEditing.on(\"checkElement\", (evt, { modelElement, viewElement }) => {\n\t\t\tconst isFirstTodoModelItemBlock = modelElement.getAttribute(\"listType\") == \"todo\" && isFirstBlockOfListItem(modelElement);\n\t\t\tlet hasViewItemMarker = false;\n\t\t\tconst viewWalker = editor.editing.view.createPositionBefore(viewElement).getWalker({ direction: \"backward\" });\n\t\t\tfor (const { item } of viewWalker) {\n\t\t\t\tif (item.is(\"element\") && editor.editing.mapper.toModelElement(item)) break;\n\t\t\t\tif (item.is(\"element\", \"input\") && item.getAttribute(\"type\") == \"checkbox\") hasViewItemMarker = true;\n\t\t\t}\n\t\t\tif (hasViewItemMarker != isFirstTodoModelItemBlock) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t});\n\t\tlistEditing.on(\"postFixer\", (evt, { listNodes, writer }) => {\n\t\t\tfor (const { node, previousNodeInList } of listNodes) {\n\t\t\t\tif (!previousNodeInList) continue;\n\t\t\t\tif (previousNodeInList.getAttribute(\"listItemId\") != node.getAttribute(\"listItemId\")) continue;\n\t\t\t\tconst previousHasAttribute = previousNodeInList.hasAttribute(\"todoListChecked\");\n\t\t\t\tconst nodeHasAttribute = node.hasAttribute(\"todoListChecked\");\n\t\t\t\tif (nodeHasAttribute && !previousHasAttribute) {\n\t\t\t\t\twriter.removeAttribute(\"todoListChecked\", node);\n\t\t\t\t\tevt.return = true;\n\t\t\t\t} else if (!nodeHasAttribute && previousHasAttribute) {\n\t\t\t\t\twriter.setAttribute(\"todoListChecked\", true, node);\n\t\t\t\t\tevt.return = true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tmodel.document.registerPostFixer((writer) => {\n\t\t\tconst changes = model.document.differ.getChanges();\n\t\t\tlet wasFixed = false;\n\t\t\tfor (const change of changes) if (change.type == \"attribute\" && change.attributeKey == \"listType\") {\n\t\t\t\tconst element = change.range.start.nodeAfter;\n\t\t\t\tif (change.attributeOldValue == \"todo\" && element.hasAttribute(\"todoListChecked\")) {\n\t\t\t\t\twriter.removeAttribute(\"todoListChecked\", element);\n\t\t\t\t\twasFixed = true;\n\t\t\t\t}\n\t\t\t} else if (change.type == \"insert\" && change.name != \"$text\") {\n\t\t\t\tfor (const { item } of writer.createRangeOn(change.position.nodeAfter)) if (item.is(\"element\") && item.getAttribute(\"listType\") != \"todo\" && item.hasAttribute(\"todoListChecked\")) {\n\t\t\t\t\twriter.removeAttribute(\"todoListChecked\", item);\n\t\t\t\t\twasFixed = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn wasFixed;\n\t\t});\n\t\tthis.listenTo(editing.view.document, \"keydown\", (evt, data) => {\n\t\t\tif (getCode(data) === ITEM_TOGGLE_KEYSTROKE$1) {\n\t\t\t\teditor.execute(\"checkTodoList\");\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: \"high\" });\n\t\tthis.listenTo(editing.view.document, \"todoCheckboxChange\", (evt, data) => {\n\t\t\tconst viewTarget = data.target;\n\t\t\tif (!viewTarget || !viewTarget.is(\"element\", \"input\")) return;\n\t\t\tconst viewPositionAfter = editing.view.createPositionAfter(viewTarget);\n\t\t\tconst modelElement = editing.mapper.toModelPosition(viewPositionAfter).parent;\n\t\t\t/* v8 ignore next -- Defensive guard for externally fired observer events outside to-do list inputs. */\n\t\t\tif (modelElement && isListItemBlock(modelElement) && modelElement.getAttribute(\"listType\") == \"todo\") this._handleCheckmarkChange(modelElement);\n\t\t});\n\t\tthis.listenTo(editing.view.document, \"arrowKey\", jumpOverCheckmarkOnSideArrowKeyPress$1(model, editor.locale), { context: \"$text\" });\n\t\tthis.listenTo(editing.mapper, \"viewToModelPosition\", (evt, data) => {\n\t\t\tconst viewParent = data.viewPosition.parent;\n\t\t\tconst isStartOfListItem = viewParent.is(\"attributeElement\", \"li\") && data.viewPosition.offset == 0;\n\t\t\tconst isStartOfListLabel = isLabelElement(viewParent) && data.viewPosition.offset <= 1;\n\t\t\tconst isInInputWrapper = viewParent.is(\"element\", \"span\") && viewParent.getAttribute(\"contenteditable\") == \"false\" && isLabelElement(viewParent.parent);\n\t\t\tif (!isStartOfListItem && !isStartOfListLabel && !isInInputWrapper) return;\n\t\t\tconst nodeAfter = data.modelPosition.nodeAfter;\n\t\t\t/* v8 ignore next -- Defensive mapper guard for view positions outside to-do list widgets. */\n\t\t\tif (nodeAfter && nodeAfter.getAttribute(\"listType\") == \"todo\") data.modelPosition = model.createPositionAt(nodeAfter, 0);\n\t\t}, { priority: \"low\" });\n\t\tthis._initAriaAnnouncements();\n\t}\n\t/**\n\t* Handles the checkbox element change, moves the selection to the corresponding model item to make it possible\n\t* to toggle the `todoListChecked` attribute using the command, and restores the selection position.\n\t*\n\t* Some say it's a hack :) Moving the selection only for executing the command on a certain node and restoring it after,\n\t* is not a clear solution. We need to design an API for using commands beyond the selection range.\n\t* See https://github.com/ckeditor/ckeditor5/issues/1954.\n\t*/\n\t_handleCheckmarkChange(listItem) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst previousSelectionRanges = Array.from(model.document.selection.getRanges());\n\t\tmodel.change((writer) => {\n\t\t\twriter.setSelection(listItem, \"end\");\n\t\t\teditor.execute(\"checkTodoList\");\n\t\t\twriter.setSelection(previousSelectionRanges);\n\t\t});\n\t}\n\t/**\n\t* Observe when user enters or leaves todo list and set proper aria value in global live announcer.\n\t* This allows screen readers to indicate when the user has entered and left the specified todo list.\n\t*\n\t* @internal\n\t*/\n\t_initAriaAnnouncements() {\n\t\tconst { model, ui, t } = this.editor;\n\t\tlet lastFocusedCodeBlock = null;\n\t\tif (!ui) return;\n\t\tmodel.document.selection.on(\"change:range\", () => {\n\t\t\tconst focusParent = model.document.selection.focus.parent;\n\t\t\tconst lastElementIsTodoList = isTodoListItemElement(lastFocusedCodeBlock);\n\t\t\tconst currentElementIsTodoList = isTodoListItemElement(focusParent);\n\t\t\tif (lastElementIsTodoList && !currentElementIsTodoList) ui.ariaLiveAnnouncer.announce(t(\"Leaving a to-do list\"));\n\t\t\telse if (!lastElementIsTodoList && currentElementIsTodoList) ui.ariaLiveAnnouncer.announce(t(\"Entering a to-do list\"));\n\t\t\tlastFocusedCodeBlock = focusParent;\n\t\t});\n\t}\n};\n/**\n* Returns an upcast converter for to-do list items.\n*/\nfunction todoListItemUpcastConverter() {\n\treturn (evt, data, conversionApi) => {\n\t\tconst { writer, schema } = conversionApi;\n\t\tif (!data.modelRange) return;\n\t\tconst groupedItems = Array.from(data.modelRange.getItems({ shallow: true })).filter((item) => item.getAttribute(\"listType\") === \"todo\" && schema.checkAttribute(item, \"listItemId\")).reduce((acc, item) => {\n\t\t\tconst listItemId = item.getAttribute(\"listItemId\");\n\t\t\tif (!acc.has(listItemId)) acc.set(listItemId, getAllListItemBlocks(item));\n\t\t\treturn acc;\n\t\t}, /* @__PURE__ */ new Map());\n\t\tfor (const [, items] of groupedItems.entries()) if (items.some((item) => item.getAttribute(\"todoListChecked\"))) for (const item of items) writer.setAttribute(\"todoListChecked\", true, item);\n\t};\n}\n/**\n* Returns an upcast converter that detects a to-do list checkbox and marks the list item as a to-do list.\n*/\nfunction todoItemInputConverter() {\n\treturn (evt, data, conversionApi) => {\n\t\tconst modelCursor = data.modelCursor;\n\t\tconst modelItem = modelCursor.parent;\n\t\tconst viewItem = data.viewItem;\n\t\tif (!conversionApi.consumable.test(viewItem, { name: true })) return;\n\t\tif (viewItem.getAttribute(\"type\") != \"checkbox\" || !modelCursor.isAtStart || !modelItem.hasAttribute(\"listType\")) return;\n\t\tconversionApi.consumable.consume(viewItem, { name: true });\n\t\tconst writer = conversionApi.writer;\n\t\twriter.setAttribute(\"listType\", \"todo\", modelItem);\n\t\tif (data.viewItem.hasAttribute(\"checked\")) writer.setAttribute(\"todoListChecked\", true, modelItem);\n\t\tdata.modelRange = writer.createRange(modelCursor);\n\t};\n}\n/**\n* Returns an upcast converter that consumes element matching the given matcher pattern.\n*/\nfunction elementUpcastConsumingConverter(matcherPattern) {\n\tconst matcher = new Matcher(matcherPattern);\n\treturn (evt, data, conversionApi) => {\n\t\tconst matcherResult = matcher.match(data.viewItem);\n\t\tif (!matcherResult) return;\n\t\tif (!conversionApi.consumable.consume(data.viewItem, matcherResult.match)) return;\n\t\tObject.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));\n\t};\n}\n/**\n* Returns an upcast converter that consumes attributes matching the given matcher pattern.\n*/\nfunction attributeUpcastConsumingConverter(matcherPattern) {\n\tconst matcher = new Matcher(matcherPattern);\n\treturn (evt, data, conversionApi) => {\n\t\tconst matcherResult = matcher.match(data.viewItem);\n\t\tif (!matcherResult) return;\n\t\tconst match = matcherResult.match;\n\t\tmatch.name = false;\n\t\tconversionApi.consumable.consume(data.viewItem, match);\n\t};\n}\n/**\n* Returns true if the given list item block should be converted as a description block of a to-do list item.\n*/\nfunction isDescriptionBlock(modelElement, listAttributeNames) {\n\treturn (modelElement.is(\"element\", \"paragraph\") || modelElement.is(\"element\", \"listItem\")) && modelElement.getAttribute(\"listType\") == \"todo\" && isFirstBlockOfListItem(modelElement) && hasOnlyListAttributes(modelElement, listAttributeNames);\n}\n/**\n* Returns true if only attributes from the given list are present on the model element.\n*/\nfunction hasOnlyListAttributes(modelElement, attributeNames) {\n\tfor (const attributeKey of modelElement.getAttributeKeys()) {\n\t\tif (attributeKey.startsWith(\"selection:\")) continue;\n\t\tif (!attributeNames.includes(attributeKey)) return false;\n\t}\n\treturn true;\n}\n/**\n* Jump at the start and end of a to-do list item.\n*/\nfunction jumpOverCheckmarkOnSideArrowKeyPress$1(model, locale) {\n\treturn (eventInfo, domEventData) => {\n\t\tconst direction = getLocalizedArrowKeyCodeDirection(domEventData.keyCode, locale.contentLanguageDirection);\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\t\tif (!selection.isCollapsed) return;\n\t\tconst position = selection.getFirstPosition();\n\t\tconst parent = position.parent;\n\t\tif (direction == \"right\" && position.isAtEnd) {\n\t\t\tconst newRange = schema.getNearestSelectionRange(model.createPositionAfter(parent), \"forward\");\n\t\t\tif (!newRange) return;\n\t\t\tconst newRangeParent = newRange.start.parent;\n\t\t\tif (newRangeParent && isListItemBlock(newRangeParent) && newRangeParent.getAttribute(\"listType\") == \"todo\") {\n\t\t\t\tmodel.change((writer) => writer.setSelection(newRange));\n\t\t\t\tdomEventData.preventDefault();\n\t\t\t\tdomEventData.stopPropagation();\n\t\t\t\teventInfo.stop();\n\t\t\t}\n\t\t} else if (direction == \"left\" && position.isAtStart && isListItemBlock(parent) && parent.getAttribute(\"listType\") == \"todo\") {\n\t\t\tconst newRange = schema.getNearestSelectionRange(model.createPositionBefore(parent), \"backward\");\n\t\t\tif (!newRange) return;\n\t\t\tmodel.change((writer) => writer.setSelection(newRange));\n\t\t\tdomEventData.preventDefault();\n\t\t\tdomEventData.stopPropagation();\n\t\t\teventInfo.stop();\n\t\t}\n\t};\n}\n/**\n* Returns true if the given element is a label element of a to-do list item.\n*/\nfunction isLabelElement(viewElement) {\n\treturn !!viewElement && viewElement.is(\"attributeElement\") && viewElement.hasClass(\"todo-list__label\");\n}\n/**\n* Returns true if the given element is a list item model element of a to-do list.\n*/\nfunction isTodoListItemElement(element) {\n\tif (!element) return false;\n\tif (!element.is(\"element\", \"paragraph\") && !element.is(\"element\", \"listItem\")) return false;\n\treturn element.getAttribute(\"listType\") == \"todo\";\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/todolist/todolistui\n*/\n/**\n* The to-do list UI feature. It introduces the `'todoList'` button that\n* allows to convert elements to and from to-do list items and to indent or outdent them.\n*/\nvar TodoListUI = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"TodoListUI\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst t = this.editor.t;\n\t\tcreateUIComponents(this.editor, \"todoList\", t(\"To-do List\"), IconTodoList);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/todolist\n*/\n/**\n* The to-do list feature.\n*\n* This is a \"glue\" plugin that loads the {@link module:list/todolist/todolistediting~TodoListEditing to-do list\n* editing feature} and the {@link module:list/todolist/todolistui~TodoListUI to-do list UI feature}.\n*/\nvar TodoList = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [TodoListEditing, TodoListUI];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"TodoList\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* The list command. It is used by the {@link module:list/legacylist~LegacyList legacy list feature}.\n*/\nvar LegacyListCommand = class extends Command {\n\t/**\n\t* The type of the list created by the command.\n\t*/\n\ttype;\n\t/**\n\t* Creates an instance of the command.\n\t*\n\t* @param editor The editor instance.\n\t* @param type List type that will be handled by this command.\n\t*/\n\tconstructor(editor, type) {\n\t\tsuper(editor);\n\t\tthis.type = type;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\t/**\n\t* Executes the list command.\n\t*\n\t* @fires execute\n\t* @param options Command options.\n\t* @param options.forceValue If set, it will force the command behavior. If `true`, the command will try to convert the\n\t* selected items and potentially the neighbor elements to the proper list items. If set to `false`, it will convert selected elements\n\t* to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.\n\t*/\n\texecute(options = {}) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst blocks = Array.from(document.selection.getSelectedBlocks()).filter((block) => checkCanBecomeListItem(block, model.schema));\n\t\tconst turnOff = options.forceValue !== void 0 ? !options.forceValue : this.value;\n\t\tmodel.change((writer) => {\n\t\t\tif (turnOff) {\n\t\t\t\tlet next = blocks[blocks.length - 1].nextSibling;\n\t\t\t\tlet currentIndent = Number.POSITIVE_INFINITY;\n\t\t\t\tlet changes = [];\n\t\t\t\twhile (next && next.name == \"listItem\" && next.getAttribute(\"listIndent\") !== 0) {\n\t\t\t\t\tconst indent = next.getAttribute(\"listIndent\");\n\t\t\t\t\tif (indent < currentIndent) currentIndent = indent;\n\t\t\t\t\tconst newIndent = indent - currentIndent;\n\t\t\t\t\tchanges.push({\n\t\t\t\t\t\telement: next,\n\t\t\t\t\t\tlistIndent: newIndent\n\t\t\t\t\t});\n\t\t\t\t\tnext = next.nextSibling;\n\t\t\t\t}\n\t\t\t\tchanges = changes.reverse();\n\t\t\t\tfor (const item of changes) writer.setAttribute(\"listIndent\", item.listIndent, item.element);\n\t\t\t}\n\t\t\tif (!turnOff) {\n\t\t\t\tlet lowestIndent = Number.POSITIVE_INFINITY;\n\t\t\t\tfor (const item of blocks) if (item.is(\"element\", \"listItem\") && item.getAttribute(\"listIndent\") < lowestIndent) lowestIndent = item.getAttribute(\"listIndent\");\n\t\t\t\tlowestIndent = lowestIndent === 0 ? 1 : lowestIndent;\n\t\t\t\t_fixType(blocks, true, lowestIndent);\n\t\t\t\t_fixType(blocks, false, lowestIndent);\n\t\t\t}\n\t\t\tfor (const element of blocks.reverse()) if (turnOff && element.name == \"listItem\") writer.rename(element, \"paragraph\");\n\t\t\telse if (!turnOff && element.name != \"listItem\") {\n\t\t\t\twriter.setAttributes({\n\t\t\t\t\tlistType: this.type,\n\t\t\t\t\tlistIndent: 0\n\t\t\t\t}, element);\n\t\t\t\twriter.rename(element, \"listItem\");\n\t\t\t} else if (!turnOff && element.name == \"listItem\" && element.getAttribute(\"listType\") != this.type) writer.setAttribute(\"listType\", this.type, element);\n\t\t\t/**\n\t\t\t* Event fired by the {@link #execute} method.\n\t\t\t*\n\t\t\t* It allows to execute an action after executing the {@link ~ListCommand#execute} method, for example adjusting\n\t\t\t* attributes of changed blocks.\n\t\t\t*\n\t\t\t* @protected\n\t\t\t* @event _executeCleanup\n\t\t\t*/\n\t\t\tthis.fire(\"_executeCleanup\", blocks);\n\t\t});\n\t}\n\t/**\n\t* Checks the command's {@link #value}.\n\t*\n\t* @returns The current value.\n\t*/\n\t_getValue() {\n\t\tconst listItem = first(this.editor.model.document.selection.getSelectedBlocks());\n\t\treturn !!listItem && listItem.is(\"element\", \"listItem\") && listItem.getAttribute(\"listType\") == this.type;\n\t}\n\t/**\n\t* Checks whether the command can be enabled in the current context.\n\t*\n\t* @returns Whether the command should be enabled.\n\t*/\n\t_checkEnabled() {\n\t\tif (this.value) return true;\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst schema = this.editor.model.schema;\n\t\tconst firstBlock = first(selection.getSelectedBlocks());\n\t\tif (!firstBlock) return false;\n\t\treturn checkCanBecomeListItem(firstBlock, schema);\n\t}\n};\n/**\n* Helper function used when one or more list item have their type changed. Fixes type of other list items\n* that are affected by the change (are in same lists) but are not directly in selection. The function got extracted\n* not to duplicated code, as same fix has to be performed before and after selection.\n*\n* @param blocks Blocks that are in selection.\n* @param isBackward Specified whether fix will be applied for blocks before first selected block (`true`)\n* or blocks after last selected block (`false`).\n* @param lowestIndent Lowest indent among selected blocks.\n*/\nfunction _fixType(blocks, isBackward, lowestIndent) {\n\tconst startingItem = isBackward ? blocks[0] : blocks[blocks.length - 1];\n\tif (startingItem.is(\"element\", \"listItem\")) {\n\t\tlet item = startingItem[isBackward ? \"previousSibling\" : \"nextSibling\"];\n\t\tlet currentIndent = startingItem.getAttribute(\"listIndent\");\n\t\twhile (item && item.is(\"element\", \"listItem\") && item.getAttribute(\"listIndent\") >= lowestIndent) {\n\t\t\tif (currentIndent > item.getAttribute(\"listIndent\")) currentIndent = item.getAttribute(\"listIndent\");\n\t\t\tif (item.getAttribute(\"listIndent\") == currentIndent) blocks[isBackward ? \"unshift\" : \"push\"](item);\n\t\t\titem = item[isBackward ? \"previousSibling\" : \"nextSibling\"];\n\t\t}\n\t}\n}\n/**\n* Checks whether the given block can be replaced by a listItem.\n*\n* @param block A block to be tested.\n* @param schema The schema of the document.\n*/\nfunction checkCanBecomeListItem(block, schema) {\n\treturn schema.checkChild(block.parent, \"listItem\") && !schema.isObject(block);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* The list indent command. It is used by the {@link module:list/legacylist~LegacyList legacy list feature}.\n*/\nvar LegacyIndentCommand = class extends Command {\n\t/**\n\t* Determines by how much the command will change the list item's indent attribute.\n\t*/\n\t_indentBy;\n\t/**\n\t* Creates an instance of the command.\n\t*\n\t* @param editor The editor instance.\n\t* @param indentDirection The direction of indent. If it is equal to `backward`, the command will outdent a list item.\n\t*/\n\tconstructor(editor, indentDirection) {\n\t\tsuper(editor);\n\t\tthis._indentBy = indentDirection == \"forward\" ? 1 : -1;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\t/**\n\t* Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t*\n\t* @fires execute\n\t*/\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tlet itemsToChange = Array.from(doc.selection.getSelectedBlocks());\n\t\tmodel.change((writer) => {\n\t\t\tconst lastItem = itemsToChange[itemsToChange.length - 1];\n\t\t\tlet next = lastItem.nextSibling;\n\t\t\twhile (next && next.name == \"listItem\" && next.getAttribute(\"listIndent\") > lastItem.getAttribute(\"listIndent\")) {\n\t\t\t\titemsToChange.push(next);\n\t\t\t\tnext = next.nextSibling;\n\t\t\t}\n\t\t\tif (this._indentBy < 0) itemsToChange = itemsToChange.reverse();\n\t\t\tfor (const item of itemsToChange) {\n\t\t\t\tconst indent = item.getAttribute(\"listIndent\") + this._indentBy;\n\t\t\t\tif (indent < 0) writer.rename(item, \"paragraph\");\n\t\t\t\telse writer.setAttribute(\"listIndent\", indent, item);\n\t\t\t}\n\t\t\tthis.fire(\"_executeCleanup\", itemsToChange);\n\t\t});\n\t}\n\t/**\n\t* Checks whether the command can be enabled in the current context.\n\t*\n\t* @returns Whether the command should be enabled.\n\t*/\n\t_checkEnabled() {\n\t\tconst listItem = first(this.editor.model.document.selection.getSelectedBlocks());\n\t\tif (!listItem || !listItem.is(\"element\", \"listItem\")) return false;\n\t\tif (this._indentBy > 0) {\n\t\t\tconst indent = listItem.getAttribute(\"listIndent\");\n\t\t\tconst type = listItem.getAttribute(\"listType\");\n\t\t\tlet prev = listItem.previousSibling;\n\t\t\twhile (prev && prev.is(\"element\", \"listItem\") && prev.getAttribute(\"listIndent\") >= indent) {\n\t\t\t\tif (prev.getAttribute(\"listIndent\") == indent) return prev.getAttribute(\"listType\") == type;\n\t\t\t\tprev = prev.previousSibling;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacylist/legacyutils\n*/\n/**\n* Creates a list item {@link module:engine/view/containerelement~ViewContainerElement}.\n*\n* @internal\n* @param writer The writer instance.\n*/\nfunction createViewListItemElement(writer) {\n\tconst viewItem = writer.createContainerElement(\"li\");\n\tviewItem.getFillerOffset = getListItemFillerOffset;\n\treturn viewItem;\n}\n/**\n* Helper function that creates a `<ul><li></li></ul>` or (`<ol>`) structure out of the given `modelItem` model `listItem` element.\n* Then, it binds the created view list item (`<li>`) with the model `listItem` element.\n* The function then returns the created view list item (`<li>`).\n*\n* @internal\n* @param modelItem Model list item.\n* @param conversionApi Conversion interface.\n* @returns View list element.\n*/\nfunction generateLiInUl(modelItem, conversionApi) {\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\tconst listType = modelItem.getAttribute(\"listType\") == \"numbered\" ? \"ol\" : \"ul\";\n\tconst viewItem = createViewListItemElement(viewWriter);\n\tconst viewList = viewWriter.createContainerElement(listType, null);\n\tviewWriter.insert(viewWriter.createPositionAt(viewList, 0), viewItem);\n\tmapper.bindElements(modelItem, viewItem);\n\treturn viewItem;\n}\n/**\n* Helper function that inserts a view list at a correct place and merges it with its siblings.\n* It takes a model list item element (`modelItem`) and a corresponding view list item element (`injectedItem`). The view list item\n* should be in a view list element (`<ul>` or `<ol>`) and should be its only child.\n* See comments below to better understand the algorithm.\n*\n* @internal\n* @param modelItem Model list item.\n* @param injectedItem\n* @param conversionApi Conversion interface.\n* @param model The model instance.\n*/\nfunction injectViewList(modelItem, injectedItem, conversionApi, model) {\n\tconst injectedList = injectedItem.parent;\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\tlet insertPosition;\n\tconst refItem = getSiblingListItem(modelItem.previousSibling, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tlistIndent: modelItem.getAttribute(\"listIndent\")\n\t});\n\tconst prevItem = modelItem.previousSibling;\n\tif (refItem && refItem.getAttribute(\"listIndent\") == modelItem.getAttribute(\"listIndent\")) {\n\t\tconst viewItem = mapper.toViewElement(refItem);\n\t\tinsertPosition = viewWriter.breakContainer(viewWriter.createPositionAfter(viewItem));\n\t} else if (prevItem && prevItem.name == \"listItem\") {\n\t\tinsertPosition = mapper.toViewPosition(model.createPositionAt(prevItem, \"end\"));\n\t\tconst mappedViewAncestor = mapper.findMappedViewAncestor(insertPosition);\n\t\tconst nestedList = findNestedList(mappedViewAncestor);\n\t\tif (nestedList) insertPosition = viewWriter.createPositionBefore(nestedList);\n\t\telse insertPosition = viewWriter.createPositionAt(mappedViewAncestor, \"end\");\n\t} else insertPosition = mapper.toViewPosition(model.createPositionBefore(modelItem));\n\tinsertPosition = positionAfterUiElements(insertPosition);\n\tviewWriter.insert(insertPosition, injectedList);\n\tif (prevItem && prevItem.name == \"listItem\") {\n\t\tconst prevView = mapper.toViewElement(prevItem);\n\t\tconst walker = viewWriter.createRange(viewWriter.createPositionAt(prevView, 0), insertPosition).getWalker({ ignoreElementEnd: true });\n\t\tfor (const value of walker) if (value.item.is(\"element\", \"li\")) {\n\t\t\tconst breakPosition = viewWriter.breakContainer(viewWriter.createPositionBefore(value.item));\n\t\t\tconst viewList = value.item.parent;\n\t\t\tconst targetPosition = viewWriter.createPositionAt(injectedItem, \"end\");\n\t\t\tmergeViewLists(viewWriter, targetPosition.nodeBefore, targetPosition.nodeAfter);\n\t\t\tviewWriter.move(viewWriter.createRangeOn(viewList), targetPosition);\n\t\t\twalker._position = breakPosition;\n\t\t}\n\t} else {\n\t\tconst nextViewList = injectedList.nextSibling;\n\t\tif (nextViewList && (nextViewList.is(\"element\", \"ul\") || nextViewList.is(\"element\", \"ol\"))) {\n\t\t\tlet lastSubChild = null;\n\t\t\tfor (const child of nextViewList.getChildren()) {\n\t\t\t\tconst modelChild = mapper.toModelElement(child);\n\t\t\t\tif (modelChild && modelChild.getAttribute(\"listIndent\") > modelItem.getAttribute(\"listIndent\")) lastSubChild = child;\n\t\t\t\telse break;\n\t\t\t}\n\t\t\tif (lastSubChild) {\n\t\t\t\tviewWriter.breakContainer(viewWriter.createPositionAfter(lastSubChild));\n\t\t\t\tviewWriter.move(viewWriter.createRangeOn(lastSubChild.parent), viewWriter.createPositionAt(injectedItem, \"end\"));\n\t\t\t}\n\t\t}\n\t}\n\tmergeViewLists(viewWriter, injectedList, injectedList.nextSibling);\n\tmergeViewLists(viewWriter, injectedList.previousSibling, injectedList);\n}\nfunction mergeViewLists(viewWriter, firstList, secondList) {\n\tif (!firstList || !secondList || firstList.name != \"ul\" && firstList.name != \"ol\") return null;\n\tif (firstList.name != secondList.name || firstList.getAttribute(\"class\") !== secondList.getAttribute(\"class\")) return null;\n\treturn viewWriter.mergeContainers(viewWriter.createPositionAfter(firstList));\n}\n/**\n* Helper function that for a given `view.Position`, returns a `view.Position` that is after all `view.UIElement`s that\n* are after the given position.\n*\n* For example:\n* `<container:p>foo^<ui:span></ui:span><ui:span></ui:span>bar</container:p>`\n* For position ^, the position before \"bar\" will be returned.\n*\n* @internal\n*/\nfunction positionAfterUiElements(viewPosition) {\n\treturn viewPosition.getLastMatchingPosition((value) => value.item.is(\"uiElement\"));\n}\n/**\n* Helper function that searches for a previous list item sibling of a given model item that meets the given criteria\n* passed by the options object.\n*\n* @internal\n* @param options Search criteria.\n* @param options.sameIndent Whether the sought sibling should have the same indentation.\n* @param options.smallerIndent Whether the sought sibling should have a smaller indentation.\n* @param options.listIndent The reference indentation.\n* @param options.direction Walking direction.\n*/\nfunction getSiblingListItem(modelItem, options) {\n\tconst sameIndent = !!options.sameIndent;\n\tconst smallerIndent = !!options.smallerIndent;\n\tconst indent = options.listIndent;\n\tlet item = modelItem;\n\twhile (item && item.name == \"listItem\") {\n\t\tconst itemIndent = item.getAttribute(\"listIndent\");\n\t\tif (sameIndent && indent == itemIndent || smallerIndent && indent > itemIndent) return item;\n\t\tif (options.direction === \"forward\") item = item.nextSibling;\n\t\telse item = item.previousSibling;\n\t}\n\treturn null;\n}\n/**\n* Returns a first list view element that is direct child of the given view element.\n*\n* @internal\n*/\nfunction findNestedList(viewElement) {\n\tfor (const node of viewElement.getChildren()) if (node.name == \"ul\" || node.name == \"ol\") return node;\n\treturn null;\n}\n/**\n* Returns an array with all `listItem` elements that represent the same list.\n*\n* It means that values of `listIndent`, `listType`, `listStyle`, `listReversed` and `listStart` for all items are equal.\n*\n* Additionally, if the `position` is inside a list item, that list item will be returned as well.\n*\n* @internal\n* @param position Starting position.\n* @param direction Walking direction.\n*/\nfunction getSiblingNodes(position, direction) {\n\tconst items = [];\n\tconst listItem = position.parent;\n\tconst walkerOptions = {\n\t\tignoreElementEnd: false,\n\t\tstartPosition: position,\n\t\tshallow: true,\n\t\tdirection\n\t};\n\tconst limitIndent = listItem.getAttribute(\"listIndent\");\n\tconst nodes = [...new ModelTreeWalker(walkerOptions)].filter((value) => value.item.is(\"element\")).map((value) => value.item);\n\tfor (const element of nodes) {\n\t\tif (!element.is(\"element\", \"listItem\")) break;\n\t\tif (element.getAttribute(\"listIndent\") < limitIndent) break;\n\t\tif (element.getAttribute(\"listIndent\") > limitIndent) continue;\n\t\tif (element.getAttribute(\"listType\") !== listItem.getAttribute(\"listType\")) break;\n\t\tif (element.getAttribute(\"listStyle\") !== listItem.getAttribute(\"listStyle\")) break;\n\t\tif (element.getAttribute(\"listReversed\") !== listItem.getAttribute(\"listReversed\")) break;\n\t\tif (element.getAttribute(\"listStart\") !== listItem.getAttribute(\"listStart\")) break;\n\t\tif (direction === \"backward\") items.unshift(element);\n\t\telse items.push(element);\n\t}\n\treturn items;\n}\n/**\n* Returns an array with all `listItem` elements in the model selection.\n*\n* It returns all the items even if only a part of the list is selected, including items that belong to nested lists.\n* If no list is selected, it returns an empty array.\n* The order of the elements is not specified.\n*\n* @internal\n*/\nfunction getSelectedListItems(model) {\n\tlet listItems = [...model.document.selection.getSelectedBlocks()].filter((element) => element.is(\"element\", \"listItem\")).map((element) => {\n\t\tconst position = model.change((writer) => writer.createPositionAt(element, 0));\n\t\treturn [...getSiblingNodes(position, \"backward\"), ...getSiblingNodes(position, \"forward\")];\n\t}).flat();\n\tlistItems = [...new Set(listItems)];\n\treturn listItems;\n}\nconst BULLETED_LIST_STYLE_TYPES = [\n\t\"disc\",\n\t\"circle\",\n\t\"square\"\n];\nconst NUMBERED_LIST_STYLE_TYPES = [\n\t\"decimal\",\n\t\"decimal-leading-zero\",\n\t\"lower-roman\",\n\t\"upper-roman\",\n\t\"lower-latin\",\n\t\"upper-latin\"\n];\n/**\n* Checks whether the given list-style-type is supported by numbered or bulleted list.\n*\n* @internal\n*/\nfunction getListTypeFromListStyleType$1(listStyleType) {\n\tif (BULLETED_LIST_STYLE_TYPES.includes(listStyleType)) return \"bulleted\";\n\tif (NUMBERED_LIST_STYLE_TYPES.includes(listStyleType)) return \"numbered\";\n\treturn null;\n}\n/**\n* Implementation of getFillerOffset for view list item element.\n*\n* @returns Block filler offset or `null` if block filler is not needed.\n*/\nfunction getListItemFillerOffset() {\n\tconst hasOnlyLists = !this.isEmpty && (this.getChild(0).name == \"ul\" || this.getChild(0).name == \"ol\");\n\tif (this.isEmpty || hasOnlyLists) return 0;\n\treturn getViewFillerOffset.call(this);\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* A set of helpers related to legacy lists.\n*/\nvar LegacyListUtils = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"LegacyListUtils\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* Checks whether the given list-style-type is supported by numbered or bulleted list.\n\t*/\n\tgetListTypeFromListStyleType(listStyleType) {\n\t\treturn getListTypeFromListStyleType$1(listStyleType);\n\t}\n\t/**\n\t* Returns an array with all `listItem` elements in the model selection.\n\t*\n\t* It returns all the items even if only a part of the list is selected, including items that belong to nested lists.\n\t* If no list is selected, it returns an empty array.\n\t* The order of the elements is not specified.\n\t*/\n\tgetSelectedListItems(model) {\n\t\treturn getSelectedListItems(model);\n\t}\n\t/**\n\t* Returns an array with all `listItem` elements that represent the same list.\n\t*\n\t* It means that values of `listIndent`, `listType`, `listStyle`, `listReversed` and `listStart` for all items are equal.\n\t*\n\t* Additionally, if the `position` is inside a list item, that list item will be returned as well.\n\t*\n\t* @param position Starting position.\n\t* @param direction Walking direction.\n\t*/\n\tgetSiblingNodes(position, direction) {\n\t\treturn getSiblingNodes(position, direction);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacylist/legacyconverters\n*/\n/**\n* A model-to-view converter for the `listItem` model element insertion.\n*\n* It creates a `<ul><li></li><ul>` (or `<ol>`) view structure out of a `listItem` model element, inserts it at the correct\n* position, and merges the list with surrounding lists (if available).\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n* @param model Model instance.\n*/\nfunction modelViewInsertion$1(model) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst consumable = conversionApi.consumable;\n\t\tif (!consumable.test(data.item, \"insert\") || !consumable.test(data.item, \"attribute:listType\") || !consumable.test(data.item, \"attribute:listIndent\")) return;\n\t\tconsumable.consume(data.item, \"insert\");\n\t\tconsumable.consume(data.item, \"attribute:listType\");\n\t\tconsumable.consume(data.item, \"attribute:listIndent\");\n\t\tconst modelItem = data.item;\n\t\tconst viewItem = generateLiInUl(modelItem, conversionApi);\n\t\tinjectViewList(modelItem, viewItem, conversionApi, model);\n\t};\n}\n/**\n* A model-to-view converter for the `listItem` model element removal.\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n* @param model Model instance.\n* @returns Returns a conversion callback.\n*/\nfunction modelViewRemove(model) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst viewItem = conversionApi.mapper.toViewPosition(data.position).getLastMatchingPosition((value) => !value.item.is(\"element\", \"li\")).nodeAfter;\n\t\tconst viewWriter = conversionApi.writer;\n\t\tviewWriter.breakContainer(viewWriter.createPositionBefore(viewItem));\n\t\tviewWriter.breakContainer(viewWriter.createPositionAfter(viewItem));\n\t\tconst viewList = viewItem.parent;\n\t\tconst viewListPrev = viewList.previousSibling;\n\t\tconst removeRange = viewWriter.createRangeOn(viewList);\n\t\tconst removed = viewWriter.remove(removeRange);\n\t\tif (viewListPrev && viewListPrev.nextSibling) mergeViewLists(viewWriter, viewListPrev, viewListPrev.nextSibling);\n\t\thoistNestedLists(conversionApi.mapper.toModelElement(viewItem).getAttribute(\"listIndent\") + 1, data.position, removeRange.start, viewItem, conversionApi, model);\n\t\tfor (const child of viewWriter.createRangeIn(removed).getItems()) conversionApi.mapper.unbindViewElement(child);\n\t\tevt.stop();\n\t};\n}\n/**\n* A model-to-view converter for the `type` attribute change on the `listItem` model element.\n*\n* This change means that the `<li>` element parent changes from `<ul>` to `<ol>` (or vice versa). This is accomplished\n* by breaking view elements and changing their name. The next {@link module:list/legacylist/legacyconverters~modelViewMergeAfterChangeType}\n* converter will attempt to merge split nodes.\n*\n* Splitting this conversion into 2 steps makes it possible to add an additional conversion in the middle.\n* Check {@link module:list/legacytodolist/legacytodolistconverters~modelViewChangeType} to see an example of it.\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n*/\nconst modelViewChangeType$1 = (evt, data, conversionApi) => {\n\tif (!conversionApi.consumable.test(data.item, evt.name)) return;\n\tconst viewItem = conversionApi.mapper.toViewElement(data.item);\n\tconst viewWriter = conversionApi.writer;\n\tviewWriter.breakContainer(viewWriter.createPositionBefore(viewItem));\n\tviewWriter.breakContainer(viewWriter.createPositionAfter(viewItem));\n\tconst viewList = viewItem.parent;\n\tconst listName = data.attributeNewValue == \"numbered\" ? \"ol\" : \"ul\";\n\tviewWriter.rename(listName, viewList);\n};\n/**\n* A model-to-view converter that attempts to merge nodes split by {@link module:list/legacylist/legacyconverters~modelViewChangeType}.\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n*/\nconst modelViewMergeAfterChangeType = (evt, data, conversionApi) => {\n\tconversionApi.consumable.consume(data.item, evt.name);\n\tconst viewList = conversionApi.mapper.toViewElement(data.item).parent;\n\tconst viewWriter = conversionApi.writer;\n\tmergeViewLists(viewWriter, viewList, viewList.nextSibling);\n\tmergeViewLists(viewWriter, viewList.previousSibling, viewList);\n};\n/**\n* A model-to-view converter for the `listIndent` attribute change on the `listItem` model element.\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n* @param model Model instance.\n* @returns Returns a conversion callback.\n*/\nfunction modelViewChangeIndent(model) {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!conversionApi.consumable.consume(data.item, \"attribute:listIndent\")) return;\n\t\tconst viewItem = conversionApi.mapper.toViewElement(data.item);\n\t\tconst viewWriter = conversionApi.writer;\n\t\tviewWriter.breakContainer(viewWriter.createPositionBefore(viewItem));\n\t\tviewWriter.breakContainer(viewWriter.createPositionAfter(viewItem));\n\t\tconst viewList = viewItem.parent;\n\t\tconst viewListPrev = viewList.previousSibling;\n\t\tconst removeRange = viewWriter.createRangeOn(viewList);\n\t\tviewWriter.remove(removeRange);\n\t\tif (viewListPrev && viewListPrev.nextSibling) mergeViewLists(viewWriter, viewListPrev, viewListPrev.nextSibling);\n\t\thoistNestedLists(data.attributeOldValue + 1, data.range.start, removeRange.start, viewItem, conversionApi, model);\n\t\tinjectViewList(data.item, viewItem, conversionApi, model);\n\t\tfor (const child of data.item.getChildren()) conversionApi.consumable.consume(child, \"insert\");\n\t};\n}\n/**\n* A special model-to-view converter introduced by the {@link module:list/legacylist~LegacyList list feature}. This converter is fired for\n* insert change of every model item, and should be fired before the actual converter. The converter checks whether the inserted\n* model item is a non-`listItem` element. If it is, and it is inserted inside a view list, the converter breaks the\n* list so the model element is inserted to the view parent element corresponding to its model parent element.\n*\n* The converter prevents such situations:\n*\n* ```xml\n* // Model: // View:\n* <listItem>foo</listItem> <ul>\n* <listItem>bar</listItem> <li>foo</li>\n* <li>bar</li>\n* </ul>\n*\n* // After change: // Correct view guaranteed by this converter:\n* <listItem>foo</listItem> <ul><li>foo</li></ul><p>xxx</p><ul><li>bar</li></ul>\n* <paragraph>xxx</paragraph> // Instead of this wrong view state:\n* <listItem>bar</listItem> <ul><li>foo</li><p>xxx</p><li>bar</li></ul>\n* ```\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n*/\nconst modelViewSplitOnInsert = (evt, data, conversionApi) => {\n\tif (!conversionApi.consumable.test(data.item, evt.name)) return;\n\tif (data.item.name != \"listItem\") {\n\t\tlet viewPosition = conversionApi.mapper.toViewPosition(data.range.start);\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst lists = [];\n\t\twhile (viewPosition.parent.name == \"ul\" || viewPosition.parent.name == \"ol\") {\n\t\t\tviewPosition = viewWriter.breakContainer(viewPosition);\n\t\t\tif (viewPosition.parent.name != \"li\") break;\n\t\t\tconst removeStart = viewPosition;\n\t\t\tconst removeEnd = viewWriter.createPositionAt(viewPosition.parent, \"end\");\n\t\t\tif (!removeStart.isEqual(removeEnd)) {\n\t\t\t\tconst removed = viewWriter.remove(viewWriter.createRange(removeStart, removeEnd));\n\t\t\t\tlists.push(removed);\n\t\t\t}\n\t\t\tviewPosition = viewWriter.createPositionAfter(viewPosition.parent);\n\t\t}\n\t\tif (lists.length > 0) {\n\t\t\tfor (let i = 0; i < lists.length; i++) {\n\t\t\t\tconst previousList = viewPosition.nodeBefore;\n\t\t\t\tviewPosition = viewWriter.insert(viewPosition, lists[i]).end;\n\t\t\t\tif (i > 0) {\n\t\t\t\t\tconst mergePos = mergeViewLists(viewWriter, previousList, previousList.nextSibling);\n\t\t\t\t\tif (mergePos && mergePos.parent == previousList) viewPosition.offset--;\n\t\t\t\t}\n\t\t\t}\n\t\t\tmergeViewLists(viewWriter, viewPosition.nodeBefore, viewPosition.nodeAfter);\n\t\t}\n\t}\n};\n/**\n* A special model-to-view converter introduced by the {@link module:list/legacylist~LegacyList list feature}. This converter takes care of\n* merging view lists after something is removed or moved from near them.\n*\n* Example:\n*\n* ```xml\n* // Model: // View:\n* <listItem>foo</listItem> <ul><li>foo</li></ul>\n* <paragraph>xxx</paragraph> <p>xxx</p>\n* <listItem>bar</listItem> <ul><li>bar</li></ul>\n*\n* // After change: // Correct view guaranteed by this converter:\n* <listItem>foo</listItem> <ul>\n* <listItem>bar</listItem> <li>foo</li>\n* <li>bar</li>\n* </ul>\n* ```\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n*/\nconst modelViewMergeAfter = (evt, data, conversionApi) => {\n\tconst viewPosition = conversionApi.mapper.toViewPosition(data.position);\n\tconst viewItemPrev = viewPosition.nodeBefore;\n\tconst viewItemNext = viewPosition.nodeAfter;\n\tmergeViewLists(conversionApi.writer, viewItemPrev, viewItemNext);\n};\n/**\n* A view-to-model converter that converts the `<li>` view elements into the `listItem` model elements.\n*\n* To set correct values of the `listType` and `listIndent` attributes the converter:\n* * checks `<li>`'s parent,\n* * stores and increases the `conversionApi.store.indent` value when `<li>`'s sub-items are converted.\n*\n* @internal\n* @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n*/\nconst viewModelConverter = (evt, data, conversionApi) => {\n\tif (conversionApi.consumable.consume(data.viewItem, { name: true })) {\n\t\tconst writer = conversionApi.writer;\n\t\tconst listItem = writer.createElement(\"listItem\");\n\t\tconst indent = getIndent$1(data.viewItem);\n\t\twriter.setAttribute(\"listIndent\", indent, listItem);\n\t\tconst type = data.viewItem.parent && data.viewItem.parent.name == \"ol\" ? \"numbered\" : \"bulleted\";\n\t\twriter.setAttribute(\"listType\", type, listItem);\n\t\tif (!conversionApi.safeInsert(listItem, data.modelCursor)) return;\n\t\tconst nextPosition = viewToModelListItemChildrenConverter(listItem, data.viewItem.getChildren(), conversionApi);\n\t\tdata.modelRange = writer.createRange(data.modelCursor, nextPosition);\n\t\tconversionApi.updateConversionResult(listItem, data);\n\t}\n};\n/**\n* A view-to-model converter for the `<ul>` and `<ol>` view elements that cleans the input view of garbage.\n* This is mostly to clean whitespaces from between the `<li>` view elements inside the view list element, however, also\n* incorrect data can be cleared if the view was incorrect.\n*\n* @internal\n* @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n*/\nconst cleanList = (evt, data, conversionApi) => {\n\tif (conversionApi.consumable.test(data.viewItem, { name: true })) {\n\t\tconst children = Array.from(data.viewItem.getChildren());\n\t\tfor (const child of children) if (!(child.is(\"element\", \"li\") || isList(child))) child._remove();\n\t}\n};\n/**\n* A view-to-model converter for the `<li>` elements that cleans whitespace formatting from the input view.\n*\n* @internal\n* @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n*/\nconst cleanListItem = (evt, data, conversionApi) => {\n\tif (conversionApi.consumable.test(data.viewItem, { name: true })) {\n\t\tif (data.viewItem.childCount === 0) return;\n\t\tconst children = [...data.viewItem.getChildren()];\n\t\tlet foundList = false;\n\t\tfor (const child of children) {\n\t\t\tif (foundList && !isList(child)) child._remove();\n\t\t\tif (isList(child)) foundList = true;\n\t\t}\n\t}\n};\n/**\n* Returns a callback for model position to view position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n* positions between the `listItem` elements that would be incorrectly mapped because of how list items are represented in the model\n* and in the view.\n*\n* @internal\n*/\nfunction modelToViewPosition(view) {\n\treturn (evt, data) => {\n\t\tif (data.isPhantom) return;\n\t\tconst modelItem = data.modelPosition.nodeBefore;\n\t\tif (modelItem && modelItem.is(\"element\", \"listItem\")) {\n\t\t\tconst viewItem = data.mapper.toViewElement(modelItem);\n\t\t\tconst topmostViewList = viewItem.getAncestors().find(isList);\n\t\t\tconst walker = view.createPositionAt(viewItem, 0).getWalker();\n\t\t\tfor (const value of walker) if (value.type == \"elementStart\" && value.item.is(\"element\", \"li\")) {\n\t\t\t\tdata.viewPosition = value.previousPosition;\n\t\t\t\tbreak;\n\t\t\t} else if (value.type == \"elementEnd\" && value.item == topmostViewList) {\n\t\t\t\tdata.viewPosition = value.nextPosition;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n}\n/**\n* The callback for view position to model position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n* positions between the `<li>` elements that would be incorrectly mapped because of how list items are represented in the model\n* and in the view.\n*\n* @internal\n* @see module:engine/conversion/mapper~Mapper#event:viewToModelPosition\n* @param model Model instance.\n* @returns Returns a conversion callback.\n*/\nfunction viewToModelPosition(model) {\n\treturn (evt, data) => {\n\t\tconst viewPos = data.viewPosition;\n\t\tconst viewParent = viewPos.parent;\n\t\tconst mapper = data.mapper;\n\t\tif (viewParent.name == \"ul\" || viewParent.name == \"ol\") {\n\t\t\tif (!viewPos.isAtEnd) {\n\t\t\t\tconst modelNode = mapper.toModelElement(viewPos.nodeAfter);\n\t\t\t\tdata.modelPosition = model.createPositionBefore(modelNode);\n\t\t\t} else {\n\t\t\t\tconst modelNode = mapper.toModelElement(viewPos.nodeBefore);\n\t\t\t\tconst modelLength = mapper.getModelLength(viewPos.nodeBefore);\n\t\t\t\tdata.modelPosition = model.createPositionBefore(modelNode).getShiftedBy(modelLength);\n\t\t\t}\n\t\t\tevt.stop();\n\t\t} else if (viewParent.name == \"li\" && viewPos.nodeBefore && (viewPos.nodeBefore.name == \"ul\" || viewPos.nodeBefore.name == \"ol\")) {\n\t\t\tconst modelNode = mapper.toModelElement(viewParent);\n\t\t\tlet modelLength = 1;\n\t\t\tlet viewList = viewPos.nodeBefore;\n\t\t\twhile (viewList && isList(viewList)) {\n\t\t\t\tmodelLength += mapper.getModelLength(viewList);\n\t\t\t\tviewList = viewList.previousSibling;\n\t\t\t}\n\t\t\tdata.modelPosition = model.createPositionBefore(modelNode).getShiftedBy(modelLength);\n\t\t\tevt.stop();\n\t\t}\n\t};\n}\n/**\n* Post-fixer that reacts to changes on document and fixes incorrect model states.\n*\n* In the example below, there is a correct list structure.\n* Then the middle element is removed so the list structure will become incorrect:\n*\n* ```xml\n* <listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n* <listItem listType=\"bulleted\" listIndent=1>Item 2</listItem> <--- this is removed.\n* <listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n* ```\n*\n* The list structure after the middle element is removed:\n*\n* ```xml\n* <listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n* <listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n* ```\n*\n* Should become:\n*\n* ```xml\n* <listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n* <listItem listType=\"bulleted\" listIndent=1>Item 3</listItem> <--- note that indent got post-fixed.\n* ```\n*\n* @internal\n* @param model The data model.\n* @param writer The writer to do changes with.\n* @returns `true` if any change has been applied, `false` otherwise.\n*/\nfunction modelChangePostFixer(model, writer) {\n\tconst changes = model.document.differ.getChanges();\n\tconst itemToListHead = /* @__PURE__ */ new Map();\n\tlet applied = false;\n\tfor (const entry of changes) if (entry.type == \"insert\" && entry.name == \"listItem\") _addListToFix(entry.position);\n\telse if (entry.type == \"insert\" && entry.name != \"listItem\") {\n\t\tif (entry.name != \"$text\") {\n\t\t\tconst item = entry.position.nodeAfter;\n\t\t\tif (item.hasAttribute(\"listIndent\")) {\n\t\t\t\twriter.removeAttribute(\"listIndent\", item);\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t\tif (item.hasAttribute(\"listType\")) {\n\t\t\t\twriter.removeAttribute(\"listType\", item);\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t\tif (item.hasAttribute(\"listStyle\")) {\n\t\t\t\twriter.removeAttribute(\"listStyle\", item);\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t\tif (item.hasAttribute(\"listReversed\")) {\n\t\t\t\twriter.removeAttribute(\"listReversed\", item);\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t\tif (item.hasAttribute(\"listStart\")) {\n\t\t\t\twriter.removeAttribute(\"listStart\", item);\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t\tfor (const innerItem of Array.from(model.createRangeIn(item)).filter((e) => e.item.is(\"element\", \"listItem\"))) _addListToFix(innerItem.previousPosition);\n\t\t}\n\t\t_addListToFix(entry.position.getShiftedBy(entry.length));\n\t} else if (entry.type == \"remove\" && entry.name == \"listItem\") _addListToFix(entry.position);\n\telse if (entry.type == \"attribute\" && entry.attributeKey == \"listIndent\") _addListToFix(entry.range.start);\n\telse if (entry.type == \"attribute\" && entry.attributeKey == \"listType\") _addListToFix(entry.range.start);\n\tfor (const listHead of itemToListHead.values()) {\n\t\t_fixListIndents(listHead);\n\t\t_fixListTypes(listHead);\n\t}\n\treturn applied;\n\tfunction _addListToFix(position) {\n\t\tconst previousNode = position.nodeBefore;\n\t\tif (!previousNode || !previousNode.is(\"element\", \"listItem\")) {\n\t\t\tconst item = position.nodeAfter;\n\t\t\tif (item && item.is(\"element\", \"listItem\")) itemToListHead.set(item, item);\n\t\t} else {\n\t\t\tlet listHead = previousNode;\n\t\t\tif (itemToListHead.has(listHead)) return;\n\t\t\tfor (let previousSibling = listHead.previousSibling; previousSibling && previousSibling.is(\"element\", \"listItem\"); previousSibling = listHead.previousSibling) {\n\t\t\t\tlistHead = previousSibling;\n\t\t\t\tif (itemToListHead.has(listHead)) return;\n\t\t\t}\n\t\t\titemToListHead.set(previousNode, listHead);\n\t\t}\n\t}\n\tfunction _fixListIndents(item) {\n\t\tlet maxIndent = 0;\n\t\tlet fixBy = null;\n\t\twhile (item && item.is(\"element\", \"listItem\")) {\n\t\t\tconst itemIndent = item.getAttribute(\"listIndent\");\n\t\t\tif (itemIndent > maxIndent) {\n\t\t\t\tlet newIndent;\n\t\t\t\tif (fixBy === null) {\n\t\t\t\t\tfixBy = itemIndent - maxIndent;\n\t\t\t\t\tnewIndent = maxIndent;\n\t\t\t\t} else {\n\t\t\t\t\tif (fixBy > itemIndent) fixBy = itemIndent;\n\t\t\t\t\tnewIndent = itemIndent - fixBy;\n\t\t\t\t}\n\t\t\t\twriter.setAttribute(\"listIndent\", newIndent, item);\n\t\t\t\tapplied = true;\n\t\t\t} else {\n\t\t\t\tfixBy = null;\n\t\t\t\tmaxIndent = item.getAttribute(\"listIndent\") + 1;\n\t\t\t}\n\t\t\titem = item.nextSibling;\n\t\t}\n\t}\n\tfunction _fixListTypes(item) {\n\t\tlet typesStack = [];\n\t\tlet prev = null;\n\t\twhile (item && item.is(\"element\", \"listItem\")) {\n\t\t\tconst itemIndent = item.getAttribute(\"listIndent\");\n\t\t\tif (prev && prev.getAttribute(\"listIndent\") > itemIndent) typesStack = typesStack.slice(0, itemIndent + 1);\n\t\t\tif (itemIndent != 0) if (typesStack[itemIndent]) {\n\t\t\t\tconst type = typesStack[itemIndent];\n\t\t\t\tif (item.getAttribute(\"listType\") != type) {\n\t\t\t\t\twriter.setAttribute(\"listType\", type, item);\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\t\t\t} else typesStack[itemIndent] = item.getAttribute(\"listType\");\n\t\t\tprev = item;\n\t\t\titem = item.nextSibling;\n\t\t}\n\t}\n}\n/**\n* A fixer for pasted content that includes list items.\n*\n* It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n*\n* Example:\n*\n* ```xml\n* <listItem listType=\"bulleted\" listIndent=0>A</listItem>\n* <listItem listType=\"bulleted\" listIndent=1>B^</listItem>\n* // At ^ paste: <listItem listType=\"bulleted\" listIndent=4>X</listItem>\n* // <listItem listType=\"bulleted\" listIndent=5>Y</listItem>\n* <listItem listType=\"bulleted\" listIndent=2>C</listItem>\n* ```\n*\n* Should become:\n*\n* ```xml\n* <listItem listType=\"bulleted\" listIndent=0>A</listItem>\n* <listItem listType=\"bulleted\" listIndent=1>BX</listItem>\n* <listItem listType=\"bulleted\" listIndent=2>Y/listItem>\n* <listItem listType=\"bulleted\" listIndent=2>C</listItem>\n* ```\n*\n* @internal\n*/\nconst modelIndentPasteFixer = function(evt, [content, selectable]) {\n\tconst model = this;\n\tlet item = content.is(\"documentFragment\") ? content.getChild(0) : content;\n\tlet selection;\n\tif (!selectable) selection = model.document.selection;\n\telse selection = model.createSelection(selectable);\n\tif (item && item.is(\"element\", \"listItem\")) {\n\t\tconst pos = selection.getFirstPosition();\n\t\tlet refItem = null;\n\t\tif (pos.parent.is(\"element\", \"listItem\")) refItem = pos.parent;\n\t\telse if (pos.nodeBefore && pos.nodeBefore.is(\"element\", \"listItem\")) refItem = pos.nodeBefore;\n\t\tif (refItem) {\n\t\t\tconst indentChange = refItem.getAttribute(\"listIndent\");\n\t\t\tif (indentChange > 0) while (item && item.is(\"element\", \"listItem\")) {\n\t\t\t\titem._setAttribute(\"listIndent\", item.getAttribute(\"listIndent\") + indentChange);\n\t\t\t\titem = item.nextSibling;\n\t\t\t}\n\t\t}\n\t}\n};\n/**\n* Helper function that converts children of a given `<li>` view element into corresponding model elements.\n* The function maintains proper order of elements if model `listItem` is split during the conversion\n* due to block children conversion.\n*\n* @param listItemModel List item model element to which converted children will be inserted.\n* @param viewChildren View elements which will be converted.\n* @param conversionApi Conversion interface to be used by the callback.\n* @returns Position on which next elements should be inserted after children conversion.\n*/\nfunction viewToModelListItemChildrenConverter(listItemModel, viewChildren, conversionApi) {\n\tconst { writer, schema } = conversionApi;\n\tlet nextPosition = writer.createPositionAfter(listItemModel);\n\tfor (const child of viewChildren) if (child.name == \"ul\" || child.name == \"ol\") nextPosition = conversionApi.convertItem(child, nextPosition).modelCursor;\n\telse {\n\t\tconst result = conversionApi.convertItem(child, writer.createPositionAt(listItemModel, \"end\"));\n\t\tconst convertedChild = result.modelRange.start.nodeAfter;\n\t\tif (convertedChild && convertedChild.is(\"element\") && !schema.checkChild(listItemModel, convertedChild.name)) {\n\t\t\tif (result.modelCursor.parent.is(\"element\", \"listItem\")) listItemModel = result.modelCursor.parent;\n\t\t\telse listItemModel = findNextListItem(result.modelCursor);\n\t\t\tnextPosition = writer.createPositionAfter(listItemModel);\n\t\t}\n\t}\n\treturn nextPosition;\n}\n/**\n* Helper function that seeks for a next list item starting from given `startPosition`.\n*/\nfunction findNextListItem(startPosition) {\n\tconst treeWalker = new ModelTreeWalker({ startPosition });\n\tlet value;\n\tdo\n\t\tvalue = treeWalker.next();\n\twhile (!value.value.item.is(\"element\", \"listItem\"));\n\treturn value.value.item;\n}\n/**\n* Helper function that takes all children of given `viewRemovedItem` and moves them in a correct place, according\n* to other given parameters.\n*/\nfunction hoistNestedLists(nextIndent, modelRemoveStartPosition, viewRemoveStartPosition, viewRemovedItem, conversionApi, model) {\n\tconst prevModelItem = getSiblingListItem(modelRemoveStartPosition.nodeBefore, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tlistIndent: nextIndent\n\t});\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\tconst prevIndent = prevModelItem ? prevModelItem.getAttribute(\"listIndent\") : null;\n\tlet insertPosition;\n\tif (!prevModelItem) insertPosition = viewRemoveStartPosition;\n\telse if (prevIndent == nextIndent) {\n\t\tconst prevViewList = mapper.toViewElement(prevModelItem).parent;\n\t\tinsertPosition = viewWriter.createPositionAfter(prevViewList);\n\t} else {\n\t\tconst modelPosition = model.createPositionAt(prevModelItem, \"end\");\n\t\tinsertPosition = mapper.toViewPosition(modelPosition);\n\t}\n\tinsertPosition = positionAfterUiElements(insertPosition);\n\tfor (const child of [...viewRemovedItem.getChildren()]) if (isList(child)) {\n\t\tinsertPosition = viewWriter.move(viewWriter.createRangeOn(child), insertPosition).end;\n\t\tmergeViewLists(viewWriter, child, child.nextSibling);\n\t\tmergeViewLists(viewWriter, child.previousSibling, child);\n\t}\n}\n/**\n* Checks if view element is a list type (ul or ol).\n*/\nfunction isList(viewElement) {\n\treturn viewElement.is(\"element\", \"ol\") || viewElement.is(\"element\", \"ul\");\n}\n/**\n* Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.\n*\n* Also, fixes non HTML compliant lists indents:\n*\n* ```\n* before: fixed list:\n* OL OL\n* |-> LI (parent LIs: 0) |-> LI (indent: 0)\n* |-> OL |-> OL\n* |-> OL |\n* | |-> OL |\n* | |-> OL |\n* | |-> LI (parent LIs: 1) |-> LI (indent: 1)\n* |-> LI (parent LIs: 1) |-> LI (indent: 1)\n*\n* before: fixed list:\n* OL OL\n* |-> OL |\n* |-> OL |\n* |-> OL |\n* |-> LI (parent LIs: 0) |-> LI (indent: 0)\n*\n* before: fixed list:\n* OL OL\n* |-> LI (parent LIs: 0) |-> LI (indent: 0)\n* |-> OL |-> OL\n* |-> LI (parent LIs: 0) |-> LI (indent: 1)\n* ```\n*/\nfunction getIndent$1(listItem) {\n\tlet indent = 0;\n\tlet parent = listItem.parent;\n\twhile (parent) {\n\t\tif (parent.is(\"element\", \"li\")) indent++;\n\t\telse {\n\t\t\tconst previousSibling = parent.previousSibling;\n\t\t\tif (previousSibling && previousSibling.is(\"element\", \"li\")) indent++;\n\t\t}\n\t\tparent = parent.parent;\n\t}\n\treturn indent;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacylist/legacylistediting\n*/\n/**\n* The engine of the list feature. It handles creating, editing and removing lists and list items.\n*\n* It registers the `'numberedList'`, `'bulletedList'`, `'indentList'` and `'outdentList'` commands.\n*/\nvar LegacyListEditing = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"LegacyListEditing\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [\n\t\t\tEnter,\n\t\t\tDelete,\n\t\t\tLegacyListUtils\n\t\t];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\teditor.model.schema.register(\"listItem\", {\n\t\t\tinheritAllFrom: \"$block\",\n\t\t\tallowAttributes: [\"listType\", \"listIndent\"]\n\t\t});\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\t\teditor.model.document.registerPostFixer((writer) => modelChangePostFixer(editor.model, writer));\n\t\tediting.mapper.registerViewToModelLength(\"li\", getViewListItemLength);\n\t\tdata.mapper.registerViewToModelLength(\"li\", getViewListItemLength);\n\t\tediting.mapper.on(\"modelToViewPosition\", modelToViewPosition(editing.view));\n\t\tediting.mapper.on(\"viewToModelPosition\", viewToModelPosition(editor.model));\n\t\tdata.mapper.on(\"modelToViewPosition\", modelToViewPosition(editing.view));\n\t\teditor.conversion.for(\"editingDowncast\").add((dispatcher) => {\n\t\t\tdispatcher.on(\"insert\", modelViewSplitOnInsert, { priority: \"high\" });\n\t\t\tdispatcher.on(\"insert:listItem\", modelViewInsertion$1(editor.model));\n\t\t\tdispatcher.on(\"attribute:listType:listItem\", modelViewChangeType$1, { priority: \"high\" });\n\t\t\tdispatcher.on(\"attribute:listType:listItem\", modelViewMergeAfterChangeType, { priority: \"low\" });\n\t\t\tdispatcher.on(\"attribute:listIndent:listItem\", modelViewChangeIndent(editor.model));\n\t\t\tdispatcher.on(\"remove:listItem\", modelViewRemove(editor.model));\n\t\t\tdispatcher.on(\"remove\", modelViewMergeAfter, { priority: \"low\" });\n\t\t});\n\t\teditor.conversion.for(\"dataDowncast\").add((dispatcher) => {\n\t\t\tdispatcher.on(\"insert\", modelViewSplitOnInsert, { priority: \"high\" });\n\t\t\tdispatcher.on(\"insert:listItem\", modelViewInsertion$1(editor.model));\n\t\t});\n\t\teditor.conversion.for(\"upcast\").add((dispatcher) => {\n\t\t\tdispatcher.on(\"element:ul\", cleanList, { priority: \"high\" });\n\t\t\tdispatcher.on(\"element:ol\", cleanList, { priority: \"high\" });\n\t\t\tdispatcher.on(\"element:li\", cleanListItem, { priority: \"high\" });\n\t\t\tdispatcher.on(\"element:li\", viewModelConverter);\n\t\t});\n\t\teditor.model.on(\"insertContent\", modelIndentPasteFixer, { priority: \"high\" });\n\t\teditor.commands.add(\"numberedList\", new LegacyListCommand(editor, \"numbered\"));\n\t\teditor.commands.add(\"bulletedList\", new LegacyListCommand(editor, \"bulleted\"));\n\t\teditor.commands.add(\"indentList\", new LegacyIndentCommand(editor, \"forward\"));\n\t\teditor.commands.add(\"outdentList\", new LegacyIndentCommand(editor, \"backward\"));\n\t\tconst viewDocument = editing.view.document;\n\t\tthis.listenTo(viewDocument, \"enter\", (evt, data) => {\n\t\t\tconst doc = this.editor.model.document;\n\t\t\tconst positionParent = doc.selection.getLastPosition().parent;\n\t\t\tif (doc.selection.isCollapsed && positionParent.name == \"listItem\" && positionParent.isEmpty) {\n\t\t\t\tthis.editor.execute(\"outdentList\");\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: \"li\" });\n\t\tthis.listenTo(viewDocument, \"delete\", (evt, data) => {\n\t\t\tif (data.direction !== \"backward\") return;\n\t\t\tconst selection = this.editor.model.document.selection;\n\t\t\tif (!selection.isCollapsed) return;\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\t\t\tif (!firstPosition.isAtStart) return;\n\t\t\tconst positionParent = firstPosition.parent;\n\t\t\tif (positionParent.name !== \"listItem\") return;\n\t\t\tif (positionParent.previousSibling && positionParent.previousSibling.name === \"listItem\") return;\n\t\t\tthis.editor.execute(\"outdentList\");\n\t\t\tdata.preventDefault();\n\t\t\tevt.stop();\n\t\t}, { context: \"li\" });\n\t\tthis.listenTo(editor.editing.view.document, \"tab\", (evt, data) => {\n\t\t\tconst commandName = data.shiftKey ? \"outdentList\" : \"indentList\";\n\t\t\tif (this.editor.commands.get(commandName).isEnabled) {\n\t\t\t\teditor.execute(commandName);\n\t\t\t\tdata.stopPropagation();\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: \"li\" });\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tafterInit() {\n\t\tconst commands = this.editor.commands;\n\t\tconst indent = commands.get(\"indent\");\n\t\tconst outdent = commands.get(\"outdent\");\n\t\tif (indent) indent.registerChildCommand(commands.get(\"indentList\"));\n\t\tif (outdent) outdent.registerChildCommand(commands.get(\"outdentList\"));\n\t}\n};\nfunction getViewListItemLength(element) {\n\tlet length = 1;\n\tfor (const child of element.getChildren()) if (child.name == \"ul\" || child.name == \"ol\") for (const item of child.getChildren()) length += getViewListItemLength(item);\n\treturn length;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacylist\n*/\n/**\n* The legacy list feature.\n*\n* This is a \"glue\" plugin that loads the {@link module:list/legacylist/legacylistediting~LegacyListEditing legacy list editing feature}\n* and {@link module:list/list/listui~ListUI list UI feature}.\n*/\nvar LegacyList = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [LegacyListEditing, ListUI];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"LegacyList\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacylistproperties/legacyliststylecommand\n*/\n/**\n* The list style command. It changes the `listStyle` attribute of the selected list items.\n*\n* If the list type (numbered or bulleted) can be inferred from the passed style type,\n* the command tries to convert selected items to a list of that type.\n* It is used by the {@link module:list/legacylistproperties~LegacyListProperties legacy list properties feature}.\n*/\nvar LegacyListStyleCommand = class extends Command {\n\t/**\n\t* The default type of the list style.\n\t*/\n\tdefaultType;\n\t/**\n\t* Creates an instance of the command.\n\t*\n\t* @param editor The editor instance.\n\t* @param defaultType The list type that will be used by default if the value was not specified during\n\t* the command execution.\n\t*/\n\tconstructor(editor, defaultType) {\n\t\tsuper(editor);\n\t\tthis.defaultType = defaultType;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\t/**\n\t* Executes the command.\n\t*\n\t* @fires execute\n\t* @param options.type The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default\n\t* style will be applied.\n\t*/\n\texecute(options = {}) {\n\t\tthis._tryToConvertItemsToList(options);\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems(model);\n\t\tif (!listItems.length) return;\n\t\tmodel.change((writer) => {\n\t\t\tfor (const item of listItems) writer.setAttribute(\"listStyle\", options.type || this.defaultType, item);\n\t\t});\n\t}\n\t/**\n\t* Checks the command's {@link #value}.\n\t*\n\t* @returns The current value.\n\t*/\n\t_getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition().parent;\n\t\tif (listItem && listItem.is(\"element\", \"listItem\")) return listItem.getAttribute(\"listStyle\");\n\t\treturn null;\n\t}\n\t/**\n\t* Checks whether the command can be enabled in the current context.\n\t*\n\t* @returns Whether the command should be enabled.\n\t*/\n\t_checkEnabled() {\n\t\tconst editor = this.editor;\n\t\tconst numberedList = editor.commands.get(\"numberedList\");\n\t\tconst bulletedList = editor.commands.get(\"bulletedList\");\n\t\treturn numberedList.isEnabled || bulletedList.isEnabled;\n\t}\n\t/**\n\t* Checks if the provided list style is valid. Also changes the selection to a list if it's not set yet.\n\t*\n\t* @param options Additional options.\n\t* @param options.type The type of the list style. If `null` is specified, the function does nothing.\n\t*/\n\t_tryToConvertItemsToList(options) {\n\t\tif (!options.type) return;\n\t\tconst listType = getListTypeFromListStyleType$1(options.type);\n\t\t/* istanbul ignore next -- @preserve */\n\t\tif (!listType) return;\n\t\tconst editor = this.editor;\n\t\tconst commandName = `${listType}List`;\n\t\tif (!editor.commands.get(commandName).value) editor.execute(commandName);\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacylistproperties/legacylistreversedcommand\n*/\n/**\n* The reversed list command. It changes the `listReversed` attribute of the selected list items. As a result, the list order will be\n* reversed.\n* It is used by the {@link module:list/legacylistproperties~LegacyListProperties legacy list properties feature}.\n*/\nvar LegacyListReversedCommand = class extends Command {\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tconst value = this._getValue();\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\t/**\n\t* Executes the command.\n\t*\n\t* @fires execute\n\t* @param options.reversed Whether the list should be reversed.\n\t*/\n\texecute(options = {}) {\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems(model).filter((item) => item.getAttribute(\"listType\") == \"numbered\");\n\t\tmodel.change((writer) => {\n\t\t\tfor (const item of listItems) writer.setAttribute(\"listReversed\", !!options.reversed, item);\n\t\t});\n\t}\n\t/**\n\t* Checks the command's {@link #value}.\n\t*\n\t* @returns The current value.\n\t*/\n\t_getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition().parent;\n\t\tif (listItem && listItem.is(\"element\", \"listItem\") && listItem.getAttribute(\"listType\") == \"numbered\") return listItem.getAttribute(\"listReversed\");\n\t\treturn null;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacylistproperties/legacyliststartcommand\n*/\n/**\n* The list start index command. It changes the `listStart` attribute of the selected list items.\n* It is used by the {@link module:list/legacylistproperties~LegacyListProperties legacy list properties feature}.\n*/\nvar LegacyListStartCommand = class extends Command {\n\t/**\n\t* @inheritDoc\n\t*/\n\trefresh() {\n\t\tconst value = this._getValue();\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\t/**\n\t* Executes the command.\n\t*\n\t* @fires execute\n\t* @param options Execute options.\n\t* @param options.startIndex The list start index.\n\t*/\n\texecute({ startIndex = 1 } = {}) {\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems(model).filter((item) => item.getAttribute(\"listType\") == \"numbered\");\n\t\tmodel.change((writer) => {\n\t\t\tfor (const item of listItems) writer.setAttribute(\"listStart\", startIndex >= 0 ? startIndex : 1, item);\n\t\t});\n\t}\n\t/**\n\t* Checks the command's {@link #value}.\n\t*\n\t* @returns The current value.\n\t*/\n\t_getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition().parent;\n\t\tif (listItem && listItem.is(\"element\", \"listItem\") && listItem.getAttribute(\"listType\") == \"numbered\") return listItem.getAttribute(\"listStart\");\n\t\treturn null;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacylistproperties/legacylistpropertiesediting\n*/\nconst DEFAULT_LIST_TYPE = \"default\";\n/**\n* The engine of the list properties feature.\n*\n* It sets the value for the `listItem` attribute of the {@link module:list/legacylist~LegacyList `<listItem>`} element that\n* allows modifying the list style type.\n*\n* It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.\n* Read more in {@link module:list/listconfig~ListPropertiesConfig}.\n*/\nvar LegacyListPropertiesEditing = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [LegacyListEditing];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"LegacyListPropertiesEditing\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(editor) {\n\t\tsuper(editor);\n\t\teditor.config.define(\"list\", { properties: {\n\t\t\tstyles: true,\n\t\t\tstartIndex: false,\n\t\t\treversed: false\n\t\t} });\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst strategies = createAttributeStrategies(editor.config.get(\"list.properties\"));\n\t\tmodel.schema.extend(\"listItem\", { allowAttributes: strategies.map((s) => s.attributeName) });\n\t\tfor (const strategy of strategies) strategy.addCommand(editor);\n\t\tthis.listenTo(editor.commands.get(\"indentList\"), \"_executeCleanup\", fixListAfterIndentListCommand(editor, strategies));\n\t\tthis.listenTo(editor.commands.get(\"outdentList\"), \"_executeCleanup\", fixListAfterOutdentListCommand(editor, strategies));\n\t\tthis.listenTo(editor.commands.get(\"bulletedList\"), \"_executeCleanup\", restoreDefaultListStyle(editor));\n\t\tthis.listenTo(editor.commands.get(\"numberedList\"), \"_executeCleanup\", restoreDefaultListStyle(editor));\n\t\tmodel.document.registerPostFixer(fixListAttributesOnListItemElements(editor, strategies));\n\t\teditor.conversion.for(\"upcast\").add(upcastListItemAttributes(strategies));\n\t\teditor.conversion.for(\"downcast\").add(downcastListItemAttributes(strategies));\n\t\tthis._mergeListAttributesWhileMergingLists(strategies);\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tif (editor.commands.get(\"todoList\")) editor.model.document.registerPostFixer(removeListItemAttributesFromTodoList(editor));\n\t}\n\t/**\n\t* Starts listening to {@link module:engine/model/model~Model#deleteContent} and checks whether two lists will be merged into a single\n\t* one after deleting the content.\n\t*\n\t* The purpose of this action is to adjust the `listStyle`, `listReversed` and `listStart` values\n\t* for the list that was merged.\n\t*\n\t* Consider the following model's content:\n\t*\n\t* ```xml\n\t* <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t* <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t* <paragraph>[A paragraph.]</paragraph>\n\t* <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 1</listItem>\n\t* <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 2</listItem>\n\t* ```\n\t*\n\t* After removing the paragraph element, the second list will be merged into the first one.\n\t* We want to inherit the `listStyle` attribute for the second list from the first one.\n\t*\n\t* ```xml\n\t* <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t* <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t* <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t* <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t* ```\n\t*\n\t* See https://github.com/ckeditor/ckeditor5/issues/7879.\n\t*\n\t* @param attributeStrategies Strategies for the enabled attributes.\n\t*/\n\t_mergeListAttributesWhileMergingLists(attributeStrategies) {\n\t\tconst model = this.editor.model;\n\t\tlet firstMostOuterItem;\n\t\tthis.listenTo(model, \"deleteContent\", (evt, [selection]) => {\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\t\t\tconst lastPosition = selection.getLastPosition();\n\t\t\tif (firstPosition.parent === lastPosition.parent) return;\n\t\t\tif (!firstPosition.parent.is(\"element\", \"listItem\")) return;\n\t\t\tconst nextSibling = lastPosition.parent.nextSibling;\n\t\t\tif (!nextSibling || !nextSibling.is(\"element\", \"listItem\")) return;\n\t\t\tconst mostOuterItemList = getSiblingListItem(firstPosition.parent, {\n\t\t\t\tsameIndent: true,\n\t\t\t\tlistIndent: nextSibling.getAttribute(\"listIndent\")\n\t\t\t});\n\t\t\tif (!mostOuterItemList) return;\n\t\t\tif (mostOuterItemList.getAttribute(\"listType\") === nextSibling.getAttribute(\"listType\")) firstMostOuterItem = mostOuterItemList;\n\t\t}, { priority: \"high\" });\n\t\tthis.listenTo(model, \"deleteContent\", () => {\n\t\t\tif (!firstMostOuterItem) return;\n\t\t\tmodel.change((writer) => {\n\t\t\t\tconst secondListMostOuterItem = getSiblingListItem(firstMostOuterItem.nextSibling, {\n\t\t\t\t\tsameIndent: true,\n\t\t\t\t\tlistIndent: firstMostOuterItem.getAttribute(\"listIndent\"),\n\t\t\t\t\tdirection: \"forward\"\n\t\t\t\t});\n\t\t\t\tif (!secondListMostOuterItem) {\n\t\t\t\t\tfirstMostOuterItem = null;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst items = [secondListMostOuterItem, ...getSiblingNodes(writer.createPositionAt(secondListMostOuterItem, 0), \"forward\")];\n\t\t\t\tfor (const listItem of items) for (const strategy of attributeStrategies) if (strategy.appliesToListItem(listItem)) {\n\t\t\t\t\tconst attributeName = strategy.attributeName;\n\t\t\t\t\tconst value = firstMostOuterItem.getAttribute(attributeName);\n\t\t\t\t\twriter.setAttribute(attributeName, value, listItem);\n\t\t\t\t}\n\t\t\t});\n\t\t\tfirstMostOuterItem = null;\n\t\t}, { priority: \"low\" });\n\t}\n};\n/**\n* Creates an array of strategies for dealing with enabled listItem attributes.\n*/\nfunction createAttributeStrategies(enabledProperties) {\n\tconst strategies = [];\n\tif (enabledProperties.styles) strategies.push({\n\t\tattributeName: \"listStyle\",\n\t\tdefaultValue: DEFAULT_LIST_TYPE,\n\t\taddCommand(editor) {\n\t\t\teditor.commands.add(\"listStyle\", new LegacyListStyleCommand(editor, DEFAULT_LIST_TYPE));\n\t\t},\n\t\tappliesToListItem() {\n\t\t\treturn true;\n\t\t},\n\t\tsetAttributeOnDowncast(writer, listStyle, element) {\n\t\t\tif (listStyle && listStyle !== DEFAULT_LIST_TYPE) writer.setStyle(\"list-style-type\", listStyle, element);\n\t\t\telse writer.removeStyle(\"list-style-type\", element);\n\t\t},\n\t\tgetAttributeOnUpcast(listParent) {\n\t\t\treturn normalizeListStyle(listParent.getStyle(\"list-style-type\")) || DEFAULT_LIST_TYPE;\n\t\t}\n\t});\n\tif (enabledProperties.reversed) strategies.push({\n\t\tattributeName: \"listReversed\",\n\t\tdefaultValue: false,\n\t\taddCommand(editor) {\n\t\t\teditor.commands.add(\"listReversed\", new LegacyListReversedCommand(editor));\n\t\t},\n\t\tappliesToListItem(item) {\n\t\t\treturn item.getAttribute(\"listType\") == \"numbered\";\n\t\t},\n\t\tsetAttributeOnDowncast(writer, listReversed, element) {\n\t\t\tif (listReversed) writer.setAttribute(\"reversed\", \"reversed\", element);\n\t\t\telse writer.removeAttribute(\"reversed\", element);\n\t\t},\n\t\tgetAttributeOnUpcast(listParent) {\n\t\t\treturn listParent.hasAttribute(\"reversed\");\n\t\t}\n\t});\n\tif (enabledProperties.startIndex) strategies.push({\n\t\tattributeName: \"listStart\",\n\t\tdefaultValue: 1,\n\t\taddCommand(editor) {\n\t\t\teditor.commands.add(\"listStart\", new LegacyListStartCommand(editor));\n\t\t},\n\t\tappliesToListItem(item) {\n\t\t\treturn item.getAttribute(\"listType\") == \"numbered\";\n\t\t},\n\t\tsetAttributeOnDowncast(writer, listStart, element) {\n\t\t\tif (listStart == 0 || listStart > 1) writer.setAttribute(\"start\", listStart, element);\n\t\t\telse writer.removeAttribute(\"start\", element);\n\t\t},\n\t\tgetAttributeOnUpcast(listParent) {\n\t\t\tconst startAttributeValue = listParent.getAttribute(\"start\");\n\t\t\treturn startAttributeValue >= 0 ? startAttributeValue : 1;\n\t\t}\n\t});\n\treturn strategies;\n}\n/**\n* Returns a converter consumes the `style`, `reversed` and `start` attribute.\n* In `style` it searches for the `list-style-type` definition.\n* If not found, the `\"default\"` value will be used.\n*/\nfunction upcastListItemAttributes(attributeStrategies) {\n\treturn (dispatcher) => {\n\t\tdispatcher.on(\"element:li\", (evt, data, conversionApi) => {\n\t\t\tif (!data.modelRange) return;\n\t\t\tconst listParent = data.viewItem.parent;\n\t\t\tconst listItem = data.modelRange.start.nodeAfter || data.modelRange.end.nodeBefore;\n\t\t\tfor (const strategy of attributeStrategies) if (strategy.appliesToListItem(listItem)) {\n\t\t\t\tconst listStyle = strategy.getAttributeOnUpcast(listParent);\n\t\t\t\tconversionApi.writer.setAttribute(strategy.attributeName, listStyle, listItem);\n\t\t\t}\n\t\t}, { priority: \"low\" });\n\t};\n}\n/**\n* Returns a converter that adds `reversed`, `start` attributes and adds `list-style-type` definition as a value for the `style` attribute.\n* The `\"default\"` values are removed and not present in the view/data.\n*/\nfunction downcastListItemAttributes(attributeStrategies) {\n\treturn (dispatcher) => {\n\t\tfor (const strategy of attributeStrategies) dispatcher.on(`attribute:${strategy.attributeName}:listItem`, (evt, data, conversionApi) => {\n\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\tconst currentElement = data.item;\n\t\t\tconst previousElement = getSiblingListItem(currentElement.previousSibling, {\n\t\t\t\tsameIndent: true,\n\t\t\t\tlistIndent: currentElement.getAttribute(\"listIndent\"),\n\t\t\t\tdirection: \"backward\"\n\t\t\t});\n\t\t\tconst viewItem = conversionApi.mapper.toViewElement(currentElement);\n\t\t\tif (!areRepresentingSameList(currentElement, previousElement)) viewWriter.breakContainer(viewWriter.createPositionBefore(viewItem));\n\t\t\tstrategy.setAttributeOnDowncast(viewWriter, data.attributeNewValue, viewItem.parent);\n\t\t}, { priority: \"low\" });\n\t};\n\t/**\n\t* Checks whether specified list items belong to the same list.\n\t*/\n\tfunction areRepresentingSameList(listItem1, listItem2) {\n\t\treturn listItem2 && listItem1.getAttribute(\"listType\") === listItem2.getAttribute(\"listType\") && listItem1.getAttribute(\"listIndent\") === listItem2.getAttribute(\"listIndent\") && listItem1.getAttribute(\"listStyle\") === listItem2.getAttribute(\"listStyle\") && listItem1.getAttribute(\"listReversed\") === listItem2.getAttribute(\"listReversed\") && listItem1.getAttribute(\"listStart\") === listItem2.getAttribute(\"listStart\");\n\t}\n}\n/**\n* When indenting list, nested list should clear its value for the attributes or inherit from nested lists.\n*\n* ■ List item 1.\n* ■ List item 2.[]\n* ■ List item 3.\n* editor.execute( 'indentList' );\n*\n* ■ List item 1.\n* ○ List item 2.[]\n* ■ List item 3.\n*/\nfunction fixListAfterIndentListCommand(editor, attributeStrategies) {\n\treturn (evt, changedItems) => {\n\t\tconst root = changedItems[0];\n\t\tconst rootIndent = root.getAttribute(\"listIndent\");\n\t\tconst itemsToUpdate = changedItems.filter((item) => item.getAttribute(\"listIndent\") === rootIndent);\n\t\tlet previousSibling = null;\n\t\tif (root.previousSibling.getAttribute(\"listIndent\") + 1 !== rootIndent) previousSibling = getSiblingListItem(root.previousSibling, {\n\t\t\tsameIndent: true,\n\t\t\tdirection: \"backward\",\n\t\t\tlistIndent: rootIndent\n\t\t});\n\t\teditor.model.change((writer) => {\n\t\t\tfor (const item of itemsToUpdate) for (const strategy of attributeStrategies) if (strategy.appliesToListItem(item)) {\n\t\t\t\tconst valueToSet = previousSibling == null ? strategy.defaultValue : previousSibling.getAttribute(strategy.attributeName);\n\t\t\t\twriter.setAttribute(strategy.attributeName, valueToSet, item);\n\t\t\t}\n\t\t});\n\t};\n}\n/**\n* When outdenting a list, a nested list should copy attribute values\n* from the previous sibling list item including the same value for the `listIndent` value.\n*\n* ■ List item 1.\n* ○ List item 2.[]\n* ■ List item 3.\n*\n* editor.execute( 'outdentList' );\n*\n* ■ List item 1.\n* ■ List item 2.[]\n* ■ List item 3.\n*/\nfunction fixListAfterOutdentListCommand(editor, attributeStrategies) {\n\treturn (evt, changedItems) => {\n\t\tchangedItems = changedItems.reverse().filter((item) => item.is(\"element\", \"listItem\"));\n\t\tif (!changedItems.length) return;\n\t\tconst indent = changedItems[0].getAttribute(\"listIndent\");\n\t\tconst listType = changedItems[0].getAttribute(\"listType\");\n\t\tlet listItem = changedItems[0].previousSibling;\n\t\tif (listItem.is(\"element\", \"listItem\")) while (listItem.getAttribute(\"listIndent\") !== indent) listItem = listItem.previousSibling;\n\t\telse listItem = null;\n\t\tif (!listItem) listItem = changedItems[changedItems.length - 1].nextSibling;\n\t\tif (!listItem || !listItem.is(\"element\", \"listItem\")) return;\n\t\tif (listItem.getAttribute(\"listType\") !== listType) return;\n\t\teditor.model.change((writer) => {\n\t\t\tconst itemsToUpdate = changedItems.filter((item) => item.getAttribute(\"listIndent\") === indent);\n\t\t\tfor (const item of itemsToUpdate) for (const strategy of attributeStrategies) if (strategy.appliesToListItem(item)) {\n\t\t\t\tconst attributeName = strategy.attributeName;\n\t\t\t\tconst valueToSet = listItem.getAttribute(attributeName);\n\t\t\t\twriter.setAttribute(attributeName, valueToSet, item);\n\t\t\t}\n\t\t});\n\t};\n}\n/**\n* Each `listItem` element must have specified the `listStyle`, `listReversed` and `listStart` attributes\n* if they are enabled and supported by its `listType`.\n* This post-fixer checks whether inserted elements `listItem` elements should inherit the attribute values from\n* their sibling nodes or should use the default values.\n*\n* Paragraph[]\n* ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n* ■ List item 2. // ...\n* ■ List item 3. // ...\n*\n* editor.execute( 'bulletedList' )\n*\n* ■ Paragraph[] // [listStyle=\"square\", listType=\"bulleted\"]\n* ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n* ■ List item 2.\n* ■ List item 3.\n*\n* It also covers a such change:\n*\n* [Paragraph 1\n* Paragraph 2]\n* ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n* ■ List item 2. // ...\n* ■ List item 3. // ...\n*\n* editor.execute( 'numberedList' )\n*\n* 1. [Paragraph 1 // [listStyle=\"default\", listType=\"numbered\"]\n* 2. Paragraph 2] // [listStyle=\"default\", listType=\"numbered\"]\n* ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n* ■ List item 2. // ...\n* ■ List item 3. // ...\n*/\nfunction fixListAttributesOnListItemElements(editor, attributeStrategies) {\n\treturn (writer) => {\n\t\tlet wasFixed = false;\n\t\tconst insertedListItems = getChangedListItems(editor.model.document.differ.getChanges()).filter((item) => {\n\t\t\treturn item.getAttribute(\"listType\") !== \"todo\";\n\t\t});\n\t\tif (!insertedListItems.length) return wasFixed;\n\t\tlet existingListItem = insertedListItems[insertedListItems.length - 1].nextSibling;\n\t\tif (!existingListItem || !existingListItem.is(\"element\", \"listItem\")) {\n\t\t\texistingListItem = insertedListItems[0].previousSibling;\n\t\t\tif (existingListItem) {\n\t\t\t\tconst indent = insertedListItems[0].getAttribute(\"listIndent\");\n\t\t\t\twhile (existingListItem.is(\"element\", \"listItem\") && existingListItem.getAttribute(\"listIndent\") !== indent) {\n\t\t\t\t\texistingListItem = existingListItem.previousSibling;\n\t\t\t\t\tif (!existingListItem) break;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const strategy of attributeStrategies) {\n\t\t\tconst attributeName = strategy.attributeName;\n\t\t\tfor (const item of insertedListItems) {\n\t\t\t\tif (!strategy.appliesToListItem(item)) {\n\t\t\t\t\twriter.removeAttribute(attributeName, item);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!item.hasAttribute(attributeName)) {\n\t\t\t\t\tif (shouldInheritListType(existingListItem, item, strategy)) writer.setAttribute(attributeName, existingListItem.getAttribute(attributeName), item);\n\t\t\t\t\telse writer.setAttribute(attributeName, strategy.defaultValue, item);\n\t\t\t\t\twasFixed = true;\n\t\t\t\t} else {\n\t\t\t\t\tconst previousSibling = item.previousSibling;\n\t\t\t\t\tif (shouldInheritListTypeFromPreviousItem(previousSibling, item, strategy.attributeName)) {\n\t\t\t\t\t\twriter.setAttribute(attributeName, previousSibling.getAttribute(attributeName), item);\n\t\t\t\t\t\twasFixed = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn wasFixed;\n\t};\n}\n/**\n* Checks whether the `listStyle`, `listReversed` and `listStart` attributes\n* should be copied from the `baseItem` element.\n*\n* The attribute should be copied if the inserted element does not have defined it and\n* the value for the element is other than default in the base element.\n*/\nfunction shouldInheritListType(baseItem, itemToChange, attributeStrategy) {\n\tif (!baseItem) return false;\n\tconst baseListAttribute = baseItem.getAttribute(attributeStrategy.attributeName);\n\tif (!baseListAttribute) return false;\n\tif (baseListAttribute == attributeStrategy.defaultValue) return false;\n\tif (baseItem.getAttribute(\"listType\") !== itemToChange.getAttribute(\"listType\")) return false;\n\treturn true;\n}\n/**\n* Checks whether the `listStyle`, `listReversed` and `listStart` attributes\n* should be copied from previous list item.\n*\n* The attribute should be copied if there's a mismatch of styles of the pasted list into a nested list.\n* Top-level lists are not normalized as we allow side-by-side list of different types.\n*/\nfunction shouldInheritListTypeFromPreviousItem(previousItem, itemToChange, attributeName) {\n\tif (!previousItem || !previousItem.is(\"element\", \"listItem\")) return false;\n\tif (itemToChange.getAttribute(\"listType\") !== previousItem.getAttribute(\"listType\")) return false;\n\tconst previousItemIndent = previousItem.getAttribute(\"listIndent\");\n\tif (previousItemIndent < 1 || previousItemIndent !== itemToChange.getAttribute(\"listIndent\")) return false;\n\tconst previousItemListAttribute = previousItem.getAttribute(attributeName);\n\tif (!previousItemListAttribute || previousItemListAttribute === itemToChange.getAttribute(attributeName)) return false;\n\treturn true;\n}\n/**\n* Removes the `listStyle`, `listReversed` and `listStart` attributes from \"todo\" list items.\n*/\nfunction removeListItemAttributesFromTodoList(editor) {\n\treturn (writer) => {\n\t\tconst todoListItems = getChangedListItems(editor.model.document.differ.getChanges()).filter((item) => {\n\t\t\treturn item.getAttribute(\"listType\") === \"todo\" && (item.hasAttribute(\"listStyle\") || item.hasAttribute(\"listReversed\") || item.hasAttribute(\"listStart\"));\n\t\t});\n\t\tif (!todoListItems.length) return false;\n\t\tfor (const item of todoListItems) {\n\t\t\twriter.removeAttribute(\"listStyle\", item);\n\t\t\twriter.removeAttribute(\"listReversed\", item);\n\t\t\twriter.removeAttribute(\"listStart\", item);\n\t\t}\n\t\treturn true;\n\t};\n}\n/**\n* Restores the `listStyle` attribute after changing the list type.\n*/\nfunction restoreDefaultListStyle(editor) {\n\treturn (evt, changedItems) => {\n\t\tchangedItems = changedItems.filter((item) => item.is(\"element\", \"listItem\"));\n\t\teditor.model.change((writer) => {\n\t\t\tfor (const item of changedItems) writer.removeAttribute(\"listStyle\", item);\n\t\t});\n\t};\n}\n/**\n* Returns the `listItem` that was inserted or changed.\n*\n* @param changes The changes list returned by the differ.\n*/\nfunction getChangedListItems(changes) {\n\tconst items = [];\n\tfor (const change of changes) {\n\t\tconst item = getItemFromChange(change);\n\t\tif (item && item.is(\"element\", \"listItem\")) items.push(item);\n\t}\n\treturn items;\n}\nfunction getItemFromChange(change) {\n\tif (change.type === \"attribute\") return change.range.start.nodeAfter;\n\tif (change.type === \"insert\") return change.position.nodeAfter;\n\treturn null;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacylistproperties\n*/\n/**\n* The legacy list properties feature.\n*\n* This is a \"glue\" plugin that loads the {@link module:list/legacylistproperties/legacylistpropertiesediting~LegacyListPropertiesEditing\n* legacy list properties editing feature} and the\n* {@link module:list/listproperties/listpropertiesui~ListPropertiesUI list properties UI feature}.\n*/\nvar LegacyListProperties = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [LegacyListPropertiesEditing, ListPropertiesUI];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"LegacyListProperties\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacytodolist/legacychecktodolistcommand\n*/\nconst attributeKey = \"todoListChecked\";\n/**\n* The check to-do command.\n*\n* The command is registered by the {@link module:list/legacytodolist/legacytodolistediting~LegacyTodoListEditing} as\n* the `checkTodoList` editor command and it is also available via aliased `todoListCheck` name.\n*/\nvar LegacyCheckTodoListCommand = class extends Command {\n\t/**\n\t* A list of to-do list items selected by the {@link module:engine/model/selection~ModelSelection}.\n\t*\n\t* @internal\n\t*/\n\t_selectedElements;\n\t/**\n\t* @inheritDoc\n\t*/\n\tconstructor(editor) {\n\t\tsuper(editor);\n\t\tthis._selectedElements = [];\n\t\tthis.on(\"execute\", () => {\n\t\t\tthis.refresh();\n\t\t}, { priority: \"highest\" });\n\t}\n\t/**\n\t* Updates the command's {@link #value} and {@link #isEnabled} properties based on the current selection.\n\t*/\n\trefresh() {\n\t\tthis._selectedElements = this._getSelectedItems();\n\t\tthis.value = this._selectedElements.every((element) => !!element.getAttribute(attributeKey));\n\t\tthis.isEnabled = !!this._selectedElements.length;\n\t}\n\t/**\n\t* Gets all to-do list items selected by the {@link module:engine/model/selection~ModelSelection}.\n\t*/\n\t_getSelectedItems() {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst selectionRange = model.document.selection.getFirstRange();\n\t\tconst startElement = selectionRange.start.parent;\n\t\tconst elements = [];\n\t\tif (schema.checkAttribute(startElement, attributeKey)) elements.push(startElement);\n\t\tfor (const item of selectionRange.getItems()) if (schema.checkAttribute(item, attributeKey) && !elements.includes(item)) elements.push(item);\n\t\treturn elements;\n\t}\n\t/**\n\t* Executes the command.\n\t*\n\t* @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply\n\t* the attribute. Otherwise, the command will remove the attribute. If not set, the command will look for its current\n\t* value to decide what it should do.\n\t*/\n\texecute(options = {}) {\n\t\tthis.editor.model.change((writer) => {\n\t\t\tfor (const element of this._selectedElements) if (options.forceValue === void 0 ? !this.value : options.forceValue) writer.setAttribute(attributeKey, true, element);\n\t\t\telse writer.removeAttribute(attributeKey, element);\n\t\t});\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* A model-to-view converter for the `listItem` model element insertion.\n*\n* It converts the `listItem` model element to an unordered list with a {@link module:engine/view/uielement~ViewUIElement checkbox element}\n* at the beginning of each list item. It also merges the list with surrounding lists (if available).\n*\n* It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n* @param model Model instance.\n* @param onCheckboxChecked Callback function.\n* @returns Returns a conversion callback.\n*/\nfunction modelViewInsertion(model, onCheckboxChecked) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst consumable = conversionApi.consumable;\n\t\tif (!consumable.test(data.item, \"insert\") || !consumable.test(data.item, \"attribute:listType\") || !consumable.test(data.item, \"attribute:listIndent\")) return;\n\t\tif (data.item.getAttribute(\"listType\") != \"todo\") return;\n\t\tconst modelItem = data.item;\n\t\tconsumable.consume(modelItem, \"insert\");\n\t\tconsumable.consume(modelItem, \"attribute:listType\");\n\t\tconsumable.consume(modelItem, \"attribute:listIndent\");\n\t\tconsumable.consume(modelItem, \"attribute:todoListChecked\");\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewItem = generateLiInUl(modelItem, conversionApi);\n\t\tconst checkmarkElement = createCheckmarkElement(modelItem, viewWriter, !!modelItem.getAttribute(\"todoListChecked\"), onCheckboxChecked);\n\t\tconst span = viewWriter.createContainerElement(\"span\", { class: \"todo-list__label__description\" });\n\t\tviewWriter.addClass(\"todo-list\", viewItem.parent);\n\t\tviewWriter.insert(viewWriter.createPositionAt(viewItem, 0), checkmarkElement);\n\t\tviewWriter.insert(viewWriter.createPositionAfter(checkmarkElement), span);\n\t\tinjectViewList(modelItem, viewItem, conversionApi, model);\n\t};\n}\n/**\n* A model-to-view converter for the `listItem` model element insertion.\n*\n* It is used by {@link module:engine/controller/datacontroller~DataController}.\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n* @param model Model instance.\n* @returns Returns a conversion callback.\n*/\nfunction dataModelViewInsertion(model) {\n\treturn (evt, data, conversionApi) => {\n\t\tconst consumable = conversionApi.consumable;\n\t\tif (!consumable.test(data.item, \"insert\") || !consumable.test(data.item, \"attribute:listType\") || !consumable.test(data.item, \"attribute:listIndent\")) return;\n\t\tif (data.item.getAttribute(\"listType\") != \"todo\") return;\n\t\tconst modelItem = data.item;\n\t\tconsumable.consume(modelItem, \"insert\");\n\t\tconsumable.consume(modelItem, \"attribute:listType\");\n\t\tconsumable.consume(modelItem, \"attribute:listIndent\");\n\t\tconsumable.consume(modelItem, \"attribute:todoListChecked\");\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewItem = generateLiInUl(modelItem, conversionApi);\n\t\tviewWriter.addClass(\"todo-list\", viewItem.parent);\n\t\tconst label = viewWriter.createContainerElement(\"label\", { class: \"todo-list__label\" });\n\t\tconst checkbox = viewWriter.createEmptyElement(\"input\", {\n\t\t\ttype: \"checkbox\",\n\t\t\tdisabled: \"disabled\"\n\t\t});\n\t\tconst span = viewWriter.createContainerElement(\"span\", { class: \"todo-list__label__description\" });\n\t\tif (modelItem.getAttribute(\"todoListChecked\")) viewWriter.setAttribute(\"checked\", \"checked\", checkbox);\n\t\tviewWriter.insert(viewWriter.createPositionAt(viewItem, 0), label);\n\t\tviewWriter.insert(viewWriter.createPositionAt(label, 0), checkbox);\n\t\tviewWriter.insert(viewWriter.createPositionAfter(checkbox), span);\n\t\tinjectViewList(modelItem, viewItem, conversionApi, model);\n\t};\n}\n/**\n* A view-to-model converter for the checkbox element inside a view list item.\n*\n* It changes the `listType` of the model `listItem` to a `todo` value.\n* When a view checkbox element is marked as checked, an additional `todoListChecked=\"true\"` attribute is added to the model item.\n*\n* It is used by {@link module:engine/controller/datacontroller~DataController}.\n*\n* @internal\n* @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n*/\nconst dataViewModelCheckmarkInsertion = (evt, data, conversionApi) => {\n\tconst modelCursor = data.modelCursor;\n\tconst modelItem = modelCursor.parent;\n\tconst viewItem = data.viewItem;\n\tif (viewItem.getAttribute(\"type\") != \"checkbox\" || modelItem.name != \"listItem\" || !modelCursor.isAtStart) return;\n\tif (!conversionApi.consumable.consume(viewItem, { name: true })) return;\n\tconst writer = conversionApi.writer;\n\twriter.setAttribute(\"listType\", \"todo\", modelItem);\n\tif (data.viewItem.hasAttribute(\"checked\")) writer.setAttribute(\"todoListChecked\", true, modelItem);\n\tdata.modelRange = writer.createRange(modelCursor);\n};\n/**\n* A model-to-view converter for the `listType` attribute change on the `listItem` model element.\n*\n* This change means that the `<li>` element parent changes to `<ul class=\"todo-list\">` and a\n* {@link module:engine/view/uielement~ViewUIElement checkbox UI element} is added at the beginning\n* of the list item element (or vice versa).\n*\n* This converter is preceded by {@link module:list/legacylist/legacyconverters~modelViewChangeType} and followed by\n* {@link module:list/legacylist/legacyconverters~modelViewMergeAfterChangeType} to handle splitting and merging surrounding lists\n* of the same type.\n*\n* It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n* @param onCheckedChange Callback fired after clicking the checkbox UI element.\n* @param view Editing view controller.\n* @returns Returns a conversion callback.\n*/\nfunction modelViewChangeType(onCheckedChange, view) {\n\treturn (evt, data, conversionApi) => {\n\t\tif (!conversionApi.consumable.consume(data.item, evt.name)) return;\n\t\tconst viewItem = conversionApi.mapper.toViewElement(data.item);\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst labelElement = findLabel(viewItem, view);\n\t\tif (data.attributeNewValue == \"todo\") {\n\t\t\tconst isChecked = !!data.item.getAttribute(\"todoListChecked\");\n\t\t\tconst checkmarkElement = createCheckmarkElement(data.item, viewWriter, isChecked, onCheckedChange);\n\t\t\tconst span = viewWriter.createContainerElement(\"span\", { class: \"todo-list__label__description\" });\n\t\t\tconst itemRange = viewWriter.createRangeIn(viewItem);\n\t\t\tconst nestedList = findNestedList(viewItem);\n\t\t\tconst descriptionStart = positionAfterUiElements(itemRange.start);\n\t\t\tconst descriptionEnd = nestedList ? viewWriter.createPositionBefore(nestedList) : itemRange.end;\n\t\t\tconst descriptionRange = viewWriter.createRange(descriptionStart, descriptionEnd);\n\t\t\tviewWriter.addClass(\"todo-list\", viewItem.parent);\n\t\t\tviewWriter.move(descriptionRange, viewWriter.createPositionAt(span, 0));\n\t\t\tviewWriter.insert(viewWriter.createPositionAt(viewItem, 0), checkmarkElement);\n\t\t\tviewWriter.insert(viewWriter.createPositionAfter(checkmarkElement), span);\n\t\t} else if (data.attributeOldValue == \"todo\") {\n\t\t\tconst descriptionSpan = findDescription(viewItem, view);\n\t\t\tviewWriter.removeClass(\"todo-list\", viewItem.parent);\n\t\t\tviewWriter.remove(labelElement);\n\t\t\tviewWriter.move(viewWriter.createRangeIn(descriptionSpan), viewWriter.createPositionBefore(descriptionSpan));\n\t\t\tviewWriter.remove(descriptionSpan);\n\t\t}\n\t};\n}\n/**\n* A model-to-view converter for the `todoListChecked` attribute change on the `listItem` model element.\n*\n* It marks the {@link module:engine/view/uielement~ViewUIElement checkbox UI element} as checked.\n*\n* It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n*\n* @internal\n* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n* @param onCheckedChange Callback fired after clicking the checkbox UI element.\n* @returns Returns a conversion callback.\n*/\nfunction modelViewChangeChecked(onCheckedChange) {\n\treturn (evt, data, conversionApi) => {\n\t\tif (data.item.getAttribute(\"listType\") != \"todo\") return;\n\t\tif (!conversionApi.consumable.consume(data.item, \"attribute:todoListChecked\")) return;\n\t\tconst { mapper, writer: viewWriter } = conversionApi;\n\t\tconst isChecked = !!data.item.getAttribute(\"todoListChecked\");\n\t\tconst oldCheckmarkElement = mapper.toViewElement(data.item).getChild(0);\n\t\tconst newCheckmarkElement = createCheckmarkElement(data.item, viewWriter, isChecked, onCheckedChange);\n\t\tviewWriter.insert(viewWriter.createPositionAfter(oldCheckmarkElement), newCheckmarkElement);\n\t\tviewWriter.remove(oldCheckmarkElement);\n\t};\n}\n/**\n* A model-to-view position at zero offset mapper.\n*\n* This helper ensures that position inside todo-list in the view is mapped after the checkbox.\n*\n* It only handles the position at the beginning of a list item as other positions are properly mapped be the default mapper.\n*\n* @internal\n*/\nfunction mapModelToViewPosition(view) {\n\treturn (evt, data) => {\n\t\tconst modelPosition = data.modelPosition;\n\t\tconst parent = modelPosition.parent;\n\t\tif (!parent.is(\"element\", \"listItem\") || parent.getAttribute(\"listType\") != \"todo\") return;\n\t\tconst descSpan = findDescription(data.mapper.toViewElement(parent), view);\n\t\tif (descSpan) data.viewPosition = data.mapper.findPositionIn(descSpan, modelPosition.offset);\n\t};\n}\n/**\n* Creates a checkbox UI element.\n*/\nfunction createCheckmarkElement(modelItem, viewWriter, isChecked, onChange) {\n\treturn viewWriter.createUIElement(\"label\", {\n\t\tclass: \"todo-list__label\",\n\t\tcontenteditable: false\n\t}, function(domDocument) {\n\t\tconst checkbox = createElement(document, \"input\", {\n\t\t\ttype: \"checkbox\",\n\t\t\ttabindex: \"-1\"\n\t\t});\n\t\tif (isChecked) checkbox.setAttribute(\"checked\", \"checked\");\n\t\tcheckbox.addEventListener(\"change\", () => onChange(modelItem));\n\t\tconst domElement = this.toDomElement(domDocument);\n\t\tdomElement.appendChild(checkbox);\n\t\treturn domElement;\n\t});\n}\nfunction findLabel(viewItem, view) {\n\tconst range = view.createRangeIn(viewItem);\n\tfor (const value of range) if (value.item.is(\"uiElement\", \"label\")) return value.item;\n}\nfunction findDescription(viewItem, view) {\n\tconst range = view.createRangeIn(viewItem);\n\tfor (const value of range) if (value.item.is(\"containerElement\", \"span\") && value.item.hasClass(\"todo-list__label__description\")) return value.item;\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\nconst ITEM_TOGGLE_KEYSTROKE = /* #__PURE__ */ parseKeystroke(\"Ctrl+Enter\");\n/**\n* The engine of the to-do list feature. It handles creating, editing and removing to-do lists and their items.\n*\n* It registers the entire functionality of the {@link module:list/legacylist/legacylistediting~LegacyListEditing legacy list editing\n* plugin} and extends it with the commands:\n*\n* - `'todoList'`,\n* - `'checkTodoList'`,\n* - `'todoListCheck'` as an alias for `checkTodoList` command.\n*/\nvar LegacyTodoListEditing = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"LegacyTodoListEditing\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [LegacyListEditing];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst { editing, data, model } = editor;\n\t\tmodel.schema.extend(\"listItem\", { allowAttributes: [\"todoListChecked\"] });\n\t\tmodel.schema.addAttributeCheck((context, attributeName) => {\n\t\t\tconst item = context.last;\n\t\t\tif (attributeName == \"todoListChecked\" && item.name == \"listItem\" && item.getAttribute(\"listType\") != \"todo\") return false;\n\t\t});\n\t\teditor.commands.add(\"todoList\", new LegacyListCommand(editor, \"todo\"));\n\t\tconst checkTodoListCommand = new LegacyCheckTodoListCommand(editor);\n\t\teditor.commands.add(\"checkTodoList\", checkTodoListCommand);\n\t\teditor.commands.add(\"todoListCheck\", checkTodoListCommand);\n\t\tdata.downcastDispatcher.on(\"insert:listItem\", dataModelViewInsertion(model), { priority: \"high\" });\n\t\tdata.upcastDispatcher.on(\"element:input\", dataViewModelCheckmarkInsertion, { priority: \"high\" });\n\t\tediting.downcastDispatcher.on(\"insert:listItem\", modelViewInsertion(model, (listItem) => this._handleCheckmarkChange(listItem)), { priority: \"high\" });\n\t\tediting.downcastDispatcher.on(\"attribute:listType:listItem\", modelViewChangeType((listItem) => this._handleCheckmarkChange(listItem), editing.view));\n\t\tediting.downcastDispatcher.on(\"attribute:todoListChecked:listItem\", modelViewChangeChecked((listItem) => this._handleCheckmarkChange(listItem)));\n\t\tediting.mapper.on(\"modelToViewPosition\", mapModelToViewPosition(editing.view));\n\t\tdata.mapper.on(\"modelToViewPosition\", mapModelToViewPosition(editing.view));\n\t\tthis.listenTo(editing.view.document, \"arrowKey\", jumpOverCheckmarkOnSideArrowKeyPress(model, editor.locale), { context: \"li\" });\n\t\tthis.listenTo(editing.view.document, \"keydown\", (evt, data) => {\n\t\t\tif (getCode(data) === ITEM_TOGGLE_KEYSTROKE) {\n\t\t\t\teditor.execute(\"checkTodoList\");\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: \"high\" });\n\t\tconst listItemsToFix = /* @__PURE__ */ new Set();\n\t\tthis.listenTo(model, \"applyOperation\", (evt, args) => {\n\t\t\tconst operation = args[0];\n\t\t\tif (operation.type == \"rename\" && operation.oldName == \"listItem\") {\n\t\t\t\tconst item = operation.position.nodeAfter;\n\t\t\t\tif (item.hasAttribute(\"todoListChecked\")) listItemsToFix.add(item);\n\t\t\t} else if (operation.type == \"changeAttribute\" && operation.key == \"listType\" && operation.oldValue === \"todo\") {\n\t\t\t\tfor (const item of operation.range.getItems()) if (item.hasAttribute(\"todoListChecked\") && item.getAttribute(\"listType\") !== \"todo\") listItemsToFix.add(item);\n\t\t\t}\n\t\t});\n\t\tmodel.document.registerPostFixer((writer) => {\n\t\t\tlet hasChanged = false;\n\t\t\tfor (const listItem of listItemsToFix) {\n\t\t\t\twriter.removeAttribute(\"todoListChecked\", listItem);\n\t\t\t\thasChanged = true;\n\t\t\t}\n\t\t\tlistItemsToFix.clear();\n\t\t\treturn hasChanged;\n\t\t});\n\t\tthis._initAriaAnnouncements();\n\t}\n\t/**\n\t* Handles the checkbox element change, moves the selection to the corresponding model item to make it possible\n\t* to toggle the `todoListChecked` attribute using the command, and restores the selection position.\n\t*\n\t* Some say it's a hack :) Moving the selection only for executing the command on a certain node and restoring it after,\n\t* is not a clear solution. We need to design an API for using commands beyond the selection range.\n\t* See https://github.com/ckeditor/ckeditor5/issues/1954.\n\t*/\n\t_handleCheckmarkChange(listItem) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst previousSelectionRanges = Array.from(model.document.selection.getRanges());\n\t\tmodel.change((writer) => {\n\t\t\twriter.setSelection(listItem, \"end\");\n\t\t\teditor.execute(\"checkTodoList\");\n\t\t\twriter.setSelection(previousSelectionRanges);\n\t\t});\n\t}\n\t/**\n\t* Observe when user enters or leaves todo list and set proper aria value in global live announcer.\n\t* This allows screen readers to indicate when the user has entered and left the specified todo list.\n\t*\n\t* @internal\n\t*/\n\t_initAriaAnnouncements() {\n\t\tconst { model, ui, t } = this.editor;\n\t\tlet lastFocusedCodeBlock = null;\n\t\tif (!ui) return;\n\t\tmodel.document.selection.on(\"change:range\", () => {\n\t\t\tconst focusParent = model.document.selection.focus.parent;\n\t\t\tconst lastElementIsTodoList = isLegacyTodoListItemElement(lastFocusedCodeBlock);\n\t\t\tconst currentElementIsTodoList = isLegacyTodoListItemElement(focusParent);\n\t\t\tif (lastElementIsTodoList && !currentElementIsTodoList) ui.ariaLiveAnnouncer.announce(t(\"Leaving a to-do list\"));\n\t\t\telse if (!lastElementIsTodoList && currentElementIsTodoList) ui.ariaLiveAnnouncer.announce(t(\"Entering a to-do list\"));\n\t\t\tlastFocusedCodeBlock = focusParent;\n\t\t});\n\t}\n};\n/**\n* Handles the left/right (LTR/RTL content) arrow key and moves the selection at the end of the previous block element\n* if the selection is just after the checkbox element. In other words, it jumps over the checkbox element when\n* moving the selection to the left/right (LTR/RTL).\n*\n* @returns Callback for 'keydown' events.\n*/\nfunction jumpOverCheckmarkOnSideArrowKeyPress(model, locale) {\n\treturn (eventInfo, domEventData) => {\n\t\tif (getLocalizedArrowKeyCodeDirection(domEventData.keyCode, locale.contentLanguageDirection) != \"left\") return;\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\t\tif (!selection.isCollapsed) return;\n\t\tconst position = selection.getFirstPosition();\n\t\tconst parent = position.parent;\n\t\tif (parent.name === \"listItem\" && parent.getAttribute(\"listType\") == \"todo\" && position.isAtStart) {\n\t\t\tconst newRange = schema.getNearestSelectionRange(model.createPositionBefore(parent), \"backward\");\n\t\t\tif (newRange) model.change((writer) => writer.setSelection(newRange));\n\t\t\tdomEventData.preventDefault();\n\t\t\tdomEventData.stopPropagation();\n\t\t\teventInfo.stop();\n\t\t}\n\t};\n}\n/**\n* Returns true if the given element is a list item model element of a to-do list.\n*/\nfunction isLegacyTodoListItemElement(element) {\n\treturn !!element && element.is(\"element\", \"listItem\") && element.getAttribute(\"listType\") === \"todo\";\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n/**\n* @module list/legacytodolist\n*/\n/**\n* The legacy to-do list feature.\n*\n* This is a \"glue\" plugin that loads the {@link module:list/legacytodolist/legacytodolistediting~LegacyTodoListEditing legacy to-do list\n* editing feature} and the {@link module:list/todolist/todolistui~TodoListUI to-do list UI feature}.\n*/\nvar LegacyTodoList = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get requires() {\n\t\treturn [LegacyTodoListEditing, TodoListUI];\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"LegacyTodoList\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n};\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\nvar AdjacentListsSupport = class extends Plugin {\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get pluginName() {\n\t\treturn \"AdjacentListsSupport\";\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tstatic get isOfficialPlugin() {\n\t\treturn true;\n\t}\n\t/**\n\t* @inheritDoc\n\t*/\n\tinit() {\n\t\tconst editor = this.editor;\n\t\teditor.model.schema.register(\"listSeparator\", {\n\t\t\tallowWhere: \"$block\",\n\t\t\tisBlock: true\n\t\t});\n\t\teditor.conversion.for(\"upcast\").add((dispatcher) => {\n\t\t\tdispatcher.on(\"element:ol\", listSeparatorUpcastConverter());\n\t\t\tdispatcher.on(\"element:ul\", listSeparatorUpcastConverter());\n\t\t}).elementToElement({\n\t\t\tmodel: \"listSeparator\",\n\t\t\tview: \"ck-list-separator\"\n\t\t});\n\t\teditor.conversion.for(\"editingDowncast\").elementToElement({\n\t\t\tmodel: \"listSeparator\",\n\t\t\tview: {\n\t\t\t\tname: \"div\",\n\t\t\t\tclasses: [\"ck-list-separator\", \"ck-hidden\"]\n\t\t\t}\n\t\t});\n\t\teditor.conversion.for(\"dataDowncast\").elementToElement({\n\t\t\tmodel: \"listSeparator\",\n\t\t\tview: (modelElement, conversionApi) => {\n\t\t\t\tconst viewElement = conversionApi.writer.createContainerElement(\"ck-list-separator\");\n\t\t\t\tconversionApi.writer.setCustomProperty(\"dataPipeline:transparentRendering\", true, viewElement);\n\t\t\t\tviewElement.getFillerOffset = () => null;\n\t\t\t\treturn viewElement;\n\t\t\t}\n\t\t});\n\t}\n};\n/**\n* Inserts a list separator element between two lists of the same type (`ol` + `ol` or `ul` + `ul`).\n*/\nfunction listSeparatorUpcastConverter() {\n\treturn (evt, data, conversionApi) => {\n\t\tconst element = data.viewItem;\n\t\tconst nextSibling = element.nextSibling;\n\t\tif (!nextSibling) return;\n\t\tif (element.name !== nextSibling.name) return;\n\t\tif (!data.modelRange) Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));\n\t\tconst writer = conversionApi.writer;\n\t\tconst modelElement = writer.createElement(\"listSeparator\");\n\t\tif (!conversionApi.safeInsert(modelElement, data.modelCursor)) return;\n\t\tconst parts = conversionApi.getSplitParts(modelElement);\n\t\tdata.modelRange = writer.createRange(data.modelRange.start, writer.createPositionAfter(parts[parts.length - 1]));\n\t\tconversionApi.updateConversionResult(modelElement, data);\n\t};\n}\n\n/**\n* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.\n* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options\n*/\n\nexport { AdjacentListsSupport, CheckTodoListCommand, LegacyCheckTodoListCommand, LegacyIndentCommand, LegacyList, LegacyListCommand, LegacyListEditing, LegacyListProperties, LegacyListPropertiesEditing, LegacyListReversedCommand, LegacyListStartCommand, LegacyListStyleCommand, LegacyListUtils, LegacyTodoList, LegacyTodoListEditing, List, ListCommand, ListEditing, ListFormatting, ListIndentCommand, ListItemBoldIntegration, ListItemFontColorIntegration, ListItemFontFamilyIntegration, ListItemFontSizeIntegration, ListItemItalicIntegration, ListMergeCommand, ListProperties, ListPropertiesEditing, ListPropertiesUI, ListPropertiesUtils, ListReversedCommand, ListSplitCommand, ListStartCommand, ListStyleCommand, ListUI, ListUtils, TodoList, TodoListEditing, TodoListUI, ListBlocksIterable as _ListBlocksIterable, ListItemUid as _ListItemUid, ListPropertiesView as _ListPropertiesView, ListWalker as _ListWalker, SiblingListBlocksIterator as _SiblingListBlocksIterator, TodoCheckboxChangeObserver as _TodoCheckboxChangeObserver, canBecomeSimpleListItem as _canBecomeSimpleListItem, createListElement as _createListElement, createListItemElement as _createListItemElement, createUIComponents as _createListUIComponents, createModelToViewPositionMapper as _createModelToViewListPositionMapper, expandListBlocksToCompleteItems as _expandListBlocksToCompleteItems, expandListBlocksToCompleteList as _expandListBlocksToCompleteList, findAndAddListHeadToMap as _findAndAddListHeadToMap, findMappedViewElement as _findMappedListItemViewElement, fixListIndents as _fixListIndents, fixListItemIds as _fixListItemIds, getAllListItemBlocks as _getAllListItemBlocks, getAllSupportedStyleTypes as _getAllSupportedListStyleTypes, getIndent as _getListIndent, getListItemBlocks as _getListItemBlocks, getListItems as _getListItems, getListStyleTypeFromTypeAttribute as _getListStyleTypeFromTypeAttribute, getListTypeFromListStyleType as _getListTypeFromListStyleType, getNestedListBlocks as _getNestedListBlocks, getNormalizedConfig as _getNormalizedListConfig, getSelectedBlockObject as _getSelectedBlockObject, getTypeAttributeFromListStyleType as _getTypeAttributeFromListStyleType, getViewElementIdForListType as _getViewElementIdForListType, getViewElementNameForListType as _getViewElementNameForListType, indentBlocks as _indentListBlocks, isFirstBlockOfListItem as _isFirstBlockOfListItem, isLastBlockOfListItem as _isLastBlockOfListItem, isListItemBlock as _isListItemBlock, isListItemView as _isListItemView, isListView as _isListView, isNumberedListType as _isNumberedListType, isSingleListItem as _isSingleListItem, bogusParagraphCreator as _listItemBogusParagraphCreator, listItemDowncastConverter as _listItemDowncastConverter, listItemDowncastRemoveConverter as _listItemDowncastRemoveConverter, listItemUpcastConverter as _listItemUpcastConverter, listPropertiesUpcastConverter as _listPropertiesUpcastConverter, mergeListItemBefore as _mergeListItemBefore, normalizeListStyle as _normalizeListStyle, outdentFollowingItems as _outdentFollowingListItems, outdentBlocksWithMerge as _outdentListBlocksWithMerge, reconvertItemsOnDataChange as _reconvertListItemsOnDataChange, removeListAttributes as _removeListAttributes, sortBlocks as _sortListBlocks, splitListItemBefore as _splitListItemBefore };\n//# sourceMappingURL=index.js.map"],"names":["ListWalker","startElement","options","__publicField","toArray","iterator","first","nestedItems","node","SiblingListBlocksIterator","indent","attr","direction","isListItemBlock","nodeIndent","previousNodeInList","previousNodeIndent","value","ListBlocksIterable","listHead","ListItemUid","uid","getAllListItemBlocks","listItem","getListItemBlocks","isForward","items","getNestedListBlocks","getListItems","backwardBlocks","forwardBlocks","isFirstBlockOfListItem","listBlock","isLastBlockOfListItem","expandListBlocksToCompleteItems","blocks","higherIndent","allBlocks","block","itemBlock","sortBlocks","expandListBlocksToCompleteList","splitListItemBefore","writer","id","mergeListItemBefore","parentBlock","attributes","key","indentBlocks","expand","indentBy","attributeNames","blockIndent","removeListAttributes","outdentBlocksWithMerge","visited","referenceIndent","parentBlocks","mergedBlocks","mergeListItemIfNotLast","mergedBlock","attributeKey","isSingleListItem","firstItemId","item","outdentFollowingItems","lastBlock","changedBlocks","currentIndent","newIndent","a","b","getSelectedBlockObject","model","selectedElement","canBecomeSimpleListItem","schema","isNumberedListType","listType","isFirstListItemInList","itemIndent","itemListType","itemListItemId","previous","sawHigherIndent","previousIndent","ListIndentCommand","Command","editor","indentDirection","getSelectedListBlocks","previousItemBlock","firstBlock","siblingItem","selection","firstNonListBlockIndex","ListCommand","type","document","selectedBlockObject","turnOff","itemBlocks","ListMergeCommand","shouldMergeOnBlocksContentLevel","firstElement","lastElement","firstIndent","lastIndent","lastElementId","nestedLastElementBlocks","sel","lastElementAfterDelete","nextSibling","positionParent","siblingNode","lastPosition","firstPosition","isFirstBlock","ListSplitCommand","ListItemBoldIntegration","Plugin","ListEditing","ListFormatting","listEditing","viewElement","env","context","ListItemItalicIntegration","ListItemFontSizeIntegration","normalizedFontSizeOptions","_normalizeFontSizeOptions","fontSizeOption","option","fontSizeOptions","ListItemFontColorIntegration","ListItemFontFamilyIntegration","changes","modifiedListItems","returnValue","entry","range","formats","getListItemConsistentFormat","formatAttributeName","formatValue","listItemFormatAttributeName","setFormattingToListItem","removeFormattingFromListItem","formatAttribute","listItemFormatAttribute","attributeKeys","getSingleListItemConsistentFormat","isNumberedOrBulletedList","attributesToCheck","valuesMap","walker","attributeValue","listItemBlocks","wasChanged","ListUtils","isListView","isListItemView","getIndent","parent","previousSibling","createListElement","getViewElementIdForListType","getViewElementNameForListType","createListItemElement","findAndAddListHeadToMap","position","itemToListHead","previousNode","fixListIndents","listNodes","maxIndent","prevIndent","fixBy","applied","fixListItemIds","seenIds","listItemId","listItemSkipLevelConsumer","evt","data","conversionApi","viewItem","isSkipLevelWrapper","modelRange","modelCursor","hasNestedList","child","listItemUpcastConverter","listIndent","firstItemListType","reconvertItemsOnDataChange","editing","itemsToRefresh","changedItems","doesItemBlockRequiresRefresh","collectListItemsToRefresh","stack","getListModelAttributes","fillStackForIntermediates","doesItemWrappingRequiresRefresh","i","siblingAtIndent","findSiblingListItemAt","ancestorAtLowerIndent","referenceItem","isItemBlockInsideStructureSlot","useBogus","shouldUseBogusParagraph","element","isListItemElement","isListElement","eventName","listItemDowncastConverter","strategies","dataPipeline","enableSkipLevelLists","consumer","createAttributesConsumer","mapper","consumable","findMappedViewElement","removeCustomMarkerElements","unwrapListItemBlock","wrapListItemBlock","insertCustomMarkerElements","listItemDowncastRemoveConverter","elementName","viewStart","modelEnd","viewEnd","bogusParagraphCreator","modelElement","viewWalker","createModelToViewPositionMapper","view","strategy","viewRange","positionAfterLastMarker","previousPosition","viewWriter","markersToRemove","collectMarkersToRemove","marker","markerElement","wrapper","attributeElement","parentElement","listItemIndent","currentListItem","isIntermediate","listItemViewElement","listViewElement","nextListItem","targetIndent","nonConsumingAttributes","events","attributeName","event","LIST_BASE_ATTRIBUTES","Enter","Delete","ClipboardPipeline","multiBlock","CKEditorError","attribute","commands","outdent","mergeBackwardCommand","mergeForwardCommand","previousBlock","hasNoMergeTarget","enterCommand","doc","isLastBlock","splitCommand","commandName","dispatcher","sibling","modelToViewPositionMapper","modelAttributes","modelChangePostFixer$1","clipboardPipeline","createModelIndentPasteFixer","allContentChildren","lastItem","allChildren","t","innerItem","content","selectable","refItem","refType","refIndent","firstElementIndent","indentDiff","isListItem","createUIComponents","label","icon","buttonView","_createButton","ButtonView","MenuBarMenuListItemButtonView","ButtonClass","command","ListUI","IconNumberedList","IconBulletedList","List","LIST_STYLE_TYPES","listStyle","typeAttribute"],"mappings":"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","x_google_ignoreList":[0]}