notelm-mcp 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +456 -0
  3. package/dist/auth/auth-manager.d.ts +139 -0
  4. package/dist/auth/auth-manager.d.ts.map +1 -0
  5. package/dist/auth/auth-manager.js +960 -0
  6. package/dist/auth/auth-manager.js.map +1 -0
  7. package/dist/config.d.ts +92 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +219 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/constants.d.ts +58 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/constants.js +133 -0
  14. package/dist/constants.js.map +1 -0
  15. package/dist/errors.d.ts +26 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +41 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/index.d.ts +32 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +325 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/library/notebook-library.d.ts +70 -0
  24. package/dist/library/notebook-library.d.ts.map +1 -0
  25. package/dist/library/notebook-library.js +279 -0
  26. package/dist/library/notebook-library.js.map +1 -0
  27. package/dist/library/types.d.ts +67 -0
  28. package/dist/library/types.d.ts.map +1 -0
  29. package/dist/library/types.js +8 -0
  30. package/dist/library/types.js.map +1 -0
  31. package/dist/playwright.config.d.ts +3 -0
  32. package/dist/playwright.config.d.ts.map +1 -0
  33. package/dist/playwright.config.js +38 -0
  34. package/dist/playwright.config.js.map +1 -0
  35. package/dist/resources/resource-handlers.d.ts +22 -0
  36. package/dist/resources/resource-handlers.d.ts.map +1 -0
  37. package/dist/resources/resource-handlers.js +216 -0
  38. package/dist/resources/resource-handlers.js.map +1 -0
  39. package/dist/scripts/save-auth-state.d.ts +2 -0
  40. package/dist/scripts/save-auth-state.d.ts.map +1 -0
  41. package/dist/scripts/save-auth-state.js +91 -0
  42. package/dist/scripts/save-auth-state.js.map +1 -0
  43. package/dist/session/browser-session.d.ts +108 -0
  44. package/dist/session/browser-session.d.ts.map +1 -0
  45. package/dist/session/browser-session.js +636 -0
  46. package/dist/session/browser-session.js.map +1 -0
  47. package/dist/session/session-manager.d.ts +76 -0
  48. package/dist/session/session-manager.d.ts.map +1 -0
  49. package/dist/session/session-manager.js +273 -0
  50. package/dist/session/session-manager.js.map +1 -0
  51. package/dist/session/shared-context-manager.d.ts +107 -0
  52. package/dist/session/shared-context-manager.d.ts.map +1 -0
  53. package/dist/session/shared-context-manager.js +447 -0
  54. package/dist/session/shared-context-manager.js.map +1 -0
  55. package/dist/src/auth/auth-manager.d.ts +139 -0
  56. package/dist/src/auth/auth-manager.d.ts.map +1 -0
  57. package/dist/src/auth/auth-manager.js +960 -0
  58. package/dist/src/auth/auth-manager.js.map +1 -0
  59. package/dist/src/config.d.ts +92 -0
  60. package/dist/src/config.d.ts.map +1 -0
  61. package/dist/src/config.js +219 -0
  62. package/dist/src/config.js.map +1 -0
  63. package/dist/src/constants.d.ts +58 -0
  64. package/dist/src/constants.d.ts.map +1 -0
  65. package/dist/src/constants.js +133 -0
  66. package/dist/src/constants.js.map +1 -0
  67. package/dist/src/errors.d.ts +26 -0
  68. package/dist/src/errors.d.ts.map +1 -0
  69. package/dist/src/errors.js +41 -0
  70. package/dist/src/errors.js.map +1 -0
  71. package/dist/src/index.d.ts +32 -0
  72. package/dist/src/index.d.ts.map +1 -0
  73. package/dist/src/index.js +325 -0
  74. package/dist/src/index.js.map +1 -0
  75. package/dist/src/library/notebook-library.d.ts +70 -0
  76. package/dist/src/library/notebook-library.d.ts.map +1 -0
  77. package/dist/src/library/notebook-library.js +279 -0
  78. package/dist/src/library/notebook-library.js.map +1 -0
  79. package/dist/src/library/types.d.ts +67 -0
  80. package/dist/src/library/types.d.ts.map +1 -0
  81. package/dist/src/library/types.js +8 -0
  82. package/dist/src/library/types.js.map +1 -0
  83. package/dist/src/resources/resource-handlers.d.ts +22 -0
  84. package/dist/src/resources/resource-handlers.d.ts.map +1 -0
  85. package/dist/src/resources/resource-handlers.js +216 -0
  86. package/dist/src/resources/resource-handlers.js.map +1 -0
  87. package/dist/src/scripts/health-check.d.ts +13 -0
  88. package/dist/src/scripts/health-check.d.ts.map +1 -0
  89. package/dist/src/scripts/health-check.js +100 -0
  90. package/dist/src/scripts/health-check.js.map +1 -0
  91. package/dist/src/session/browser-session.d.ts +108 -0
  92. package/dist/src/session/browser-session.d.ts.map +1 -0
  93. package/dist/src/session/browser-session.js +642 -0
  94. package/dist/src/session/browser-session.js.map +1 -0
  95. package/dist/src/session/session-manager.d.ts +76 -0
  96. package/dist/src/session/session-manager.d.ts.map +1 -0
  97. package/dist/src/session/session-manager.js +273 -0
  98. package/dist/src/session/session-manager.js.map +1 -0
  99. package/dist/src/session/shared-context-manager.d.ts +107 -0
  100. package/dist/src/session/shared-context-manager.d.ts.map +1 -0
  101. package/dist/src/session/shared-context-manager.js +447 -0
  102. package/dist/src/session/shared-context-manager.js.map +1 -0
  103. package/dist/src/tools/definitions/ask-question.d.ts +8 -0
  104. package/dist/src/tools/definitions/ask-question.d.ts.map +1 -0
  105. package/dist/src/tools/definitions/ask-question.js +211 -0
  106. package/dist/src/tools/definitions/ask-question.js.map +1 -0
  107. package/dist/src/tools/definitions/notebook-management.d.ts +3 -0
  108. package/dist/src/tools/definitions/notebook-management.d.ts.map +1 -0
  109. package/dist/src/tools/definitions/notebook-management.js +243 -0
  110. package/dist/src/tools/definitions/notebook-management.js.map +1 -0
  111. package/dist/src/tools/definitions/session-management.d.ts +3 -0
  112. package/dist/src/tools/definitions/session-management.d.ts.map +1 -0
  113. package/dist/src/tools/definitions/session-management.js +41 -0
  114. package/dist/src/tools/definitions/session-management.js.map +1 -0
  115. package/dist/src/tools/definitions/system.d.ts +3 -0
  116. package/dist/src/tools/definitions/system.d.ts.map +1 -0
  117. package/dist/src/tools/definitions/system.js +143 -0
  118. package/dist/src/tools/definitions/system.js.map +1 -0
  119. package/dist/src/tools/definitions.d.ts +12 -0
  120. package/dist/src/tools/definitions.d.ts.map +1 -0
  121. package/dist/src/tools/definitions.js +26 -0
  122. package/dist/src/tools/definitions.js.map +1 -0
  123. package/dist/src/tools/handlers.d.ts +212 -0
  124. package/dist/src/tools/handlers.d.ts.map +1 -0
  125. package/dist/src/tools/handlers.js +712 -0
  126. package/dist/src/tools/handlers.js.map +1 -0
  127. package/dist/src/tools/index.d.ts +8 -0
  128. package/dist/src/tools/index.d.ts.map +1 -0
  129. package/dist/src/tools/index.js +8 -0
  130. package/dist/src/tools/index.js.map +1 -0
  131. package/dist/src/types.d.ts +88 -0
  132. package/dist/src/types.d.ts.map +1 -0
  133. package/dist/src/types.js +5 -0
  134. package/dist/src/types.js.map +1 -0
  135. package/dist/src/utils/auth-manager.d.ts +2 -0
  136. package/dist/src/utils/auth-manager.d.ts.map +1 -0
  137. package/dist/src/utils/auth-manager.js +25 -0
  138. package/dist/src/utils/auth-manager.js.map +1 -0
  139. package/dist/src/utils/cleanup-manager.d.ts +133 -0
  140. package/dist/src/utils/cleanup-manager.d.ts.map +1 -0
  141. package/dist/src/utils/cleanup-manager.js +673 -0
  142. package/dist/src/utils/cleanup-manager.js.map +1 -0
  143. package/dist/src/utils/cli-handler.d.ts +16 -0
  144. package/dist/src/utils/cli-handler.d.ts.map +1 -0
  145. package/dist/src/utils/cli-handler.js +102 -0
  146. package/dist/src/utils/cli-handler.js.map +1 -0
  147. package/dist/src/utils/logger.d.ts +61 -0
  148. package/dist/src/utils/logger.d.ts.map +1 -0
  149. package/dist/src/utils/logger.js +92 -0
  150. package/dist/src/utils/logger.js.map +1 -0
  151. package/dist/src/utils/page-utils.d.ts +54 -0
  152. package/dist/src/utils/page-utils.d.ts.map +1 -0
  153. package/dist/src/utils/page-utils.js +381 -0
  154. package/dist/src/utils/page-utils.js.map +1 -0
  155. package/dist/src/utils/rate-limit-handler.d.ts +42 -0
  156. package/dist/src/utils/rate-limit-handler.d.ts.map +1 -0
  157. package/dist/src/utils/rate-limit-handler.js +88 -0
  158. package/dist/src/utils/rate-limit-handler.js.map +1 -0
  159. package/dist/src/utils/rate-limit-handler.test.d.ts +7 -0
  160. package/dist/src/utils/rate-limit-handler.test.d.ts.map +1 -0
  161. package/dist/src/utils/rate-limit-handler.test.js +86 -0
  162. package/dist/src/utils/rate-limit-handler.test.js.map +1 -0
  163. package/dist/src/utils/settings-manager.d.ts +37 -0
  164. package/dist/src/utils/settings-manager.d.ts.map +1 -0
  165. package/dist/src/utils/settings-manager.js +121 -0
  166. package/dist/src/utils/settings-manager.js.map +1 -0
  167. package/dist/src/utils/stealth-utils.d.ts +135 -0
  168. package/dist/src/utils/stealth-utils.d.ts.map +1 -0
  169. package/dist/src/utils/stealth-utils.js +396 -0
  170. package/dist/src/utils/stealth-utils.js.map +1 -0
  171. package/dist/src/utils/stealth-utils.test.d.ts +7 -0
  172. package/dist/src/utils/stealth-utils.test.d.ts.map +1 -0
  173. package/dist/src/utils/stealth-utils.test.js +72 -0
  174. package/dist/src/utils/stealth-utils.test.js.map +1 -0
  175. package/dist/tests/e2e/authenticated.spec.d.ts +2 -0
  176. package/dist/tests/e2e/authenticated.spec.d.ts.map +1 -0
  177. package/dist/tests/e2e/authenticated.spec.js +41 -0
  178. package/dist/tests/e2e/authenticated.spec.js.map +1 -0
  179. package/dist/tests/e2e/mocked.spec.d.ts +2 -0
  180. package/dist/tests/e2e/mocked.spec.d.ts.map +1 -0
  181. package/dist/tests/e2e/mocked.spec.js +32 -0
  182. package/dist/tests/e2e/mocked.spec.js.map +1 -0
  183. package/dist/tests/mocks/handlers.d.ts +4 -0
  184. package/dist/tests/mocks/handlers.d.ts.map +1 -0
  185. package/dist/tests/mocks/handlers.js +55 -0
  186. package/dist/tests/mocks/handlers.js.map +1 -0
  187. package/dist/tests/mocks/setup.d.ts +3 -0
  188. package/dist/tests/mocks/setup.d.ts.map +1 -0
  189. package/dist/tests/mocks/setup.js +77 -0
  190. package/dist/tests/mocks/setup.js.map +1 -0
  191. package/dist/tools/definitions/ask-question.d.ts +8 -0
  192. package/dist/tools/definitions/ask-question.d.ts.map +1 -0
  193. package/dist/tools/definitions/ask-question.js +211 -0
  194. package/dist/tools/definitions/ask-question.js.map +1 -0
  195. package/dist/tools/definitions/notebook-management.d.ts +3 -0
  196. package/dist/tools/definitions/notebook-management.d.ts.map +1 -0
  197. package/dist/tools/definitions/notebook-management.js +243 -0
  198. package/dist/tools/definitions/notebook-management.js.map +1 -0
  199. package/dist/tools/definitions/session-management.d.ts +3 -0
  200. package/dist/tools/definitions/session-management.d.ts.map +1 -0
  201. package/dist/tools/definitions/session-management.js +41 -0
  202. package/dist/tools/definitions/session-management.js.map +1 -0
  203. package/dist/tools/definitions/system.d.ts +3 -0
  204. package/dist/tools/definitions/system.d.ts.map +1 -0
  205. package/dist/tools/definitions/system.js +143 -0
  206. package/dist/tools/definitions/system.js.map +1 -0
  207. package/dist/tools/definitions.d.ts +12 -0
  208. package/dist/tools/definitions.d.ts.map +1 -0
  209. package/dist/tools/definitions.js +26 -0
  210. package/dist/tools/definitions.js.map +1 -0
  211. package/dist/tools/handlers.d.ts +212 -0
  212. package/dist/tools/handlers.d.ts.map +1 -0
  213. package/dist/tools/handlers.js +712 -0
  214. package/dist/tools/handlers.js.map +1 -0
  215. package/dist/tools/index.d.ts +8 -0
  216. package/dist/tools/index.d.ts.map +1 -0
  217. package/dist/tools/index.js +8 -0
  218. package/dist/tools/index.js.map +1 -0
  219. package/dist/types.d.ts +82 -0
  220. package/dist/types.d.ts.map +1 -0
  221. package/dist/types.js +5 -0
  222. package/dist/types.js.map +1 -0
  223. package/dist/utils/cleanup-manager.d.ts +133 -0
  224. package/dist/utils/cleanup-manager.d.ts.map +1 -0
  225. package/dist/utils/cleanup-manager.js +673 -0
  226. package/dist/utils/cleanup-manager.js.map +1 -0
  227. package/dist/utils/cli-handler.d.ts +16 -0
  228. package/dist/utils/cli-handler.d.ts.map +1 -0
  229. package/dist/utils/cli-handler.js +102 -0
  230. package/dist/utils/cli-handler.js.map +1 -0
  231. package/dist/utils/logger.d.ts +61 -0
  232. package/dist/utils/logger.d.ts.map +1 -0
  233. package/dist/utils/logger.js +92 -0
  234. package/dist/utils/logger.js.map +1 -0
  235. package/dist/utils/page-utils.d.ts +54 -0
  236. package/dist/utils/page-utils.d.ts.map +1 -0
  237. package/dist/utils/page-utils.js +381 -0
  238. package/dist/utils/page-utils.js.map +1 -0
  239. package/dist/utils/rate-limit-handler.d.ts +42 -0
  240. package/dist/utils/rate-limit-handler.d.ts.map +1 -0
  241. package/dist/utils/rate-limit-handler.js +88 -0
  242. package/dist/utils/rate-limit-handler.js.map +1 -0
  243. package/dist/utils/rate-limit-handler.test.d.ts +7 -0
  244. package/dist/utils/rate-limit-handler.test.d.ts.map +1 -0
  245. package/dist/utils/rate-limit-handler.test.js +91 -0
  246. package/dist/utils/rate-limit-handler.test.js.map +1 -0
  247. package/dist/utils/settings-manager.d.ts +37 -0
  248. package/dist/utils/settings-manager.d.ts.map +1 -0
  249. package/dist/utils/settings-manager.js +121 -0
  250. package/dist/utils/settings-manager.js.map +1 -0
  251. package/dist/utils/stealth-utils.d.ts +135 -0
  252. package/dist/utils/stealth-utils.d.ts.map +1 -0
  253. package/dist/utils/stealth-utils.js +396 -0
  254. package/dist/utils/stealth-utils.js.map +1 -0
  255. package/dist/utils/stealth-utils.test.d.ts +7 -0
  256. package/dist/utils/stealth-utils.test.d.ts.map +1 -0
  257. package/dist/utils/stealth-utils.test.js +72 -0
  258. package/dist/utils/stealth-utils.test.js.map +1 -0
  259. package/docs/01_configuration.md +94 -0
  260. package/docs/02_tools.md +34 -0
  261. package/docs/03_troubleshooting.md +59 -0
  262. package/docs/04_usage-guide.md +245 -0
  263. package/docs/05_project-analysis.qmd +309 -0
  264. package/docs/06_integration-analysis.html +914 -0
  265. package/docs/06_integration-analysis.qmd +255 -0
  266. package/docs/06_integration-analysis_files/libs/bootstrap/bootstrap-4f0954b6b0dd6bf39f4bb9151ba984db.min.css +12 -0
  267. package/docs/06_integration-analysis_files/libs/bootstrap/bootstrap-icons.css +2106 -0
  268. package/docs/06_integration-analysis_files/libs/bootstrap/bootstrap-icons.woff +0 -0
  269. package/docs/06_integration-analysis_files/libs/bootstrap/bootstrap.min.js +7 -0
  270. package/docs/06_integration-analysis_files/libs/clipboard/clipboard.min.js +7 -0
  271. package/docs/06_integration-analysis_files/libs/quarto-html/anchor.min.js +9 -0
  272. package/docs/06_integration-analysis_files/libs/quarto-html/axe/axe-check.js +145 -0
  273. package/docs/06_integration-analysis_files/libs/quarto-html/popper.min.js +6 -0
  274. package/docs/06_integration-analysis_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css +236 -0
  275. package/docs/06_integration-analysis_files/libs/quarto-html/quarto.js +847 -0
  276. package/docs/06_integration-analysis_files/libs/quarto-html/tabsets/tabsets.js +95 -0
  277. package/docs/06_integration-analysis_files/libs/quarto-html/tippy.css +1 -0
  278. package/docs/06_integration-analysis_files/libs/quarto-html/tippy.umd.min.js +2 -0
  279. package/docs/07_e2e-testing-safety.qmd +754 -0
  280. package/docs/08_project-re-evaluation.html +609 -0
  281. package/docs/08_project-re-evaluation.qmd +86 -0
  282. package/docs/08_project-re-evaluation_files/libs/bootstrap/bootstrap-4f0954b6b0dd6bf39f4bb9151ba984db.min.css +12 -0
  283. package/docs/08_project-re-evaluation_files/libs/bootstrap/bootstrap-icons.css +2106 -0
  284. package/docs/08_project-re-evaluation_files/libs/bootstrap/bootstrap-icons.woff +0 -0
  285. package/docs/08_project-re-evaluation_files/libs/bootstrap/bootstrap.min.js +7 -0
  286. package/docs/08_project-re-evaluation_files/libs/clipboard/clipboard.min.js +7 -0
  287. package/docs/08_project-re-evaluation_files/libs/quarto-html/anchor.min.js +9 -0
  288. package/docs/08_project-re-evaluation_files/libs/quarto-html/axe/axe-check.js +145 -0
  289. package/docs/08_project-re-evaluation_files/libs/quarto-html/popper.min.js +6 -0
  290. package/docs/08_project-re-evaluation_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css +236 -0
  291. package/docs/08_project-re-evaluation_files/libs/quarto-html/quarto.js +847 -0
  292. package/docs/08_project-re-evaluation_files/libs/quarto-html/tabsets/tabsets.js +95 -0
  293. package/docs/08_project-re-evaluation_files/libs/quarto-html/tippy.css +1 -0
  294. package/docs/08_project-re-evaluation_files/libs/quarto-html/tippy.umd.min.js +2 -0
  295. package/docs/notebooklm-mcp-usage.html +704 -0
  296. package/docs/notebooklm-mcp-usage.qmd +119 -0
  297. package/docs/notebooklm-mcp-usage_files/libs/bootstrap/bootstrap-6b71f2156b6a5230c6677325978bcf08.min.css +12 -0
  298. package/docs/notebooklm-mcp-usage_files/libs/bootstrap/bootstrap-icons.css +2106 -0
  299. package/docs/notebooklm-mcp-usage_files/libs/bootstrap/bootstrap-icons.woff +0 -0
  300. package/docs/notebooklm-mcp-usage_files/libs/bootstrap/bootstrap.min.js +7 -0
  301. package/docs/notebooklm-mcp-usage_files/libs/clipboard/clipboard.min.js +7 -0
  302. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/anchor.min.js +9 -0
  303. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/axe/axe-check.js +145 -0
  304. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/popper.min.js +6 -0
  305. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css +236 -0
  306. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/quarto.js +847 -0
  307. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/tabsets/tabsets.js +95 -0
  308. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/tippy.css +1 -0
  309. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/tippy.umd.min.js +2 -0
  310. package/docs/repomix-usage_files/libs/bootstrap/bootstrap-6b71f2156b6a5230c6677325978bcf08.min.css +12 -0
  311. package/docs/repomix-usage_files/libs/bootstrap/bootstrap-icons.css +2106 -0
  312. package/docs/repomix-usage_files/libs/bootstrap/bootstrap-icons.woff +0 -0
  313. package/docs/repomix-usage_files/libs/bootstrap/bootstrap.min.js +7 -0
  314. package/docs/repomix-usage_files/libs/clipboard/clipboard.min.js +7 -0
  315. package/docs/repomix-usage_files/libs/quarto-html/anchor.min.js +9 -0
  316. package/docs/repomix-usage_files/libs/quarto-html/axe/axe-check.js +145 -0
  317. package/docs/repomix-usage_files/libs/quarto-html/popper.min.js +6 -0
  318. package/docs/repomix-usage_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css +236 -0
  319. package/docs/repomix-usage_files/libs/quarto-html/quarto.js +847 -0
  320. package/docs/repomix-usage_files/libs/quarto-html/tabsets/tabsets.js +95 -0
  321. package/docs/repomix-usage_files/libs/quarto-html/tippy.css +1 -0
  322. package/docs/repomix-usage_files/libs/quarto-html/tippy.umd.min.js +2 -0
  323. package/package.json +62 -0
@@ -0,0 +1,847 @@
1
+ import * as tabsets from "./tabsets/tabsets.js";
2
+ import * as axe from "./axe/axe-check.js";
3
+
4
+ const sectionChanged = new CustomEvent("quarto-sectionChanged", {
5
+ detail: {},
6
+ bubbles: true,
7
+ cancelable: false,
8
+ composed: false,
9
+ });
10
+
11
+ const layoutMarginEls = () => {
12
+ // Find any conflicting margin elements and add margins to the
13
+ // top to prevent overlap
14
+ const marginChildren = window.document.querySelectorAll(
15
+ ".column-margin.column-container > *, .margin-caption, .aside"
16
+ );
17
+
18
+ let lastBottom = 0;
19
+ for (const marginChild of marginChildren) {
20
+ if (marginChild.offsetParent !== null) {
21
+ // clear the top margin so we recompute it
22
+ marginChild.style.marginTop = null;
23
+ const top = marginChild.getBoundingClientRect().top + window.scrollY;
24
+ if (top < lastBottom) {
25
+ const marginChildStyle = window.getComputedStyle(marginChild);
26
+ const marginBottom = parseFloat(marginChildStyle["marginBottom"]);
27
+ const margin = lastBottom - top + marginBottom;
28
+ marginChild.style.marginTop = `${margin}px`;
29
+ }
30
+ const styles = window.getComputedStyle(marginChild);
31
+ const marginTop = parseFloat(styles["marginTop"]);
32
+ lastBottom = top + marginChild.getBoundingClientRect().height + marginTop;
33
+ }
34
+ }
35
+ };
36
+
37
+ window.document.addEventListener("DOMContentLoaded", function (_event) {
38
+ // Recompute the position of margin elements anytime the body size changes
39
+ if (window.ResizeObserver) {
40
+ const resizeObserver = new window.ResizeObserver(
41
+ throttle(() => {
42
+ layoutMarginEls();
43
+ if (
44
+ window.document.body.getBoundingClientRect().width < 990 &&
45
+ isReaderMode()
46
+ ) {
47
+ quartoToggleReader();
48
+ }
49
+ }, 50)
50
+ );
51
+ resizeObserver.observe(window.document.body);
52
+ }
53
+
54
+ const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]');
55
+ const sidebarEl = window.document.getElementById("quarto-sidebar");
56
+ const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left");
57
+ const marginSidebarEl = window.document.getElementById(
58
+ "quarto-margin-sidebar"
59
+ );
60
+ // function to determine whether the element has a previous sibling that is active
61
+ const prevSiblingIsActiveLink = (el) => {
62
+ const sibling = el.previousElementSibling;
63
+ if (sibling && sibling.tagName === "A") {
64
+ return sibling.classList.contains("active");
65
+ } else {
66
+ return false;
67
+ }
68
+ };
69
+
70
+ // dispatch for htmlwidgets
71
+ // they use slideenter event to trigger resize
72
+ function fireSlideEnter() {
73
+ const event = window.document.createEvent("Event");
74
+ event.initEvent("slideenter", true, true);
75
+ window.document.dispatchEvent(event);
76
+ }
77
+
78
+ const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]');
79
+ tabs.forEach((tab) => {
80
+ tab.addEventListener("shown.bs.tab", fireSlideEnter);
81
+ });
82
+
83
+ // dispatch for shiny
84
+ // they use BS shown and hidden events to trigger rendering
85
+ function distpatchShinyEvents(previous, current) {
86
+ if (window.jQuery) {
87
+ if (previous) {
88
+ window.jQuery(previous).trigger("hidden");
89
+ }
90
+ if (current) {
91
+ window.jQuery(current).trigger("shown");
92
+ }
93
+ }
94
+ }
95
+
96
+ // tabby.js listener: Trigger event for htmlwidget and shiny
97
+ document.addEventListener(
98
+ "tabby",
99
+ function (event) {
100
+ fireSlideEnter();
101
+ distpatchShinyEvents(event.detail.previousTab, event.detail.tab);
102
+ },
103
+ false
104
+ );
105
+
106
+ // Track scrolling and mark TOC links as active
107
+ // get table of contents and sidebar (bail if we don't have at least one)
108
+ const tocLinks = tocEl
109
+ ? [...tocEl.querySelectorAll("a[data-scroll-target]")]
110
+ : [];
111
+ const makeActive = (link) => tocLinks[link].classList.add("active");
112
+ const removeActive = (link) => tocLinks[link].classList.remove("active");
113
+ const removeAllActive = () =>
114
+ [...Array(tocLinks.length).keys()].forEach((link) => removeActive(link));
115
+
116
+ // activate the anchor for a section associated with this TOC entry
117
+ tocLinks.forEach((link) => {
118
+ link.addEventListener("click", () => {
119
+ if (link.href.indexOf("#") !== -1) {
120
+ const anchor = link.href.split("#")[1];
121
+ const heading = window.document.querySelector(
122
+ `[data-anchor-id="${anchor}"]`
123
+ );
124
+ if (heading) {
125
+ // Add the class
126
+ heading.classList.add("reveal-anchorjs-link");
127
+
128
+ // function to show the anchor
129
+ const handleMouseout = () => {
130
+ heading.classList.remove("reveal-anchorjs-link");
131
+ heading.removeEventListener("mouseout", handleMouseout);
132
+ };
133
+
134
+ // add a function to clear the anchor when the user mouses out of it
135
+ heading.addEventListener("mouseout", handleMouseout);
136
+ }
137
+ }
138
+ });
139
+ });
140
+
141
+ const sections = tocLinks.map((link) => {
142
+ const target = link.getAttribute("data-scroll-target");
143
+ if (target.startsWith("#")) {
144
+ return window.document.getElementById(decodeURI(`${target.slice(1)}`));
145
+ } else {
146
+ return window.document.querySelector(decodeURI(`${target}`));
147
+ }
148
+ });
149
+
150
+ const sectionMargin = 200;
151
+ let currentActive = 0;
152
+ // track whether we've initialized state the first time
153
+ let init = false;
154
+
155
+ const updateActiveLink = () => {
156
+ // The index from bottom to top (e.g. reversed list)
157
+ let sectionIndex = -1;
158
+ if (
159
+ window.innerHeight + window.pageYOffset >=
160
+ window.document.body.offsetHeight
161
+ ) {
162
+ // This is the no-scroll case where last section should be the active one
163
+ sectionIndex = 0;
164
+ } else {
165
+ // This finds the last section visible on screen that should be made active
166
+ sectionIndex = [...sections].reverse().findIndex((section) => {
167
+ if (section) {
168
+ return window.pageYOffset >= section.offsetTop - sectionMargin;
169
+ } else {
170
+ return false;
171
+ }
172
+ });
173
+ }
174
+ if (sectionIndex > -1) {
175
+ const current = sections.length - sectionIndex - 1;
176
+ if (current !== currentActive) {
177
+ removeAllActive();
178
+ currentActive = current;
179
+ makeActive(current);
180
+ if (init) {
181
+ window.dispatchEvent(sectionChanged);
182
+ }
183
+ init = true;
184
+ }
185
+ }
186
+ };
187
+
188
+ const inHiddenRegion = (top, bottom, hiddenRegions) => {
189
+ for (const region of hiddenRegions) {
190
+ if (top <= region.bottom && bottom >= region.top) {
191
+ return true;
192
+ }
193
+ }
194
+ return false;
195
+ };
196
+
197
+ const categorySelector = "header.quarto-title-block .quarto-category";
198
+ const activateCategories = (href) => {
199
+ // Find any categories
200
+ // Surround them with a link pointing back to:
201
+ // #category=Authoring
202
+ try {
203
+ const categoryEls = window.document.querySelectorAll(categorySelector);
204
+ for (const categoryEl of categoryEls) {
205
+ const categoryText = categoryEl.textContent;
206
+ if (categoryText) {
207
+ const link = `${href}#category=${encodeURIComponent(categoryText)}`;
208
+ const linkEl = window.document.createElement("a");
209
+ linkEl.setAttribute("href", link);
210
+ for (const child of categoryEl.childNodes) {
211
+ linkEl.append(child);
212
+ }
213
+ categoryEl.appendChild(linkEl);
214
+ }
215
+ }
216
+ } catch {
217
+ // Ignore errors
218
+ }
219
+ };
220
+ function hasTitleCategories() {
221
+ return window.document.querySelector(categorySelector) !== null;
222
+ }
223
+
224
+ function offsetRelativeUrl(url) {
225
+ const offset = getMeta("quarto:offset");
226
+ return offset ? offset + url : url;
227
+ }
228
+
229
+ function offsetAbsoluteUrl(url) {
230
+ const offset = getMeta("quarto:offset");
231
+ const baseUrl = new URL(offset, window.location);
232
+
233
+ const projRelativeUrl = url.replace(baseUrl, "");
234
+ if (projRelativeUrl.startsWith("/")) {
235
+ return projRelativeUrl;
236
+ } else {
237
+ return "/" + projRelativeUrl;
238
+ }
239
+ }
240
+
241
+ // read a meta tag value
242
+ function getMeta(metaName) {
243
+ const metas = window.document.getElementsByTagName("meta");
244
+ for (let i = 0; i < metas.length; i++) {
245
+ if (metas[i].getAttribute("name") === metaName) {
246
+ return metas[i].getAttribute("content");
247
+ }
248
+ }
249
+ return "";
250
+ }
251
+
252
+ async function findAndActivateCategories() {
253
+ // Categories search with listing only use path without query
254
+ const currentPagePath = offsetAbsoluteUrl(
255
+ window.location.origin + window.location.pathname
256
+ );
257
+ const response = await fetch(offsetRelativeUrl("listings.json"));
258
+ if (response.status == 200) {
259
+ return response.json().then(function (listingPaths) {
260
+ const listingHrefs = [];
261
+ for (const listingPath of listingPaths) {
262
+ const pathWithoutLeadingSlash = listingPath.listing.substring(1);
263
+ for (const item of listingPath.items) {
264
+ const encodedItem = encodeURI(item);
265
+ if (
266
+ encodedItem === currentPagePath ||
267
+ encodedItem === currentPagePath + "index.html"
268
+ ) {
269
+ // Resolve this path against the offset to be sure
270
+ // we already are using the correct path to the listing
271
+ // (this adjusts the listing urls to be rooted against
272
+ // whatever root the page is actually running against)
273
+ const relative = offsetRelativeUrl(pathWithoutLeadingSlash);
274
+ const baseUrl = window.location;
275
+ const resolvedPath = new URL(relative, baseUrl);
276
+ listingHrefs.push(resolvedPath.pathname);
277
+ break;
278
+ }
279
+ }
280
+ }
281
+
282
+ // Look up the tree for a nearby linting and use that if we find one
283
+ const nearestListing = findNearestParentListing(
284
+ offsetAbsoluteUrl(window.location.pathname),
285
+ listingHrefs
286
+ );
287
+ if (nearestListing) {
288
+ activateCategories(nearestListing);
289
+ } else {
290
+ // See if the referrer is a listing page for this item
291
+ const referredRelativePath = offsetAbsoluteUrl(document.referrer);
292
+ const referrerListing = listingHrefs.find((listingHref) => {
293
+ const isListingReferrer =
294
+ listingHref === referredRelativePath ||
295
+ listingHref === referredRelativePath + "index.html";
296
+ return isListingReferrer;
297
+ });
298
+
299
+ if (referrerListing) {
300
+ // Try to use the referrer if possible
301
+ activateCategories(referrerListing);
302
+ } else if (listingHrefs.length > 0) {
303
+ // Otherwise, just fall back to the first listing
304
+ activateCategories(listingHrefs[0]);
305
+ }
306
+ }
307
+ });
308
+ }
309
+ }
310
+ if (hasTitleCategories()) {
311
+ findAndActivateCategories();
312
+ }
313
+
314
+ const findNearestParentListing = (href, listingHrefs) => {
315
+ if (!href || !listingHrefs) {
316
+ return undefined;
317
+ }
318
+ // Look up the tree for a nearby linting and use that if we find one
319
+ const relativeParts = href.substring(1).split("/");
320
+ while (relativeParts.length > 0) {
321
+ const path = relativeParts.join("/");
322
+ for (const listingHref of listingHrefs) {
323
+ if (listingHref.startsWith(path)) {
324
+ return listingHref;
325
+ }
326
+ }
327
+ relativeParts.pop();
328
+ }
329
+
330
+ return undefined;
331
+ };
332
+
333
+ const manageSidebarVisiblity = (el, placeholderDescriptor) => {
334
+ let isVisible = true;
335
+ let elRect;
336
+
337
+ return (hiddenRegions) => {
338
+ if (el === null) {
339
+ return;
340
+ }
341
+
342
+ // Find the last element of the TOC
343
+ const lastChildEl = el.lastElementChild;
344
+
345
+ if (lastChildEl) {
346
+ // Converts the sidebar to a menu
347
+ const convertToMenu = () => {
348
+ for (const child of el.children) {
349
+ child.style.opacity = 0;
350
+ child.style.overflow = "hidden";
351
+ child.style.pointerEvents = "none";
352
+ }
353
+
354
+ nexttick(() => {
355
+ const toggleContainer = window.document.createElement("div");
356
+ toggleContainer.style.width = "100%";
357
+ toggleContainer.classList.add("zindex-over-content");
358
+ toggleContainer.classList.add("quarto-sidebar-toggle");
359
+ toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom
360
+ toggleContainer.id = placeholderDescriptor.id;
361
+ toggleContainer.style.position = "fixed";
362
+
363
+ const toggleIcon = window.document.createElement("i");
364
+ toggleIcon.classList.add("quarto-sidebar-toggle-icon");
365
+ toggleIcon.classList.add("bi");
366
+ toggleIcon.classList.add("bi-caret-down-fill");
367
+
368
+ const toggleTitle = window.document.createElement("div");
369
+ const titleEl = window.document.body.querySelector(
370
+ placeholderDescriptor.titleSelector
371
+ );
372
+ if (titleEl) {
373
+ toggleTitle.append(
374
+ titleEl.textContent || titleEl.innerText,
375
+ toggleIcon
376
+ );
377
+ }
378
+ toggleTitle.classList.add("zindex-over-content");
379
+ toggleTitle.classList.add("quarto-sidebar-toggle-title");
380
+ toggleContainer.append(toggleTitle);
381
+
382
+ const toggleContents = window.document.createElement("div");
383
+ toggleContents.classList = el.classList;
384
+ toggleContents.classList.add("zindex-over-content");
385
+ toggleContents.classList.add("quarto-sidebar-toggle-contents");
386
+ for (const child of el.children) {
387
+ if (child.id === "toc-title") {
388
+ continue;
389
+ }
390
+
391
+ const clone = child.cloneNode(true);
392
+ clone.style.opacity = 1;
393
+ clone.style.pointerEvents = null;
394
+ clone.style.display = null;
395
+ toggleContents.append(clone);
396
+ }
397
+ toggleContents.style.height = "0px";
398
+ const positionToggle = () => {
399
+ // position the element (top left of parent, same width as parent)
400
+ if (!elRect) {
401
+ elRect = el.getBoundingClientRect();
402
+ }
403
+ toggleContainer.style.left = `${elRect.left}px`;
404
+ toggleContainer.style.top = `${elRect.top}px`;
405
+ toggleContainer.style.width = `${elRect.width}px`;
406
+ };
407
+ positionToggle();
408
+
409
+ toggleContainer.append(toggleContents);
410
+ el.parentElement.prepend(toggleContainer);
411
+
412
+ // Process clicks
413
+ let tocShowing = false;
414
+ // Allow the caller to control whether this is dismissed
415
+ // when it is clicked (e.g. sidebar navigation supports
416
+ // opening and closing the nav tree, so don't dismiss on click)
417
+ const clickEl = placeholderDescriptor.dismissOnClick
418
+ ? toggleContainer
419
+ : toggleTitle;
420
+
421
+ const closeToggle = () => {
422
+ if (tocShowing) {
423
+ toggleContainer.classList.remove("expanded");
424
+ toggleContents.style.height = "0px";
425
+ tocShowing = false;
426
+ }
427
+ };
428
+
429
+ // Get rid of any expanded toggle if the user scrolls
430
+ window.document.addEventListener(
431
+ "scroll",
432
+ throttle(() => {
433
+ closeToggle();
434
+ }, 50)
435
+ );
436
+
437
+ // Handle positioning of the toggle
438
+ window.addEventListener(
439
+ "resize",
440
+ throttle(() => {
441
+ elRect = undefined;
442
+ positionToggle();
443
+ }, 50)
444
+ );
445
+
446
+ window.addEventListener("quarto-hrChanged", () => {
447
+ elRect = undefined;
448
+ });
449
+
450
+ // Process the click
451
+ clickEl.onclick = () => {
452
+ if (!tocShowing) {
453
+ toggleContainer.classList.add("expanded");
454
+ toggleContents.style.height = null;
455
+ tocShowing = true;
456
+ } else {
457
+ closeToggle();
458
+ }
459
+ };
460
+ });
461
+ };
462
+
463
+ // Converts a sidebar from a menu back to a sidebar
464
+ const convertToSidebar = () => {
465
+ for (const child of el.children) {
466
+ child.style.opacity = 1;
467
+ child.style.overflow = null;
468
+ child.style.pointerEvents = null;
469
+ }
470
+
471
+ const placeholderEl = window.document.getElementById(
472
+ placeholderDescriptor.id
473
+ );
474
+ if (placeholderEl) {
475
+ placeholderEl.remove();
476
+ }
477
+
478
+ el.classList.remove("rollup");
479
+ };
480
+
481
+ if (isReaderMode()) {
482
+ convertToMenu();
483
+ isVisible = false;
484
+ } else {
485
+ // Find the top and bottom o the element that is being managed
486
+ const elTop = el.offsetTop;
487
+ const elBottom =
488
+ elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight;
489
+
490
+ if (!isVisible) {
491
+ // If the element is current not visible reveal if there are
492
+ // no conflicts with overlay regions
493
+ if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) {
494
+ convertToSidebar();
495
+ isVisible = true;
496
+ }
497
+ } else {
498
+ // If the element is visible, hide it if it conflicts with overlay regions
499
+ // and insert a placeholder toggle (or if we're in reader mode)
500
+ if (inHiddenRegion(elTop, elBottom, hiddenRegions)) {
501
+ convertToMenu();
502
+ isVisible = false;
503
+ }
504
+ }
505
+ }
506
+ }
507
+ };
508
+ };
509
+
510
+ const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]');
511
+ for (const tabEl of tabEls) {
512
+ const id = tabEl.getAttribute("data-bs-target");
513
+ if (id) {
514
+ const columnEl = document.querySelector(
515
+ `${id} .column-margin, .tabset-margin-content`
516
+ );
517
+ if (columnEl)
518
+ tabEl.addEventListener("shown.bs.tab", function (event) {
519
+ const el = event.srcElement;
520
+ if (el) {
521
+ const visibleCls = `${el.id}-margin-content`;
522
+ // walk up until we find a parent tabset
523
+ let panelTabsetEl = el.parentElement;
524
+ while (panelTabsetEl) {
525
+ if (panelTabsetEl.classList.contains("panel-tabset")) {
526
+ break;
527
+ }
528
+ panelTabsetEl = panelTabsetEl.parentElement;
529
+ }
530
+
531
+ if (panelTabsetEl) {
532
+ const prevSib = panelTabsetEl.previousElementSibling;
533
+ if (
534
+ prevSib &&
535
+ prevSib.classList.contains("tabset-margin-container")
536
+ ) {
537
+ const childNodes = prevSib.querySelectorAll(
538
+ ".tabset-margin-content"
539
+ );
540
+ for (const childEl of childNodes) {
541
+ if (childEl.classList.contains(visibleCls)) {
542
+ childEl.classList.remove("collapse");
543
+ } else {
544
+ childEl.classList.add("collapse");
545
+ }
546
+ }
547
+ }
548
+ }
549
+ }
550
+
551
+ layoutMarginEls();
552
+ });
553
+ }
554
+ }
555
+
556
+ // Manage the visibility of the toc and the sidebar
557
+ const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, {
558
+ id: "quarto-toc-toggle",
559
+ titleSelector: "#toc-title",
560
+ dismissOnClick: true,
561
+ });
562
+ const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, {
563
+ id: "quarto-sidebarnav-toggle",
564
+ titleSelector: ".title",
565
+ dismissOnClick: false,
566
+ });
567
+ let tocLeftScrollVisibility;
568
+ if (leftTocEl) {
569
+ tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, {
570
+ id: "quarto-lefttoc-toggle",
571
+ titleSelector: "#toc-title",
572
+ dismissOnClick: true,
573
+ });
574
+ }
575
+
576
+ // Find the first element that uses formatting in special columns
577
+ const conflictingEls = window.document.body.querySelectorAll(
578
+ '[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]'
579
+ );
580
+
581
+ // Filter all the possibly conflicting elements into ones
582
+ // the do conflict on the left or ride side
583
+ const arrConflictingEls = Array.from(conflictingEls);
584
+ const leftSideConflictEls = arrConflictingEls.filter((el) => {
585
+ if (el.tagName === "ASIDE") {
586
+ return false;
587
+ }
588
+ return Array.from(el.classList).find((className) => {
589
+ return (
590
+ className !== "column-body" &&
591
+ className.startsWith("column-") &&
592
+ !className.endsWith("right") &&
593
+ !className.endsWith("container") &&
594
+ className !== "column-margin"
595
+ );
596
+ });
597
+ });
598
+ const rightSideConflictEls = arrConflictingEls.filter((el) => {
599
+ if (el.tagName === "ASIDE") {
600
+ return true;
601
+ }
602
+
603
+ const hasMarginCaption = Array.from(el.classList).find((className) => {
604
+ return className == "margin-caption";
605
+ });
606
+ if (hasMarginCaption) {
607
+ return true;
608
+ }
609
+
610
+ return Array.from(el.classList).find((className) => {
611
+ return (
612
+ className !== "column-body" &&
613
+ !className.endsWith("container") &&
614
+ className.startsWith("column-") &&
615
+ !className.endsWith("left")
616
+ );
617
+ });
618
+ });
619
+
620
+ const kOverlapPaddingSize = 10;
621
+ function toRegions(els) {
622
+ return els.map((el) => {
623
+ const boundRect = el.getBoundingClientRect();
624
+ const top =
625
+ boundRect.top +
626
+ document.documentElement.scrollTop -
627
+ kOverlapPaddingSize;
628
+ return {
629
+ top,
630
+ bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize,
631
+ };
632
+ });
633
+ }
634
+
635
+ let hasObserved = false;
636
+ const visibleItemObserver = (els) => {
637
+ let visibleElements = [...els];
638
+ const intersectionObserver = new IntersectionObserver(
639
+ (entries, _observer) => {
640
+ entries.forEach((entry) => {
641
+ if (entry.isIntersecting) {
642
+ if (visibleElements.indexOf(entry.target) === -1) {
643
+ visibleElements.push(entry.target);
644
+ }
645
+ } else {
646
+ visibleElements = visibleElements.filter((visibleEntry) => {
647
+ return visibleEntry !== entry;
648
+ });
649
+ }
650
+ });
651
+
652
+ if (!hasObserved) {
653
+ hideOverlappedSidebars();
654
+ }
655
+ hasObserved = true;
656
+ },
657
+ {}
658
+ );
659
+ els.forEach((el) => {
660
+ intersectionObserver.observe(el);
661
+ });
662
+
663
+ return {
664
+ getVisibleEntries: () => {
665
+ return visibleElements;
666
+ },
667
+ };
668
+ };
669
+
670
+ const rightElementObserver = visibleItemObserver(rightSideConflictEls);
671
+ const leftElementObserver = visibleItemObserver(leftSideConflictEls);
672
+
673
+ const hideOverlappedSidebars = () => {
674
+ marginScrollVisibility(toRegions(rightElementObserver.getVisibleEntries()));
675
+ sidebarScrollVisiblity(toRegions(leftElementObserver.getVisibleEntries()));
676
+ if (tocLeftScrollVisibility) {
677
+ tocLeftScrollVisibility(
678
+ toRegions(leftElementObserver.getVisibleEntries())
679
+ );
680
+ }
681
+ };
682
+
683
+ window.quartoToggleReader = () => {
684
+ // Applies a slow class (or removes it)
685
+ // to update the transition speed
686
+ const slowTransition = (slow) => {
687
+ const manageTransition = (id, slow) => {
688
+ const el = document.getElementById(id);
689
+ if (el) {
690
+ if (slow) {
691
+ el.classList.add("slow");
692
+ } else {
693
+ el.classList.remove("slow");
694
+ }
695
+ }
696
+ };
697
+
698
+ manageTransition("TOC", slow);
699
+ manageTransition("quarto-sidebar", slow);
700
+ };
701
+ const readerMode = !isReaderMode();
702
+ setReaderModeValue(readerMode);
703
+
704
+ // If we're entering reader mode, slow the transition
705
+ if (readerMode) {
706
+ slowTransition(readerMode);
707
+ }
708
+ highlightReaderToggle(readerMode);
709
+ hideOverlappedSidebars();
710
+
711
+ // If we're exiting reader mode, restore the non-slow transition
712
+ if (!readerMode) {
713
+ slowTransition(!readerMode);
714
+ }
715
+ };
716
+
717
+ const highlightReaderToggle = (readerMode) => {
718
+ const els = document.querySelectorAll(".quarto-reader-toggle");
719
+ if (els) {
720
+ els.forEach((el) => {
721
+ if (readerMode) {
722
+ el.classList.add("reader");
723
+ } else {
724
+ el.classList.remove("reader");
725
+ }
726
+ });
727
+ }
728
+ };
729
+
730
+ const setReaderModeValue = (val) => {
731
+ if (window.location.protocol !== "file:") {
732
+ window.localStorage.setItem("quarto-reader-mode", val);
733
+ } else {
734
+ localReaderMode = val;
735
+ }
736
+ };
737
+
738
+ const isReaderMode = () => {
739
+ if (window.location.protocol !== "file:") {
740
+ return window.localStorage.getItem("quarto-reader-mode") === "true";
741
+ } else {
742
+ return localReaderMode;
743
+ }
744
+ };
745
+ let localReaderMode = null;
746
+
747
+ const tocOpenDepthStr = tocEl?.getAttribute("data-toc-expanded");
748
+ const tocOpenDepth = tocOpenDepthStr ? Number(tocOpenDepthStr) : 1;
749
+
750
+ // Walk the TOC and collapse/expand nodes
751
+ // Nodes are expanded if:
752
+ // - they are top level
753
+ // - they have children that are 'active' links
754
+ // - they are directly below an link that is 'active'
755
+ const walk = (el, depth) => {
756
+ // Tick depth when we enter a UL
757
+ if (el.tagName === "UL") {
758
+ depth = depth + 1;
759
+ }
760
+
761
+ // It this is active link
762
+ let isActiveNode = false;
763
+ if (el.tagName === "A" && el.classList.contains("active")) {
764
+ isActiveNode = true;
765
+ }
766
+
767
+ // See if there is an active child to this element
768
+ let hasActiveChild = false;
769
+ for (const child of el.children) {
770
+ hasActiveChild = walk(child, depth) || hasActiveChild;
771
+ }
772
+
773
+ // Process the collapse state if this is an UL
774
+ if (el.tagName === "UL") {
775
+ if (tocOpenDepth === -1 && depth > 1) {
776
+ // toc-expand: false
777
+ el.classList.add("collapse");
778
+ } else if (
779
+ depth <= tocOpenDepth ||
780
+ hasActiveChild ||
781
+ prevSiblingIsActiveLink(el)
782
+ ) {
783
+ el.classList.remove("collapse");
784
+ } else {
785
+ el.classList.add("collapse");
786
+ }
787
+
788
+ // untick depth when we leave a UL
789
+ depth = depth - 1;
790
+ }
791
+ return hasActiveChild || isActiveNode;
792
+ };
793
+
794
+ // walk the TOC and expand / collapse any items that should be shown
795
+ if (tocEl) {
796
+ updateActiveLink();
797
+ walk(tocEl, 0);
798
+ }
799
+
800
+ // Throttle the scroll event and walk peridiocally
801
+ window.document.addEventListener(
802
+ "scroll",
803
+ throttle(() => {
804
+ if (tocEl) {
805
+ updateActiveLink();
806
+ walk(tocEl, 0);
807
+ }
808
+ if (!isReaderMode()) {
809
+ hideOverlappedSidebars();
810
+ }
811
+ }, 5)
812
+ );
813
+ window.addEventListener(
814
+ "resize",
815
+ throttle(() => {
816
+ if (tocEl) {
817
+ updateActiveLink();
818
+ walk(tocEl, 0);
819
+ }
820
+ if (!isReaderMode()) {
821
+ hideOverlappedSidebars();
822
+ }
823
+ }, 10)
824
+ );
825
+ hideOverlappedSidebars();
826
+ highlightReaderToggle(isReaderMode());
827
+ });
828
+
829
+ tabsets.init();
830
+ axe.init();
831
+
832
+ function throttle(func, wait) {
833
+ let waiting = false;
834
+ return function () {
835
+ if (!waiting) {
836
+ func.apply(this, arguments);
837
+ waiting = true;
838
+ setTimeout(function () {
839
+ waiting = false;
840
+ }, wait);
841
+ }
842
+ };
843
+ }
844
+
845
+ function nexttick(func) {
846
+ return setTimeout(func, 0);
847
+ }