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,704 @@
1
+ <!DOCTYPE html>
2
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
3
+
4
+ <meta charset="utf-8">
5
+ <meta name="generator" content="quarto-1.8.26">
6
+
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
+
9
+ <meta name="author" content="Assistant">
10
+ <meta name="dcterms.date" content="2026-01-03">
11
+
12
+ <title>NotebookLM MCP 사용 가이드</title>
13
+ <style>
14
+ code{white-space: pre-wrap;}
15
+ span.smallcaps{font-variant: small-caps;}
16
+ div.columns{display: flex; gap: min(4vw, 1.5em);}
17
+ div.column{flex: auto; overflow-x: auto;}
18
+ div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
19
+ ul.task-list{list-style: none;}
20
+ ul.task-list li input[type="checkbox"] {
21
+ width: 0.8em;
22
+ margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
23
+ vertical-align: middle;
24
+ }
25
+ /* CSS for syntax highlighting */
26
+ html { -webkit-text-size-adjust: 100%; }
27
+ pre > code.sourceCode { white-space: pre; position: relative; }
28
+ pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
29
+ pre > code.sourceCode > span:empty { height: 1.2em; }
30
+ .sourceCode { overflow: visible; }
31
+ code.sourceCode > span { color: inherit; text-decoration: inherit; }
32
+ div.sourceCode { margin: 1em 0; }
33
+ pre.sourceCode { margin: 0; }
34
+ @media screen {
35
+ div.sourceCode { overflow: auto; }
36
+ }
37
+ @media print {
38
+ pre > code.sourceCode { white-space: pre-wrap; }
39
+ pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
40
+ }
41
+ pre.numberSource code
42
+ { counter-reset: source-line 0; }
43
+ pre.numberSource code > span
44
+ { position: relative; left: -4em; counter-increment: source-line; }
45
+ pre.numberSource code > span > a:first-child::before
46
+ { content: counter(source-line);
47
+ position: relative; left: -1em; text-align: right; vertical-align: baseline;
48
+ border: none; display: inline-block;
49
+ -webkit-touch-callout: none; -webkit-user-select: none;
50
+ -khtml-user-select: none; -moz-user-select: none;
51
+ -ms-user-select: none; user-select: none;
52
+ padding: 0 4px; width: 4em;
53
+ }
54
+ pre.numberSource { margin-left: 3em; padding-left: 4px; }
55
+ div.sourceCode
56
+ { }
57
+ @media screen {
58
+ pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
59
+ }
60
+ </style>
61
+
62
+
63
+ <script src="notebooklm-mcp-usage_files/libs/clipboard/clipboard.min.js"></script>
64
+ <script src="notebooklm-mcp-usage_files/libs/quarto-html/quarto.js" type="module"></script>
65
+ <script src="notebooklm-mcp-usage_files/libs/quarto-html/tabsets/tabsets.js" type="module"></script>
66
+ <script src="notebooklm-mcp-usage_files/libs/quarto-html/axe/axe-check.js" type="module"></script>
67
+ <script src="notebooklm-mcp-usage_files/libs/quarto-html/popper.min.js"></script>
68
+ <script src="notebooklm-mcp-usage_files/libs/quarto-html/tippy.umd.min.js"></script>
69
+ <script src="notebooklm-mcp-usage_files/libs/quarto-html/anchor.min.js"></script>
70
+ <link href="notebooklm-mcp-usage_files/libs/quarto-html/tippy.css" rel="stylesheet">
71
+ <link href="notebooklm-mcp-usage_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css" rel="stylesheet" id="quarto-text-highlighting-styles">
72
+ <script src="notebooklm-mcp-usage_files/libs/bootstrap/bootstrap.min.js"></script>
73
+ <link href="notebooklm-mcp-usage_files/libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
74
+ <link href="notebooklm-mcp-usage_files/libs/bootstrap/bootstrap-6b71f2156b6a5230c6677325978bcf08.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
75
+
76
+
77
+ </head>
78
+
79
+ <body class="quarto-light">
80
+
81
+ <div id="quarto-content" class="page-columns page-rows-contents page-layout-article">
82
+ <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
83
+ <nav id="TOC" role="doc-toc" class="toc-active">
84
+ <h2 id="toc-title">Table of contents</h2>
85
+
86
+ <ul>
87
+ <li><a href="#개요" id="toc-개요" class="nav-link active" data-scroll-target="#개요">개요</a></li>
88
+ <li><a href="#설치-installation" id="toc-설치-installation" class="nav-link" data-scroll-target="#설치-installation">1. 설치 (Installation)</a>
89
+ <ul class="collapse">
90
+ <li><a href="#요구-사항" id="toc-요구-사항" class="nav-link" data-scroll-target="#요구-사항">요구 사항</a></li>
91
+ <li><a href="#실행-방법" id="toc-실행-방법" class="nav-link" data-scroll-target="#실행-방법">실행 방법</a></li>
92
+ </ul></li>
93
+ <li><a href="#클라이언트-연동-configuration" id="toc-클라이언트-연동-configuration" class="nav-link" data-scroll-target="#클라이언트-연동-configuration">2. 클라이언트 연동 (Configuration)</a>
94
+ <ul class="collapse">
95
+ <li><a href="#환경-변수-목록" id="toc-환경-변수-목록" class="nav-link" data-scroll-target="#환경-변수-목록">환경 변수 목록</a></li>
96
+ </ul></li>
97
+ <li><a href="#주요-기능-tools" id="toc-주요-기능-tools" class="nav-link" data-scroll-target="#주요-기능-tools">3. 주요 기능 (Tools)</a>
98
+ <ul class="collapse">
99
+ <li><a href="#질문-및-대화" id="toc-질문-및-대화" class="nav-link" data-scroll-target="#질문-및-대화">📝 질문 및 대화</a></li>
100
+ <li><a href="#노트북-관리" id="toc-노트북-관리" class="nav-link" data-scroll-target="#노트북-관리">📚 노트북 관리</a></li>
101
+ <li><a href="#세션-및-인증" id="toc-세션-및-인증" class="nav-link" data-scroll-target="#세션-및-인증">⚙️ 세션 및 인증</a></li>
102
+ </ul></li>
103
+ <li><a href="#리소스-resources" id="toc-리소스-resources" class="nav-link" data-scroll-target="#리소스-resources">4. 리소스 (Resources)</a></li>
104
+ <li><a href="#문제-해결-troubleshooting" id="toc-문제-해결-troubleshooting" class="nav-link" data-scroll-target="#문제-해결-troubleshooting">5. 문제 해결 (Troubleshooting)</a></li>
105
+ </ul>
106
+ </nav>
107
+ </div>
108
+ <main class="content" id="quarto-document-content">
109
+
110
+ <header id="title-block-header" class="quarto-title-block default">
111
+ <div class="quarto-title">
112
+ <h1 class="title">NotebookLM MCP 사용 가이드</h1>
113
+ </div>
114
+
115
+
116
+
117
+ <div class="quarto-title-meta">
118
+
119
+ <div>
120
+ <div class="quarto-title-meta-heading">Author</div>
121
+ <div class="quarto-title-meta-contents">
122
+ <p>Assistant </p>
123
+ </div>
124
+ </div>
125
+
126
+ <div>
127
+ <div class="quarto-title-meta-heading">Published</div>
128
+ <div class="quarto-title-meta-contents">
129
+ <p class="date">January 3, 2026</p>
130
+ </div>
131
+ </div>
132
+
133
+
134
+ </div>
135
+
136
+
137
+
138
+ </header>
139
+
140
+
141
+ <section id="개요" class="level1">
142
+ <h1>개요</h1>
143
+ <p><strong>NotebookLM MCP</strong>는 Google NotebookLM의 강력한 기능을 MCP(Model Context Protocol) 인터페이스를 통해 제공하는 서버입니다. 이를 통해 Claude Desktop, Cursor 등 MCP 호환 클라이언트에서 Gemini 3 모델과 대화하거나 나만의 노트북(Knowledge Base)을 활용할 수 있습니다.</p>
144
+ </section>
145
+ <section id="설치-installation" class="level1">
146
+ <h1>1. 설치 (Installation)</h1>
147
+ <p>이 프로젝트는 Node.js 기반의 MCP 서버입니다.</p>
148
+ <section id="요구-사항" class="level3">
149
+ <h3 class="anchored" data-anchor-id="요구-사항">요구 사항</h3>
150
+ <ul>
151
+ <li>Node.js v18.0.0 이상</li>
152
+ <li>Google 계정 (NotebookLM 접근용)</li>
153
+ </ul>
154
+ </section>
155
+ <section id="실행-방법" class="level3">
156
+ <h3 class="anchored" data-anchor-id="실행-방법">실행 방법</h3>
157
+ <p><code>npx</code>를 사용하여 별도의 설치 없이 바로 실행할 수 있습니다.</p>
158
+ <div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">npx</span> notebooklm-mcp</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
159
+ <p>또는 소스 코드를 클론하여 빌드 후 실행할 수 있습니다.</p>
160
+ <div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> clone https://github.com/PleasePrompto/notebooklm-mcp.git</span>
161
+ <span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> notebooklm-mcp</span>
162
+ <span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="ex">npm</span> install</span>
163
+ <span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="ex">npm</span> run build</span>
164
+ <span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="ex">node</span> dist/index.js</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
165
+ </section>
166
+ </section>
167
+ <section id="클라이언트-연동-configuration" class="level1">
168
+ <h1>2. 클라이언트 연동 (Configuration)</h1>
169
+ <p>Claude Desktop 등 MCP 클라이언트의 설정 파일(<code>claude_desktop_config.json</code>)에 다음과 같이 추가하세요.</p>
170
+ <p><strong>중요:</strong> 자동 로그인을 위해 Google 계정 정보를 환경 변수로 설정하는 것이 좋습니다.</p>
171
+ <div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
172
+ <span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"mcpServers"</span><span class="fu">:</span> <span class="fu">{</span></span>
173
+ <span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"notebooklm"</span><span class="fu">:</span> <span class="fu">{</span></span>
174
+ <span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"command"</span><span class="fu">:</span> <span class="st">"npx"</span><span class="fu">,</span></span>
175
+ <span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"args"</span><span class="fu">:</span> <span class="ot">[</span></span>
176
+ <span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a> <span class="st">"-y"</span><span class="ot">,</span></span>
177
+ <span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a> <span class="st">"notebooklm-mcp"</span></span>
178
+ <span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a> <span class="ot">]</span><span class="fu">,</span></span>
179
+ <span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"env"</span><span class="fu">:</span> <span class="fu">{</span></span>
180
+ <span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"NOTEBOOK_URL"</span><span class="fu">:</span> <span class="st">"https://notebooklm.google.com/notebook/YOUR_NOTEBOOK_ID"</span><span class="fu">,</span></span>
181
+ <span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"AUTO_LOGIN_ENABLED"</span><span class="fu">:</span> <span class="st">"true"</span><span class="fu">,</span></span>
182
+ <span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"LOGIN_EMAIL"</span><span class="fu">:</span> <span class="st">"your.email@gmail.com"</span><span class="fu">,</span></span>
183
+ <span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"LOGIN_PASSWORD"</span><span class="fu">:</span> <span class="st">"your-app-password-or-regular-password"</span><span class="fu">,</span></span>
184
+ <span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">"HEADLESS"</span><span class="fu">:</span> <span class="st">"true"</span></span>
185
+ <span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
186
+ <span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
187
+ <span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
188
+ <span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
189
+ <section id="환경-변수-목록" class="level3">
190
+ <h3 class="anchored" data-anchor-id="환경-변수-목록">환경 변수 목록</h3>
191
+ <table class="caption-top table">
192
+ <colgroup>
193
+ <col style="width: 36%">
194
+ <col style="width: 27%">
195
+ <col style="width: 36%">
196
+ </colgroup>
197
+ <thead>
198
+ <tr class="header">
199
+ <th>변수명</th>
200
+ <th>설명</th>
201
+ <th>기본값</th>
202
+ </tr>
203
+ </thead>
204
+ <tbody>
205
+ <tr class="odd">
206
+ <td><code>NOTEBOOK_URL</code></td>
207
+ <td>기본으로 사용할 노트북 URL (선택 사항)</td>
208
+ <td>-</td>
209
+ </tr>
210
+ <tr class="even">
211
+ <td><code>AUTO_LOGIN_ENABLED</code></td>
212
+ <td>자동 로그인 활성화 여부 (<code>true</code>/<code>false</code>)</td>
213
+ <td><code>false</code></td>
214
+ </tr>
215
+ <tr class="odd">
216
+ <td><code>LOGIN_EMAIL</code></td>
217
+ <td>Google 로그인 이메일</td>
218
+ <td>-</td>
219
+ </tr>
220
+ <tr class="even">
221
+ <td><code>LOGIN_PASSWORD</code></td>
222
+ <td>Google 로그인 비밀번호</td>
223
+ <td>-</td>
224
+ </tr>
225
+ <tr class="odd">
226
+ <td><code>HEADLESS</code></td>
227
+ <td>브라우저 헤드리스 모드 여부 (<code>true</code>/<code>false</code>)</td>
228
+ <td><code>true</code></td>
229
+ </tr>
230
+ <tr class="even">
231
+ <td><code>MAX_SESSIONS</code></td>
232
+ <td>최대 동시 세션 수</td>
233
+ <td><code>10</code></td>
234
+ </tr>
235
+ <tr class="odd">
236
+ <td><code>SESSION_TIMEOUT</code></td>
237
+ <td>세션 타임아웃 (초)</td>
238
+ <td><code>900</code></td>
239
+ </tr>
240
+ <tr class="even">
241
+ <td><code>STEALTH_ENABLED</code></td>
242
+ <td>봇 탐지 회피 기능 활성화</td>
243
+ <td><code>true</code></td>
244
+ </tr>
245
+ </tbody>
246
+ </table>
247
+ </section>
248
+ </section>
249
+ <section id="주요-기능-tools" class="level1">
250
+ <h1>3. 주요 기능 (Tools)</h1>
251
+ <p>NotebookLM MCP는 다음과 같은 도구들을 제공합니다.</p>
252
+ <section id="질문-및-대화" class="level3">
253
+ <h3 class="anchored" data-anchor-id="질문-및-대화">📝 질문 및 대화</h3>
254
+ <ul>
255
+ <li><strong><code>ask_question</code></strong>: 지정된 노트북 또는 기본 노트북에 질문을 던지고 Gemini 3의 답변을 받습니다. 이전 대화 맥락을 유지하는 세션을 지원합니다.</li>
256
+ </ul>
257
+ </section>
258
+ <section id="노트북-관리" class="level3">
259
+ <h3 class="anchored" data-anchor-id="노트북-관리">📚 노트북 관리</h3>
260
+ <ul>
261
+ <li><strong><code>list_notebooks</code></strong>: 사용 가능한 모든 노트북 목록을 조회합니다.</li>
262
+ <li><strong><code>get_notebook</code></strong>: 특정 노트북의 상세 정보(ID, 이름, 주제 등)를 조회합니다.</li>
263
+ <li><strong><code>add_notebook</code></strong>: 새로운 노트북을 생성합니다.</li>
264
+ <li><strong><code>select_notebook</code></strong>: 작업할 활성 노트북을 선택합니다.</li>
265
+ <li><strong><code>update_notebook</code></strong>: 노트북의 정보를 수정합니다.</li>
266
+ <li><strong><code>remove_notebook</code></strong>: 노트북을 삭제합니다.</li>
267
+ <li><strong><code>search_notebooks</code></strong>: 쿼리 기반으로 관련 노트북을 검색합니다.</li>
268
+ </ul>
269
+ </section>
270
+ <section id="세션-및-인증" class="level3">
271
+ <h3 class="anchored" data-anchor-id="세션-및-인증">⚙️ 세션 및 인증</h3>
272
+ <ul>
273
+ <li><strong><code>setup_auth</code></strong>: 초기 인증을 수행합니다. (브라우저가 열려 직접 로그인할 수 있음)</li>
274
+ <li><strong><code>list_sessions</code></strong>: 현재 활성화된 대화 세션 목록을 확인합니다.</li>
275
+ <li><strong><code>close_session</code> / <code>reset_session</code></strong>: 세션을 종료하거나 초기화합니다.</li>
276
+ <li><strong><code>cleanup_data</code></strong>: 브라우저 데이터를 정리합니다.</li>
277
+ </ul>
278
+ </section>
279
+ </section>
280
+ <section id="리소스-resources" class="level1">
281
+ <h1>4. 리소스 (Resources)</h1>
282
+ <p>MCP 리소스 기능을 통해 노트북 정보를 직접 읽어올 수 있습니다.</p>
283
+ <ul>
284
+ <li><strong><code>notebooklm://library</code></strong>: 전체 노트북 목록과 라이브러리 통계를 JSON 형식으로 반환합니다.</li>
285
+ <li><strong><code>notebooklm://library/{id}</code></strong>: 특정 노트북의 메타데이터를 반환합니다.</li>
286
+ </ul>
287
+ </section>
288
+ <section id="문제-해결-troubleshooting" class="level1">
289
+ <h1>5. 문제 해결 (Troubleshooting)</h1>
290
+ <ul>
291
+ <li><strong>로그인 실패:</strong> <code>HEADLESS="false"</code>로 설정하여 브라우저 창을 띄우고 직접 로그인 과정을 모니터링하세요. 2단계 인증이 필요한 경우 수동 개입이 필요할 수 있습니다.</li>
292
+ <li><strong>봇 탐지:</strong> <code>STEALTH_ENABLED="true"</code> 설정이 켜져 있는지 확인하세요. 너무 잦은 요청은 일시적인 차단을 유발할 수 있습니다.</li>
293
+ <li><strong>권한 오류:</strong> <code>setup_auth</code> 도구를 실행하여 인증 토큰을 갱신하세요.</li>
294
+ </ul>
295
+ </section>
296
+
297
+ </main>
298
+ <!-- /main column -->
299
+ <script id="quarto-html-after-body" type="application/javascript">
300
+ window.document.addEventListener("DOMContentLoaded", function (event) {
301
+ const icon = "";
302
+ const anchorJS = new window.AnchorJS();
303
+ anchorJS.options = {
304
+ placement: 'right',
305
+ icon: icon
306
+ };
307
+ anchorJS.add('.anchored');
308
+ const isCodeAnnotation = (el) => {
309
+ for (const clz of el.classList) {
310
+ if (clz.startsWith('code-annotation-')) {
311
+ return true;
312
+ }
313
+ }
314
+ return false;
315
+ }
316
+ const onCopySuccess = function(e) {
317
+ // button target
318
+ const button = e.trigger;
319
+ // don't keep focus
320
+ button.blur();
321
+ // flash "checked"
322
+ button.classList.add('code-copy-button-checked');
323
+ var currentTitle = button.getAttribute("title");
324
+ button.setAttribute("title", "Copied!");
325
+ let tooltip;
326
+ if (window.bootstrap) {
327
+ button.setAttribute("data-bs-toggle", "tooltip");
328
+ button.setAttribute("data-bs-placement", "left");
329
+ button.setAttribute("data-bs-title", "Copied!");
330
+ tooltip = new bootstrap.Tooltip(button,
331
+ { trigger: "manual",
332
+ customClass: "code-copy-button-tooltip",
333
+ offset: [0, -8]});
334
+ tooltip.show();
335
+ }
336
+ setTimeout(function() {
337
+ if (tooltip) {
338
+ tooltip.hide();
339
+ button.removeAttribute("data-bs-title");
340
+ button.removeAttribute("data-bs-toggle");
341
+ button.removeAttribute("data-bs-placement");
342
+ }
343
+ button.setAttribute("title", currentTitle);
344
+ button.classList.remove('code-copy-button-checked');
345
+ }, 1000);
346
+ // clear code selection
347
+ e.clearSelection();
348
+ }
349
+ const getTextToCopy = function(trigger) {
350
+ const outerScaffold = trigger.parentElement.cloneNode(true);
351
+ const codeEl = outerScaffold.querySelector('code');
352
+ for (const childEl of codeEl.children) {
353
+ if (isCodeAnnotation(childEl)) {
354
+ childEl.remove();
355
+ }
356
+ }
357
+ return codeEl.innerText;
358
+ }
359
+ const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
360
+ text: getTextToCopy
361
+ });
362
+ clipboard.on('success', onCopySuccess);
363
+ if (window.document.getElementById('quarto-embedded-source-code-modal')) {
364
+ const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
365
+ text: getTextToCopy,
366
+ container: window.document.getElementById('quarto-embedded-source-code-modal')
367
+ });
368
+ clipboardModal.on('success', onCopySuccess);
369
+ }
370
+ var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
371
+ var mailtoRegex = new RegExp(/^mailto:/);
372
+ var filterRegex = new RegExp('/' + window.location.host + '/');
373
+ var isInternal = (href) => {
374
+ return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
375
+ }
376
+ // Inspect non-navigation links and adorn them if external
377
+ var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
378
+ for (var i=0; i<links.length; i++) {
379
+ const link = links[i];
380
+ if (!isInternal(link.href)) {
381
+ // undo the damage that might have been done by quarto-nav.js in the case of
382
+ // links that we want to consider external
383
+ if (link.dataset.originalHref !== undefined) {
384
+ link.href = link.dataset.originalHref;
385
+ }
386
+ }
387
+ }
388
+ function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
389
+ const config = {
390
+ allowHTML: true,
391
+ maxWidth: 500,
392
+ delay: 100,
393
+ arrow: false,
394
+ appendTo: function(el) {
395
+ return el.parentElement;
396
+ },
397
+ interactive: true,
398
+ interactiveBorder: 10,
399
+ theme: 'quarto',
400
+ placement: 'bottom-start',
401
+ };
402
+ if (contentFn) {
403
+ config.content = contentFn;
404
+ }
405
+ if (onTriggerFn) {
406
+ config.onTrigger = onTriggerFn;
407
+ }
408
+ if (onUntriggerFn) {
409
+ config.onUntrigger = onUntriggerFn;
410
+ }
411
+ window.tippy(el, config);
412
+ }
413
+ const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
414
+ for (var i=0; i<noterefs.length; i++) {
415
+ const ref = noterefs[i];
416
+ tippyHover(ref, function() {
417
+ // use id or data attribute instead here
418
+ let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
419
+ try { href = new URL(href).hash; } catch {}
420
+ const id = href.replace(/^#\/?/, "");
421
+ const note = window.document.getElementById(id);
422
+ if (note) {
423
+ return note.innerHTML;
424
+ } else {
425
+ return "";
426
+ }
427
+ });
428
+ }
429
+ const xrefs = window.document.querySelectorAll('a.quarto-xref');
430
+ const processXRef = (id, note) => {
431
+ // Strip column container classes
432
+ const stripColumnClz = (el) => {
433
+ el.classList.remove("page-full", "page-columns");
434
+ if (el.children) {
435
+ for (const child of el.children) {
436
+ stripColumnClz(child);
437
+ }
438
+ }
439
+ }
440
+ stripColumnClz(note)
441
+ if (id === null || id.startsWith('sec-')) {
442
+ // Special case sections, only their first couple elements
443
+ const container = document.createElement("div");
444
+ if (note.children && note.children.length > 2) {
445
+ container.appendChild(note.children[0].cloneNode(true));
446
+ for (let i = 1; i < note.children.length; i++) {
447
+ const child = note.children[i];
448
+ if (child.tagName === "P" && child.innerText === "") {
449
+ continue;
450
+ } else {
451
+ container.appendChild(child.cloneNode(true));
452
+ break;
453
+ }
454
+ }
455
+ if (window.Quarto?.typesetMath) {
456
+ window.Quarto.typesetMath(container);
457
+ }
458
+ return container.innerHTML
459
+ } else {
460
+ if (window.Quarto?.typesetMath) {
461
+ window.Quarto.typesetMath(note);
462
+ }
463
+ return note.innerHTML;
464
+ }
465
+ } else {
466
+ // Remove any anchor links if they are present
467
+ const anchorLink = note.querySelector('a.anchorjs-link');
468
+ if (anchorLink) {
469
+ anchorLink.remove();
470
+ }
471
+ if (window.Quarto?.typesetMath) {
472
+ window.Quarto.typesetMath(note);
473
+ }
474
+ if (note.classList.contains("callout")) {
475
+ return note.outerHTML;
476
+ } else {
477
+ return note.innerHTML;
478
+ }
479
+ }
480
+ }
481
+ for (var i=0; i<xrefs.length; i++) {
482
+ const xref = xrefs[i];
483
+ tippyHover(xref, undefined, function(instance) {
484
+ instance.disable();
485
+ let url = xref.getAttribute('href');
486
+ let hash = undefined;
487
+ if (url.startsWith('#')) {
488
+ hash = url;
489
+ } else {
490
+ try { hash = new URL(url).hash; } catch {}
491
+ }
492
+ if (hash) {
493
+ const id = hash.replace(/^#\/?/, "");
494
+ const note = window.document.getElementById(id);
495
+ if (note !== null) {
496
+ try {
497
+ const html = processXRef(id, note.cloneNode(true));
498
+ instance.setContent(html);
499
+ } finally {
500
+ instance.enable();
501
+ instance.show();
502
+ }
503
+ } else {
504
+ // See if we can fetch this
505
+ fetch(url.split('#')[0])
506
+ .then(res => res.text())
507
+ .then(html => {
508
+ const parser = new DOMParser();
509
+ const htmlDoc = parser.parseFromString(html, "text/html");
510
+ const note = htmlDoc.getElementById(id);
511
+ if (note !== null) {
512
+ const html = processXRef(id, note);
513
+ instance.setContent(html);
514
+ }
515
+ }).finally(() => {
516
+ instance.enable();
517
+ instance.show();
518
+ });
519
+ }
520
+ } else {
521
+ // See if we can fetch a full url (with no hash to target)
522
+ // This is a special case and we should probably do some content thinning / targeting
523
+ fetch(url)
524
+ .then(res => res.text())
525
+ .then(html => {
526
+ const parser = new DOMParser();
527
+ const htmlDoc = parser.parseFromString(html, "text/html");
528
+ const note = htmlDoc.querySelector('main.content');
529
+ if (note !== null) {
530
+ // This should only happen for chapter cross references
531
+ // (since there is no id in the URL)
532
+ // remove the first header
533
+ if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
534
+ note.children[0].remove();
535
+ }
536
+ const html = processXRef(null, note);
537
+ instance.setContent(html);
538
+ }
539
+ }).finally(() => {
540
+ instance.enable();
541
+ instance.show();
542
+ });
543
+ }
544
+ }, function(instance) {
545
+ });
546
+ }
547
+ let selectedAnnoteEl;
548
+ const selectorForAnnotation = ( cell, annotation) => {
549
+ let cellAttr = 'data-code-cell="' + cell + '"';
550
+ let lineAttr = 'data-code-annotation="' + annotation + '"';
551
+ const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
552
+ return selector;
553
+ }
554
+ const selectCodeLines = (annoteEl) => {
555
+ const doc = window.document;
556
+ const targetCell = annoteEl.getAttribute("data-target-cell");
557
+ const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
558
+ const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
559
+ const lines = annoteSpan.getAttribute("data-code-lines").split(",");
560
+ const lineIds = lines.map((line) => {
561
+ return targetCell + "-" + line;
562
+ })
563
+ let top = null;
564
+ let height = null;
565
+ let parent = null;
566
+ if (lineIds.length > 0) {
567
+ //compute the position of the single el (top and bottom and make a div)
568
+ const el = window.document.getElementById(lineIds[0]);
569
+ top = el.offsetTop;
570
+ height = el.offsetHeight;
571
+ parent = el.parentElement.parentElement;
572
+ if (lineIds.length > 1) {
573
+ const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
574
+ const bottom = lastEl.offsetTop + lastEl.offsetHeight;
575
+ height = bottom - top;
576
+ }
577
+ if (top !== null && height !== null && parent !== null) {
578
+ // cook up a div (if necessary) and position it
579
+ let div = window.document.getElementById("code-annotation-line-highlight");
580
+ if (div === null) {
581
+ div = window.document.createElement("div");
582
+ div.setAttribute("id", "code-annotation-line-highlight");
583
+ div.style.position = 'absolute';
584
+ parent.appendChild(div);
585
+ }
586
+ div.style.top = top - 2 + "px";
587
+ div.style.height = height + 4 + "px";
588
+ div.style.left = 0;
589
+ let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
590
+ if (gutterDiv === null) {
591
+ gutterDiv = window.document.createElement("div");
592
+ gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
593
+ gutterDiv.style.position = 'absolute';
594
+ const codeCell = window.document.getElementById(targetCell);
595
+ const gutter = codeCell.querySelector('.code-annotation-gutter');
596
+ gutter.appendChild(gutterDiv);
597
+ }
598
+ gutterDiv.style.top = top - 2 + "px";
599
+ gutterDiv.style.height = height + 4 + "px";
600
+ }
601
+ selectedAnnoteEl = annoteEl;
602
+ }
603
+ };
604
+ const unselectCodeLines = () => {
605
+ const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
606
+ elementsIds.forEach((elId) => {
607
+ const div = window.document.getElementById(elId);
608
+ if (div) {
609
+ div.remove();
610
+ }
611
+ });
612
+ selectedAnnoteEl = undefined;
613
+ };
614
+ // Handle positioning of the toggle
615
+ window.addEventListener(
616
+ "resize",
617
+ throttle(() => {
618
+ elRect = undefined;
619
+ if (selectedAnnoteEl) {
620
+ selectCodeLines(selectedAnnoteEl);
621
+ }
622
+ }, 10)
623
+ );
624
+ function throttle(fn, ms) {
625
+ let throttle = false;
626
+ let timer;
627
+ return (...args) => {
628
+ if(!throttle) { // first call gets through
629
+ fn.apply(this, args);
630
+ throttle = true;
631
+ } else { // all the others get throttled
632
+ if(timer) clearTimeout(timer); // cancel #2
633
+ timer = setTimeout(() => {
634
+ fn.apply(this, args);
635
+ timer = throttle = false;
636
+ }, ms);
637
+ }
638
+ };
639
+ }
640
+ // Attach click handler to the DT
641
+ const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
642
+ for (const annoteDlNode of annoteDls) {
643
+ annoteDlNode.addEventListener('click', (event) => {
644
+ const clickedEl = event.target;
645
+ if (clickedEl !== selectedAnnoteEl) {
646
+ unselectCodeLines();
647
+ const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
648
+ if (activeEl) {
649
+ activeEl.classList.remove('code-annotation-active');
650
+ }
651
+ selectCodeLines(clickedEl);
652
+ clickedEl.classList.add('code-annotation-active');
653
+ } else {
654
+ // Unselect the line
655
+ unselectCodeLines();
656
+ clickedEl.classList.remove('code-annotation-active');
657
+ }
658
+ });
659
+ }
660
+ const findCites = (el) => {
661
+ const parentEl = el.parentElement;
662
+ if (parentEl) {
663
+ const cites = parentEl.dataset.cites;
664
+ if (cites) {
665
+ return {
666
+ el,
667
+ cites: cites.split(' ')
668
+ };
669
+ } else {
670
+ return findCites(el.parentElement)
671
+ }
672
+ } else {
673
+ return undefined;
674
+ }
675
+ };
676
+ var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
677
+ for (var i=0; i<bibliorefs.length; i++) {
678
+ const ref = bibliorefs[i];
679
+ const citeInfo = findCites(ref);
680
+ if (citeInfo) {
681
+ tippyHover(citeInfo.el, function() {
682
+ var popup = window.document.createElement('div');
683
+ citeInfo.cites.forEach(function(cite) {
684
+ var citeDiv = window.document.createElement('div');
685
+ citeDiv.classList.add('hanging-indent');
686
+ citeDiv.classList.add('csl-entry');
687
+ var biblioDiv = window.document.getElementById('ref-' + cite);
688
+ if (biblioDiv) {
689
+ citeDiv.innerHTML = biblioDiv.innerHTML;
690
+ }
691
+ popup.appendChild(citeDiv);
692
+ });
693
+ return popup.innerHTML;
694
+ });
695
+ }
696
+ }
697
+ });
698
+ </script>
699
+ </div> <!-- /content -->
700
+
701
+
702
+
703
+
704
+ </body></html>