[
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"root\": true,\n  \"parser\": \"@typescript-eslint/parser\",\n  \"parserOptions\": {\n    \"ecmaVersion\": 6,\n    \"sourceType\": \"module\"\n  },\n  \"plugins\": [\"@typescript-eslint\"],\n  \"rules\": {\n    \"@typescript-eslint/naming-convention\": \"warn\",\n    \"@typescript-eslint/semi\": \"off\",\n    \"curly\": \"warn\",\n    \"eqeqeq\": \"warn\",\n    \"no-throw-literal\": \"warn\",\n    \"semi\": \"off\"\n  },\n  \"ignorePatterns\": \"resources\"\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "out\ndist\nnode_modules\n.vscode-test/\n*.vsix\nresources/webview"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"plugins\": [\"./node_modules/prettier-plugin-import-sort\"],\n  \"singleQuote\": true,\n  \"semi\": false\n}\n"
  },
  {
    "path": ".vscode/extensions.json",
    "content": "{\n  // See http://go.microsoft.com/fwlink/?LinkId=827846\n  // for the documentation about the extensions.json format\n  \"recommendations\": [\"dbaeumer.vscode-eslint\", \"eamodio.tsl-problem-matcher\"]\n}\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "// A launch configuration that compiles the extension and then opens it inside a new window\n// Use IntelliSense to learn about possible attributes.\n// Hover to view descriptions of existing attributes.\n// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"name\": \"Run Extension\",\n      \"type\": \"extensionHost\",\n      \"request\": \"launch\",\n      \"args\": [\"--extensionDevelopmentPath=${workspaceFolder}\"],\n      \"outFiles\": [\"${workspaceFolder}/dist/**/*.js\"]\n    },\n    {\n      \"name\": \"Extension Tests\",\n      \"type\": \"extensionHost\",\n      \"request\": \"launch\",\n      \"args\": [\n        \"--extensionDevelopmentPath=${workspaceFolder}\",\n        \"--extensionTestsPath=${workspaceFolder}/out/test/suite/index\"\n      ],\n      \"outFiles\": [\"${workspaceFolder}/out/test/**/*.js\"]\n    }\n  ]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "// Place your settings in this file to overwrite default and user settings.\n{\n  \"files.exclude\": {\n    \"out\": false // set this to true to hide the \"out\" folder with the compiled JS files\n  },\n  \"search.exclude\": {\n    \"out\": true // set this to false to include \"out\" folder in search results\n  },\n  // Turn off tsc task auto detection since we have the necessary tasks as npm scripts\n  \"typescript.tsc.autoDetect\": \"off\"\n}\n"
  },
  {
    "path": ".vscodeignore",
    "content": ".github/**\n.vscode/**\n.vscode-test/**\nout/**\nsrc/**\n.gitignore\n.yarnrc\nvsc-extension-quickstart.md\n**/tsconfig.json\n**/.eslintrc.json\n**/*.map\n**/*.ts\n"
  },
  {
    "path": ".yarnrc",
    "content": "--ignore-engines true"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## 1.1.0\n\n- Support viewing private pages using `accessToken` setting\n- Allow certain embeddings by the `allowEmbeds` setting\n- Allow dynamic line height using `lineHeight` setting\n- Update extension icon and demo.gif\n- Add sidebar to view recent and bookmarked pages\n\n## 1.0.1\n\n- Parse URLs including usernames\n- Show error dialog\n\n## 1.0.0\n\n- Initial release\n- Add preview gif to README.md\n\n## 0.0.4\n\n- Exclude webview dependencies from package, reducing extension size\n\n## 0.0.3\n\n- Fix disappearing input box error\n\n## 0.0.2\n\n- Fix disposed webview left in cache error\n- Add fallback CSS properties\n- Use `--vscode-font-family` as monospace font\n- Align icon center\n\n## 0.0.1\n\n- Initial preview release\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Frenco Jobs\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "README.md",
    "content": "# VSCode Notion\n\nBrowse Notion pages directly in Visual Studio Code.\n\n> Disclaimer: This is an unofficial extension made using an unofficial renderer with the data from an unofficial API.\n\n<img align=\"center\" src=\"https://raw.githubusercontent.com/frencojobs/vscode-notion/main/.github/demo.gif\" />\n\n## Features\n\nHere is a list of features that the extension currently supports.\n\n- 📄 View Notion pages while you're coding\n- 🔓 Supports both private + public pages\n- 🗓️ Browse recently opened pages\n- 📌 Bookmark important ones for next times\n\nHere is the checklist for features I'm planning to add to the extension.\n\n- [x] View notion pages\n- [x] Support embeddings for certain trusted sources\n- [ ] Native syntax highlight for code snippets\n- [ ] Authentication for viewing private pages\n- [ ] Sidebar for all of user's pages\n\n_Authentication is not currently available since the unofficial API doesn't support much._ But I'm planning to add it as soon as I get access to the official notion API that is coming very soon.\n\n## Configuration\n\n### API\n\nA URL to get the data for Notion pages. By default, it is a hosted version of [Notion Api Worker](https://github.com/splitbee/notion-api-worker) and feel free to host your own and use.\n\n### Access Token\n\nThe `Authorization` header to be used when getting the data from the API. Will be empty by default and replace it with your own to view private pages of yours. As of now, you can get the token from `token_v2` of Notion website's cookies in your web browser.\n\n### Allow Embeds\n\nA boolean value to determine whether to allow iframe embeddings when viewing pages. It will be `false` by default.\n\n### Font Family\n\nA comma separated string of font families to use in the pages. Will be `'Helvetica Neue', sans-serif` by default.\n\n### Font Size\n\nThe font size in pixels to use in the pages. It will be `14` by default.\n\n### Line Height\n\nThe unitless line height value to use in the pages. By default, `1.5` will be used.\n\n---\n\nHere are the available settings with default values.\n\n```json\n{\n  \"VSCodeNotion.api\": \"https://notion-api.frenco.dev\",\n  \"VSCodeNotion.accessToken\": \"\",\n  \"VSCodeNotion.allowEmbeds\": false,\n  \"VSCodeNotion.fontFamily\": \"'Helvetica Neue', sans-serif\",\n  \"VSCodeNotion.fontSize\": 14,\n  \"VSCodeNotion.lineHeight\": 1.5\n}\n```\n\n## Acknowledgement\n\nThis project won't be possible without [React Notion](https://github.com/splitbee/react-notion) and [Notion API Worker](https://github.com/splitbee/notion-api-worker) libraries by Splitbee.\n\n## License\n\nMIT © Frenco Jobs\n"
  },
  {
    "path": "build/node-extension.webpack.config.js",
    "content": "'use strict'\n\nconst path = require('path')\n\n/**@type {import('webpack').Configuration}*/\nconst config = {\n  target: 'node',\n  mode: 'none',\n  entry: './src/extension.ts',\n  output: {\n    path: path.resolve(__dirname, '..', 'dist'),\n    filename: 'extension.js',\n    libraryTarget: 'commonjs2',\n  },\n  devtool: 'nosources-source-map',\n  externals: {\n    vscode: 'commonjs vscode',\n  },\n  resolve: {\n    extensions: ['.ts', '.js'],\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.ts$/,\n        exclude: /node_modules/,\n        use: [\n          {\n            loader: 'ts-loader',\n          },\n        ],\n      },\n    ],\n  },\n}\nmodule.exports = config\n"
  },
  {
    "path": "build/react-webview.webpack.config.js",
    "content": "'use strict'\n\nconst path = require('path')\n\n/**@type {import('webpack').Configuration}*/\nconst config = {\n  target: 'web',\n  mode: 'production',\n  entry: './src/webview/index.tsx',\n  output: {\n    path: path.resolve(__dirname, '..', 'resources/webview'),\n    filename: 'index.js',\n    libraryTarget: 'umd',\n  },\n  devtool: false,\n  resolve: {\n    extensions: ['.ts', '.tsx', '.js', '.jsx'],\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.tsx?$/,\n        exclude: /node_modules/,\n        use: [\n          {\n            loader: 'ts-loader',\n          },\n        ],\n      },\n    ],\n  },\n}\nmodule.exports = config\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"vscode-notion\",\n  \"version\": \"1.1.0\",\n  \"icon\": \"resources/icons/vscode-notion.png\",\n  \"displayName\": \"VSCode Notion\",\n  \"description\": \"Browse Notion pages directly in Visual Studio Code.\",\n  \"publisher\": \"frenco\",\n  \"author\": \"Frenco <hey@frenco.dev>\",\n  \"homepage\": \"https://github.com/frencojobs/vscode-notion#readme\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/frencojobs/vscode-notion\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/frencojobs/vscode-notion/issues\"\n  },\n  \"engines\": {\n    \"vscode\": \"^1.52.0\"\n  },\n  \"categories\": [\n    \"Other\"\n  ],\n  \"keywords\": [\n    \"notion\",\n    \"notion.so\"\n  ],\n  \"main\": \"./dist/extension.js\",\n  \"activationEvents\": [\n    \"onCommand:vscode-notion.openPage\",\n    \"onCommand:vscode-notion.refreshPage\",\n    \"onCommand:vscode-notion.copyLink\",\n    \"onCommand:vscode-notion.refreshRecents\",\n    \"onCommand:vscode-notion.clearRecents\",\n    \"onCommand:vscode-notion.removeRecent\",\n    \"onCommand:vscode-notion.refreshBookmarks\",\n    \"onCommand:vscode-notion.bookmarkPage\",\n    \"onCommand:vscode-notion.unBookmarkPage\",\n    \"onWebviewPanel:vscode-notion.pageView\",\n    \"onView:vscode-notion-recents\",\n    \"onView:vscode-notion-bookmarks\"\n  ],\n  \"contributes\": {\n    \"configuration\": {\n      \"title\": \"VSCode Notion\",\n      \"properties\": {\n        \"VSCodeNotion.api\": {\n          \"type\": \"string\",\n          \"default\": \"https://notion-api.frenco.dev\",\n          \"description\": \"Specifies the API url to get the Notion data from.\"\n        },\n        \"VSCodeNotion.accessToken\": {\n          \"type\": \"string\",\n          \"default\": \"\",\n          \"description\": \"Specifies the personal access token to use with API.\"\n        },\n        \"VSCodeNotion.allowEmbeds\": {\n          \"type\": \"boolean\",\n          \"default\": false,\n          \"description\": \"Specifies whether to allow embeds or not.\"\n        },\n        \"VSCodeNotion.fontSize\": {\n          \"type\": \"number\",\n          \"default\": 14,\n          \"description\": \"Specifies the font size in pixels.\"\n        },\n        \"VSCodeNotion.fontFamily\": {\n          \"type\": \"string\",\n          \"default\": \"'Helvetica Neue', sans-serif\",\n          \"description\": \"Specifies the font family to use when rendering the Notion page.\"\n        },\n        \"VSCodeNotion.lineHeight\": {\n          \"type\": \"number\",\n          \"default\": 1.5,\n          \"description\": \"Specifies the unitless line height.\"\n        }\n      }\n    },\n    \"commands\": [\n      {\n        \"command\": \"vscode-notion.openPage\",\n        \"category\": \"VSCode Notion\",\n        \"title\": \"Open A Notion Page\"\n      },\n      {\n        \"command\": \"vscode-notion.refreshPage\",\n        \"category\": \"VSCode Notion\",\n        \"title\": \"Refresh Active Page\",\n        \"icon\": \"$(extensions-refresh)\"\n      },\n      {\n        \"command\": \"vscode-notion.copyLink\",\n        \"category\": \"VSCode Notion\",\n        \"title\": \"Copy Link to Page\",\n        \"icon\": \"$(link)\"\n      },\n      {\n        \"command\": \"vscode-notion.refreshRecents\",\n        \"category\": \"VSCode Notion\",\n        \"title\": \"Refresh Recently Opened Pages\",\n        \"icon\": \"$(extensions-refresh)\"\n      },\n      {\n        \"command\": \"vscode-notion.clearRecents\",\n        \"category\": \"VSCode Notion\",\n        \"title\": \"Clear Recently Opened Pages\",\n        \"icon\": \"$(trash)\"\n      },\n      {\n        \"command\": \"vscode-notion.removeRecent\",\n        \"category\": \"VSCode Notion\",\n        \"title\": \"Remove Item From Recents\",\n        \"icon\": \"$(close)\"\n      },\n      {\n        \"command\": \"vscode-notion.refreshBookmarks\",\n        \"category\": \"VSCode Notion\",\n        \"title\": \"Refresh Bookmarked Pages\",\n        \"icon\": \"$(extensions-refresh)\"\n      },\n      {\n        \"command\": \"vscode-notion.bookmarkPage\",\n        \"category\": \"VSCode Notion\",\n        \"title\": \"Bookmark A Page\",\n        \"icon\": \"$(star-empty)\"\n      },\n      {\n        \"command\": \"vscode-notion.unBookmarkPage\",\n        \"category\": \"VSCode Notion\",\n        \"title\": \"Remove Page from Bookmarks\",\n        \"icon\": \"$(star-full)\"\n      }\n    ],\n    \"viewsContainers\": {\n      \"activitybar\": [\n        {\n          \"id\": \"vscode-notion-sidebar\",\n          \"title\": \"VSCode Notion\",\n          \"icon\": \"resources/icons/dark/notion.svg\"\n        }\n      ]\n    },\n    \"viewsWelcome\": [\n      {\n        \"view\": \"vscode-notion-recents\",\n        \"contents\": \"You have not yet opened a page recently.\\n[Open A Page](command:vscode-notion.openPage)\"\n      }\n    ],\n    \"views\": {\n      \"vscode-notion-sidebar\": [\n        {\n          \"type\": \"tree\",\n          \"id\": \"vscode-notion-recents\",\n          \"name\": \"Recents\",\n          \"contextualTitle\": \"Recently Opened Pages\"\n        },\n        {\n          \"type\": \"tree\",\n          \"id\": \"vscode-notion-bookmarks\",\n          \"name\": \"Bookmarks\",\n          \"contextualTitle\": \"Bookmarked Pages\"\n        }\n      ]\n    },\n    \"menus\": {\n      \"commandPalette\": [\n        {\n          \"command\": \"vscode-notion.refreshPage\",\n          \"when\": \"false\"\n        },\n        {\n          \"command\": \"vscode-notion.copyLink\",\n          \"when\": \"false\"\n        },\n        {\n          \"command\": \"vscode-notion.refreshRecents\",\n          \"when\": \"false\"\n        },\n        {\n          \"command\": \"vscode-notion.clearRecents\",\n          \"when\": \"false\"\n        },\n        {\n          \"command\": \"vscode-notion.removeRecent\",\n          \"when\": \"false\"\n        },\n        {\n          \"command\": \"vscode-notion.refreshBookmarks\",\n          \"when\": \"false\"\n        },\n        {\n          \"command\": \"vscode-notion.bookmarkPage\",\n          \"when\": \"false\"\n        },\n        {\n          \"command\": \"vscode-notion.unBookmarkPage\",\n          \"when\": \"false\"\n        }\n      ],\n      \"editor/title\": [\n        {\n          \"command\": \"vscode-notion.refreshPage\",\n          \"when\": \"notionPageFocus\",\n          \"group\": \"navigation@0\"\n        },\n        {\n          \"command\": \"vscode-notion.bookmarkPage\",\n          \"when\": \"notionPageFocus && !notionPageBookmark\",\n          \"group\": \"navigation@1\"\n        },\n        {\n          \"command\": \"vscode-notion.unBookmarkPage\",\n          \"when\": \"notionPageFocus && notionPageBookmark\",\n          \"group\": \"navigation@1\"\n        },\n        {\n          \"command\": \"vscode-notion.copyLink\",\n          \"when\": \"notionPageFocus\"\n        }\n      ],\n      \"view/title\": [\n        {\n          \"command\": \"vscode-notion.refreshRecents\",\n          \"when\": \"view == vscode-notion-recents\",\n          \"group\": \"navigation@0\"\n        },\n        {\n          \"command\": \"vscode-notion.clearRecents\",\n          \"when\": \"view == vscode-notion-recents\",\n          \"group\": \"navigation@1\"\n        },\n        {\n          \"command\": \"vscode-notion.refreshBookmarks\",\n          \"when\": \"view == vscode-notion-bookmarks\",\n          \"group\": \"navigation@0\"\n        }\n      ],\n      \"view/item/context\": [\n        {\n          \"command\": \"vscode-notion.removeRecent\",\n          \"when\": \"view == vscode-notion-recents\",\n          \"group\": \"inline\"\n        }\n      ]\n    }\n  },\n  \"scripts\": {\n    \"vscode:prepublish\": \"yarn run package:webview && yarn run package\",\n    \"compile:webview\": \"webpack --config ./build/react-webview.webpack.config.js\",\n    \"compile\": \"webpack --config ./build/node-extension.webpack.config.js\",\n    \"watch:webview\": \"webpack --watch --config ./build/react-webview.webpack.config.js\",\n    \"watch\": \"webpack --watch --config ./build/node-extension.webpack.config.js\",\n    \"package:webview\": \"webpack --mode production --devtool hidden-source-map --config ./build/react-webview.webpack.config.js\",\n    \"package\": \"webpack --mode production --devtool hidden-source-map --config ./build/node-extension.webpack.config.js\",\n    \"test-compile\": \"tsc -p ./\",\n    \"test-watch\": \"tsc -watch -p ./\",\n    \"pretest\": \"yarn run test-compile && yarn run lint\",\n    \"lint\": \"eslint src --ext ts\",\n    \"test\": \"node ./out/test/runTest.js\",\n    \"format\": \"prettier --write .\"\n  },\n  \"devDependencies\": {\n    \"@types/glob\": \"^7.1.3\",\n    \"@types/mocha\": \"^8.0.4\",\n    \"@types/node\": \"^12.11.7\",\n    \"@types/node-fetch\": \"^2.5.7\",\n    \"@types/react\": \"^17.0.0\",\n    \"@types/react-dom\": \"^17.0.0\",\n    \"@types/vscode\": \"^1.52.0\",\n    \"@typescript-eslint/eslint-plugin\": \"^4.9.0\",\n    \"@typescript-eslint/parser\": \"^4.9.0\",\n    \"eslint\": \"^7.15.0\",\n    \"glob\": \"^7.1.6\",\n    \"import-sort-style-absolute\": \"^1.0.1\",\n    \"mocha\": \"^8.1.3\",\n    \"prettier\": \"^2.2.1\",\n    \"prettier-plugin-import-sort\": \"^0.0.6\",\n    \"ts-loader\": \"^8.0.11\",\n    \"typescript\": \"^4.1.2\",\n    \"vscode-test\": \"^1.4.1\",\n    \"webpack\": \"^5.10.0\",\n    \"webpack-cli\": \"^4.2.0\",\n    \"react\": \"^17.0.1\",\n    \"react-dom\": \"^17.0.1\",\n    \"react-notion\": \"^0.9.3\"\n  },\n  \"dependencies\": {\n    \"axios\": \"^0.21.1\"\n  },\n  \"importSort\": {\n    \".js, .jsx, .ts, .tsx\": {\n      \"style\": \"absolute\",\n      \"parser\": \"typescript\"\n    }\n  },\n  \"license\": \"MIT\"\n}\n"
  },
  {
    "path": "resources/styles/notion.css",
    "content": "body.vscode-light .notion-page-link,\nbody.vscode-light .notion-image-caption,\nbody.vscode-light .notion-bookmark > div:first-child,\nbody.vscode-light .notion-bookmark-link > div,\nbody.vscode-light .notion-th {\n  color: rgb(55, 53, 47);\n  caret-color: rgb(55, 53, 47);\n}\n\nbody.vscode-dark .notion-page-link,\nbody.vscode-dark .notion-image-caption,\nbody.vscode-dark .notion-bookmark > div:first-child,\nbody.vscode-dark .notion-bookmark-link > div,\nbody.vscode-dark .notion-th {\n  color: rgba(255, 255, 255, 0.9);\n  caret-color: rgba(255, 255, 255, 0.9);\n}\n\nbody.vscode-light .notion-bookmark,\nbody.vscode-light .notion-table,\nbody.vscode-light .notion-th,\nbody.vscode-light .notion-td {\n  border: 1px solid rgba(55, 53, 47, 0.16);\n}\n\nbody.vscode-dark .notion-bookmark,\nbody.vscode-dark .notion-table,\nbody.vscode-dark .notion-th,\nbody.vscode-dark .notion-td {\n  border: 1px solid rgba(255, 255, 255, 0.9);\n}\n\nbody.vscode-light .notion-gallery {\n  border-top: 1px solid rgba(55, 53, 47, 0.16);\n}\n\nbody.vscode-dark .notion-gallery {\n  border-top: 1px solid rgba(255, 255, 255, 0.9);\n}\n\n.notion {\n  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica,\n    'Apple Color Emoji', Arial, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol';\n  font-size: 14;\n  line-height: 1.5;\n\n  font-family: var(--notion-font-family);\n  font-size: var(--notion-font-size);\n  line-height: var(--notion-line-height);\n}\n\n.notion > *,\n.notion-page > *,\n.notion-column > * {\n  padding: 3px 0px;\n}\n\n.notion * {\n  box-sizing: border-box;\n  margin-block-start: 0px;\n  margin-block-end: 0px;\n}\n\n.notion-red {\n  color: rgb(224, 62, 62);\n}\n.notion-pink {\n  color: rgb(173, 26, 114);\n}\n.notion-blue {\n  color: rgb(11, 110, 153);\n}\n.notion-purple {\n  color: rgb(105, 64, 165);\n}\n.notion-teal {\n  color: rgb(15, 123, 108);\n}\n.notion-yellow {\n  color: rgb(223, 171, 1);\n}\n.notion-orange {\n  color: rgb(217, 115, 13);\n}\n.notion-brown {\n  color: rgb(100, 71, 58);\n}\n.notion-gray {\n  color: rgb(155, 154, 151);\n}\n.notion-red_background {\n  background-color: rgb(251, 228, 228);\n}\n.notion-pink_background {\n  background-color: rgb(244, 223, 235);\n}\n.notion-blue_background {\n  background-color: rgb(221, 235, 241);\n}\n.notion-purple_background {\n  background-color: rgb(234, 228, 242);\n}\n.notion-teal_background {\n  background-color: rgb(221, 237, 234);\n}\n.notion-yellow_background {\n  background-color: rgb(251, 243, 219);\n}\n.notion-orange_background {\n  background-color: rgb(250, 235, 221);\n}\n.notion-brown_background {\n  background-color: rgb(233, 229, 227);\n}\n.notion-gray_background {\n  background-color: rgb(235, 236, 237);\n}\n.notion-red_background_co {\n  background-color: rgb(251, 228, 228, 0.3);\n}\n.notion-pink_background_co {\n  background-color: rgb(244, 223, 235, 0.3);\n}\n.notion-blue_background_co {\n  background-color: rgb(221, 235, 241, 0.3);\n}\n.notion-purple_background_co {\n  background-color: rgb(234, 228, 242, 0.3);\n}\n.notion-teal_background_co {\n  background-color: rgb(221, 237, 234, 0.3);\n}\n.notion-yellow_background_co {\n  background-color: rgb(251, 243, 219, 0.3);\n}\n.notion-orange_background_co {\n  background-color: rgb(250, 235, 221, 0.3);\n}\n.notion-brown_background_co {\n  background-color: rgb(233, 229, 227, 0.3);\n}\n.notion-gray_background_co {\n  background-color: rgb(235, 236, 237, 0.3);\n}\n\n.notion b {\n  font-weight: 600;\n}\n\n.notion-title {\n  font-size: 2.5em;\n  font-weight: 700;\n  margin-top: 0.75em;\n  margin-bottom: 0.25em;\n}\n\n.notion-h1,\n.notion-h2,\n.notion-h3 {\n  font-weight: 600;\n  line-height: 1.3;\n  padding: 3px 2px;\n}\n\n.notion-h1 {\n  font-size: 1.875em;\n  margin-top: 1.4em;\n}\n.notion-h1:first-child {\n  margin-top: 0;\n}\n.notion-h2 {\n  font-size: 1.5em;\n  margin-top: 1.1em;\n}\n.notion-h3 {\n  font-size: 1.25em;\n  margin-top: 1em;\n}\n.notion-emoji {\n  font-family: 'Apple Color Emoji', Arial, sans-serif, 'Segoe UI Emoji',\n    'Segoe UI Symbol';\n}\n.notion-page-cover {\n  display: block;\n  object-fit: cover;\n  width: 100%;\n  height: 30vh;\n  min-height: 30vh;\n  padding: 0;\n}\n\n.notion-page {\n  padding: 0;\n  margin: 0 auto;\n  max-width: 708px;\n  width: 100%;\n}\n\n@media only screen and (max-width: 730px) {\n  .notion-page {\n    padding: 0 2vw;\n  }\n}\n\n.notion-page-offset {\n  margin-top: 96px;\n}\n\nspan.notion-page-icon-cover {\n  height: 78px;\n  width: 78px;\n  font-size: 78px;\n  display: inline-block;\n  line-height: 1.1;\n  margin-left: 0px;\n}\n\nspan.notion-page-icon-offset {\n  margin-top: -42px;\n}\n\nimg.notion-page-icon-cover {\n  border-radius: 3px;\n  width: 124px;\n  height: 124px;\n  margin: 8px;\n}\n\nimg.notion-page-icon-offset {\n  margin-top: -80px;\n}\n\n.notion-full-width {\n  padding: 0 40px;\n  max-width: 100%;\n}\n\n.notion-small-text {\n  font-size: 14px;\n}\n.notion-quote {\n  white-space: pre-wrap;\n  word-break: break-word;\n  border-left: 3px solid currentcolor;\n  padding: 0.2em 0.9em;\n  margin: 0;\n  font-size: 1.2em;\n}\n.notion-hr {\n  margin: 6px 0px;\n  padding: 0;\n  border-top-width: 1px;\n  border-bottom-width: 0;\n  border-color: rgba(55, 53, 47, 0.09);\n}\n.notion-link {\n  color: inherit;\n  word-break: break-word;\n  text-decoration: underline;\n  text-decoration-color: inherit;\n}\n.notion-blank {\n  min-height: 1rem;\n  padding: 3px 2px;\n  margin-top: 1px;\n  margin-bottom: 1px;\n}\n.notion-page-link {\n  display: flex;\n  /* color: rgb(55, 53, 47); */\n  text-decoration: none;\n  height: 30px;\n  margin: 1px 0px;\n  transition: background 120ms ease-in 0s;\n}\n.notion-page-link:hover {\n  background: rgba(55, 53, 47, 0.08);\n}\n\n.notion-page-icon {\n  line-height: 1.4;\n  margin-right: 4px;\n  margin-left: 2px;\n}\nimg.notion-page-icon {\n  display: block;\n  object-fit: cover;\n  border-radius: 3px;\n  width: 20px;\n  height: 20px;\n}\n\n.notion-icon {\n  display: block;\n  width: 18px;\n  height: 18px;\n  color: rgba(55, 53, 47, 0.4);\n}\n\n.notion-page-text {\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  font-weight: 500;\n  line-height: 1.3;\n  border-bottom: 1px solid rgba(55, 53, 47, 0.16);\n  margin: 1px 0px;\n}\n\n.notion-inline-code {\n  color: #eb5757;\n  padding: 0.2em 0.4em;\n  background: rgba(135, 131, 120, 0.15);\n  border-radius: 3px;\n  font-size: 85%;\n  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier,\n    monospace;\n  font-family: var(--vscode-editor-font-family);\n}\n\n.notion-list {\n  margin: 0;\n  margin-block-start: 0.6em;\n  margin-block-end: 0.6em;\n}\n\n.notion-list-disc {\n  list-style-type: disc;\n  padding-inline-start: 1.7em;\n  margin-top: 0px;\n  margin-bottom: 0px;\n}\n.notion-list-numbered {\n  list-style-type: decimal;\n  padding-inline-start: 1.6em;\n  margin-top: 0px;\n  margin-bottom: 0px;\n}\n\n.notion-list-disc li {\n  padding-left: 0.1em;\n}\n\n.notion-list-numbered li {\n  padding-left: 0.2em;\n}\n\n.notion-list li {\n  padding: 6px 0px;\n  white-space: pre-wrap;\n}\n\n.notion-asset-wrapper {\n  margin: 0.5rem auto 0.5rem;\n  max-width: 100%;\n}\n\n.notion-asset-wrapper > img {\n  max-width: 100%;\n}\n\n.notion-asset-wrapper iframe {\n  border: none;\n}\n\n.notion-text {\n  white-space: pre-wrap;\n  caret-color: rgb(55, 53, 47);\n  padding: 3px 2px;\n}\n.notion-block {\n  padding: 3px 2px;\n}\n\n.notion .notion-code {\n  font-size: 85%;\n}\n\n.notion-code {\n  padding: 30px 16px 30px 20px;\n  margin: 4px 0;\n  border-radius: 3px;\n  tab-size: 2;\n  display: block;\n  box-sizing: border-box;\n  overflow-x: scroll;\n  background: rgb(247, 246, 243);\n  font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier,\n    monospace;\n  font-family: var(--vscode-editor-font-family);\n}\n\n.notion-column {\n  padding-top: 12px;\n  padding-bottom: 12px;\n}\n\n.notion-column > *:first-child {\n  margin-top: 0;\n  margin-left: 0;\n  margin-right: 0;\n}\n\n.notion-column > *:last-child {\n  margin-left: 0;\n  margin-right: 0;\n  margin-bottom: 0;\n}\n\n.notion-row {\n  display: flex;\n  overflow: hidden;\n}\n\n.notion-bookmark {\n  margin: 4px 0;\n  width: 100%;\n  box-sizing: border-box;\n  text-decoration: none;\n  /* border: 1px solid rgba(55, 53, 47, 0.16); */\n  border-radius: 3px;\n  display: flex;\n  overflow: hidden;\n  user-select: none;\n}\n\n.notion-bookmark > div:first-child {\n  flex: 4 1 180px;\n  padding: 12px 14px 14px;\n  overflow: hidden;\n  text-align: left;\n  /* color: rgb(55, 53, 47); */\n}\n\n.notion-bookmark-title {\n  font-size: 14px;\n  line-height: 20px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  min-height: 24px;\n  margin-bottom: 2px;\n}\n\n.notion-bookmark-description {\n  font-size: 12px;\n  line-height: 16px;\n  opacity: 0.6;\n  height: 32px;\n  overflow: hidden;\n}\n\n.notion-bookmark-link {\n  display: flex;\n  margin-top: 6px;\n}\n\n.notion-bookmark-link > img {\n  width: 16px;\n  height: 16px;\n  min-width: 16px;\n  margin-right: 6px;\n}\n\n.notion-bookmark-link > div {\n  font-size: 12px;\n  line-height: 16px;\n  /* color: rgb(55, 53, 47); */\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.notion-bookmark-image {\n  flex: 1 1 180px;\n  position: relative;\n}\n\n.notion-bookmark-image img {\n  object-fit: cover;\n  width: 100%;\n  height: 100%;\n  position: absolute;\n}\n\n.notion-column .notion-bookmark-image {\n  display: none;\n}\n\n@media (max-width: 640px) {\n  .notion-bookmark-image {\n    display: none;\n  }\n\n  .notion-row {\n    flex-direction: column;\n  }\n\n  .notion-row > *,\n  .notion-column > * {\n    width: 100% !important;\n  }\n}\n\n.notion-spacer:last-child {\n  display: none;\n}\n\n.notion-image-inset {\n  position: absolute;\n  left: 0;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  width: 100%;\n  height: 100%;\n  border-radius: 1px;\n}\n\n.notion-image-caption {\n  padding: 6px 0px;\n  white-space: pre-wrap;\n  word-break: break-word;\n  /* caret-color: rgb(55, 53, 47); */\n  font-size: 14px;\n  line-height: 1.4;\n  /* color: rgba(55, 53, 47, 0.6); */\n}\n\n.notion-callout {\n  padding: 16px 16px 16px 12px;\n  display: inline-flex;\n  width: 100%;\n  border-radius: 3px;\n  border-width: 1px;\n  align-items: center;\n  box-sizing: border-box;\n  margin: 4px 0;\n}\n.notion-callout-text {\n  margin-left: 8px;\n}\n\n.notion-toggle {\n  padding: 3px 2px;\n}\n.notion-toggle > summary {\n  cursor: pointer;\n  outline: none;\n}\n.notion-toggle > div {\n  margin-left: 1.1em;\n}\n\n.notion-table,\n.notion-th,\n.notion-td {\n  /* border: 1px solid rgba(55, 53, 47, 0.09); */\n  border-collapse: collapse;\n}\n\n.notion-table {\n  width: 100%;\n  border-left: none;\n  border-right: none;\n  border-spacing: 0px;\n  white-space: nowrap;\n}\n\n.notion-th,\n.notion-td {\n  font-weight: normal;\n  padding: 0.25em 0.5em;\n  line-height: 1.5;\n  min-height: 1.5em;\n  text-align: left;\n  font-size: 14px;\n}\n\n.notion-td.notion-bold {\n  font-weight: 500;\n}\n\n.notion-th {\n  /* color: rgba(55, 53, 47, 0.6); */\n  font-size: 14px;\n}\n\n.notion-td:first-child,\n.notion-th:first-child {\n  border-left: 0;\n}\n\n.notion-td:last-child,\n.notion-th:last-child {\n  border-right: 0;\n}\n\n.notion-gallery {\n  display: grid;\n  position: relative;\n  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));\n  grid-auto-rows: 1fr;\n  gap: 16px;\n  /* border-top: 1px solid rgba(55, 53, 47, 0.16); */\n  padding-top: 16px;\n  padding-bottom: 4px;\n}\n.notion-gallery-card {\n  display: block;\n  color: inherit;\n  text-decoration: none;\n  box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px,\n    rgba(15, 15, 15, 0.1) 0px 2px 4px;\n  border-radius: 3px;\n  background: white;\n  overflow: hidden;\n  transition: background 100ms ease-out 0s;\n  position: static;\n  height: 100%;\n}\n\n.notion-gallery-content {\n  padding: 8px 10px 6px;\n  font-size: 12px;\n  white-space: nowrap;\n}\n\n.notion-gallery-data.is-first {\n  white-space: nowrap;\n  word-break: break-word;\n  caret-color: rgb(55, 53, 47);\n  font-size: 14px;\n  line-height: 1.5;\n  min-height: 21px;\n  font-weight: 500;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.notion-page-header {\n  position: sticky;\n  top: 0;\n  width: 100%;\n  max-width: 100vw;\n  height: 45px;\n  min-height: 45px;\n  display: flex;\n  background: #fff;\n  flex-direction: row;\n  box-sizing: border-box;\n  justify-content: space-between;\n  align-items: center;\n  padding: 0 12px;\n  text-size-adjust: 100%;\n  line-height: 1.5;\n  line-height: 1.2;\n  font-size: 14px;\n}\n\n.notion-nav-breadcrumbs {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  height: 100%;\n  flex-grow: 0;\n  min-width: 0;\n  margin-right: 8px;\n}\n\n.notion-nav-breadcrumb {\n  display: inline-flex;\n  flex-direction: row;\n  align-items: center;\n  justify-content: center;\n  white-space: nowrap;\n\n  color: rgb(55, 53, 47);\n  text-decoration: none;\n  margin: 1px 0px;\n  padding: 4px 6px;\n  border-radius: 3px;\n  transition: background 120ms ease-in 0s;\n  user-select: none;\n  background: transparent;\n  cursor: pointer;\n}\n\nimg.notion-nav-icon {\n  width: 18px !important;\n  height: 18px !important;\n}\n\n.notion-nav-icon {\n  font-size: 18px;\n  margin-right: 6px;\n  line-height: 1.1;\n  color: #000;\n}\n\n.notion-nav-breadcrumb:not(.notion-nav-breadcrumb-active):hover {\n  background: rgba(55, 53, 47, 0.08);\n}\n\n.notion-nav-breadcrumb:not(.notion-nav-breadcrumb-active):active {\n  background: rgba(55, 53, 47, 0.16);\n}\n\n.notion-nav-breadcrumb.notion-nav-breadcrumb-active {\n  cursor: default;\n}\n\n.notion-nav-spacer {\n  margin: 0 2px;\n  color: rgba(55, 53, 47, 0.4);\n}\n"
  },
  {
    "path": "resources/styles/prism.css",
    "content": "/* PrismJS 1.23.0\nhttps://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+asciidoc+aspnet+asm6502+autohotkey+autoit+bash+basic+batch+bbcode+birb+bison+bnf+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cil+clojure+cmake+coffeescript+concurnas+csp+crystal+css-extras+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+firestore-security-rules+flow+fortran+ftl+gml+gcode+gdscript+gedcom+gherkin+git+glsl+go+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+http+hpkp+hsts+ichigojam+icon+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keyman+kotlin+latex+latte+less+lilypond+liquid+lisp+livescript+llvm+lolcode+lua+makefile+markdown+markup-templating+matlab+mel+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nginx+nim+nix+nsis+objectivec+ocaml+opencl+oz+parigp+parser+pascal+pascaligo+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+q+qml+qore+r+racket+jsx+tsx+reason+regex+renpy+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+stan+iecst+stylus+swift+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+turtle+twig+typescript+typoscript+unrealscript+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+wiki+xeora+xml-doc+xojo+xquery+yaml+yang+zig */\n/**\n * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML\n * Based on https://github.com/chriskempson/tomorrow-theme\n * @author Rose Pritchard\n */\n\ncode[class*='language-'],\npre[class*='language-'] {\n  color: #ccc;\n  background: none;\n  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;\n  font-family: var(--vscode-editor-font-family);\n  font-size: 1em;\n  text-align: left;\n  white-space: pre;\n  word-spacing: normal;\n  word-break: normal;\n  word-wrap: normal;\n  line-height: 1.5;\n\n  -moz-tab-size: 4;\n  -o-tab-size: 4;\n  tab-size: 4;\n\n  -webkit-hyphens: none;\n  -moz-hyphens: none;\n  -ms-hyphens: none;\n  hyphens: none;\n}\n\n/* Code blocks */\npre[class*='language-'] {\n  padding: 1em;\n  margin: 0.5em 0;\n  overflow: auto;\n}\n\n:not(pre) > code[class*='language-'],\npre[class*='language-'] {\n  background: #2d2d2d;\n}\n\n/* Inline code */\n:not(pre) > code[class*='language-'] {\n  padding: 0.1em;\n  border-radius: 0.3em;\n  white-space: normal;\n}\n\n.token.comment,\n.token.block-comment,\n.token.prolog,\n.token.doctype,\n.token.cdata {\n  color: #999;\n}\n\n.token.punctuation {\n  color: #ccc;\n}\n\n.token.tag,\n.token.attr-name,\n.token.namespace,\n.token.deleted {\n  color: #e2777a;\n}\n\n.token.function-name {\n  color: #6196cc;\n}\n\n.token.boolean,\n.token.number,\n.token.function {\n  color: #f08d49;\n}\n\n.token.property,\n.token.class-name,\n.token.constant,\n.token.symbol {\n  color: #f8c555;\n}\n\n.token.selector,\n.token.important,\n.token.atrule,\n.token.keyword,\n.token.builtin {\n  color: #cc99cd;\n}\n\n.token.string,\n.token.char,\n.token.attr-value,\n.token.regex,\n.token.variable {\n  color: #7ec699;\n}\n\n.token.operator,\n.token.entity,\n.token.url {\n  color: #67cdcc;\n}\n\n.token.important,\n.token.bold {\n  font-weight: bold;\n}\n.token.italic {\n  font-style: italic;\n}\n\n.token.entity {\n  cursor: help;\n}\n\n.token.inserted {\n  color: green;\n}\n"
  },
  {
    "path": "resources/styles/reset.css",
    "content": "html {\n  box-sizing: border-box;\n  font-size: 13px;\n}\n\n*,\n*:before,\n*:after {\n  box-sizing: inherit;\n}\n\nbody,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\np,\nol,\nul {\n  margin: 0;\n  padding: 0;\n  font-weight: normal;\n}\n\nimg {\n  max-width: 100%;\n  height: auto;\n}\n"
  },
  {
    "path": "resources/styles/vscode.css",
    "content": ":root {\n  --container-paddding: 0px;\n  --input-padding-vertical: 6px;\n  --input-padding-horizontal: 4px;\n  --input-margin-vertical: 4px;\n  --input-margin-horizontal: 0;\n}\n\nbody {\n  padding: 0 var(--container-paddding) 20px var(--container-paddding);\n  color: var(--vscode-foreground);\n  font-size: var(--vscode-font-size);\n  font-weight: var(--vscode-font-weight);\n  font-family: var(--vscode-font-family);\n  background-color: var(--vscode-editor-background);\n}\n\nol,\nul {\n  padding-left: var(--container-paddding);\n}\n\nbody > *,\nform > * {\n  margin-block-start: var(--input-margin-vertical);\n  margin-block-end: var(--input-margin-vertical);\n}\n\n*:focus {\n  outline-color: var(--vscode-focusBorder) !important;\n}\n\na {\n  color: var(--vscode-textLink-foreground);\n}\n\na:hover,\na:active {\n  color: var(--vscode-textLink-activeForeground);\n}\n\ncode {\n  font-size: var(--vscode-editor-font-size);\n  font-family: var(--vscode-editor-font-family);\n}\n\nbutton {\n  border: none;\n  padding: var(--input-padding-vertical) var(--input-padding-horizontal);\n  width: 100%;\n  text-align: center;\n  outline: 1px solid transparent;\n  outline-offset: 2px !important;\n  color: var(--vscode-button-foreground);\n  background: var(--vscode-button-background);\n}\n\nbutton:hover {\n  cursor: pointer;\n  background: var(--vscode-button-hoverBackground);\n}\n\nbutton:focus {\n  outline-color: var(--vscode-focusBorder);\n}\n\nbutton.secondary {\n  color: var(--vscode-button-secondaryForeground);\n  background: var(--vscode-button-secondaryBackground);\n}\n\nbutton.secondary:hover {\n  background: var(--vscode-button-secondaryHoverBackground);\n}\n\ninput:not([type='checkbox']),\ntextarea {\n  display: block;\n  width: 100%;\n  border: none;\n  font-family: var(--vscode-font-family);\n  padding: var(--input-padding-vertical) var(--input-padding-horizontal);\n  color: var(--vscode-input-foreground);\n  outline-color: var(--vscode-input-border);\n  background-color: var(--vscode-input-background);\n}\n\ninput::placeholder,\ntextarea::placeholder {\n  color: var(--vscode-input-placeholderForeground);\n}\n"
  },
  {
    "path": "src/CommandManager.ts",
    "content": "import * as vscode from 'vscode'\n\nexport interface Command {\n  readonly id: string\n  execute(...args: any[]): void\n}\n\nexport class CommandManager {\n  private readonly commands = new Map<string, vscode.Disposable>()\n\n  public dispose() {\n    for (const registration of this.commands.values()) {\n      registration.dispose()\n    }\n    this.commands.clear()\n  }\n\n  public register<T extends Command>(command: T): T {\n    this.registerCommand(command.id, command.execute, command)\n    return command\n  }\n\n  private registerCommand(\n    id: string,\n    impl: (...args: any[]) => void,\n    thisArg?: any\n  ) {\n    if (this.commands.has(id)) {\n      return\n    }\n    this.commands.set(id, vscode.commands.registerCommand(id, impl, thisArg))\n  }\n}\n"
  },
  {
    "path": "src/commands/BookmarkPage.ts",
    "content": "import { Command } from '../CommandManager'\nimport NotionPanelManager from '../features/NotionPanelManager'\n\nexport class BookmarkPage implements Command {\n  public readonly id = 'vscode-notion.bookmarkPage'\n\n  constructor(private readonly manager: NotionPanelManager) {}\n\n  execute() {\n    const activeViews = Array.from(this.manager.cache.values()).filter(\n      (x) => x.isActive\n    )\n\n    if (activeViews.length > 0) {\n      activeViews[0].bookmark()\n    }\n  }\n}\n"
  },
  {
    "path": "src/commands/ClearRecents.ts",
    "content": "import { Command } from '../CommandManager'\nimport NotionPanelManager from '../features/NotionPanelManager'\n\nexport class ClearRecents implements Command {\n  public readonly id = 'vscode-notion.clearRecents'\n\n  constructor(private readonly manager: NotionPanelManager) {}\n\n  execute() {\n    this.manager.clearRecents()\n  }\n}\n"
  },
  {
    "path": "src/commands/CopyLink.ts",
    "content": "import * as vscode from 'vscode'\n\nimport { Command } from '../CommandManager'\nimport NotionPanelManager from '../features/NotionPanelManager'\n\nexport class CopyLink implements Command {\n  public readonly id = 'vscode-notion.copyLink'\n\n  constructor(private readonly manager: NotionPanelManager) {}\n\n  execute() {\n    const activeViews = Array.from(this.manager.cache.values()).filter(\n      (x) => x.isActive\n    )\n\n    if (activeViews.length > 0) {\n      vscode.env.clipboard.writeText(`https://notion.so/${activeViews[0].id}`)\n    }\n  }\n}\n"
  },
  {
    "path": "src/commands/OpenPage.ts",
    "content": "import * as vscode from 'vscode'\n\nimport { Command } from '../CommandManager'\nimport NotionPanelManager from '../features/NotionPanelManager'\nimport parseId from '../utils/parseId'\n\nexport class OpenPage implements Command {\n  public readonly id = 'vscode-notion.openPage'\n\n  public constructor(private readonly manager: NotionPanelManager) {}\n\n  public async execute(urlOrId?: string) {\n    let input = urlOrId ?? ''\n\n    if (!urlOrId) {\n      input =\n        (await vscode.window.showInputBox({\n          prompt: 'Enter a full URL or just ID of the page.',\n        })) ?? ''\n    }\n\n    if (!!input.trim()) {\n      const id = parseId(input)\n      this.manager.createOrShow(id)\n    }\n  }\n}\n"
  },
  {
    "path": "src/commands/RefreshBookmarks.ts",
    "content": "import { Command } from '../CommandManager'\nimport NotionPanelManager from '../features/NotionPanelManager'\n\nexport class RefreshBookmarks implements Command {\n  public readonly id = 'vscode-notion.reloadBookmarks'\n\n  constructor(private readonly manager: NotionPanelManager) {}\n\n  execute() {\n    this.manager.refreshBookmarks()\n  }\n}\n"
  },
  {
    "path": "src/commands/RefreshPage.ts",
    "content": "import { Command } from '../CommandManager'\nimport NotionPanelManager from '../features/NotionPanelManager'\n\nexport class RefreshPage implements Command {\n  public readonly id = 'vscode-notion.refreshPage'\n\n  constructor(private readonly manager: NotionPanelManager) {}\n\n  execute() {\n    Array.from(this.manager.cache.values())\n      .filter((x) => x.isActive)\n      .forEach((x) => x.refresh())\n  }\n}\n"
  },
  {
    "path": "src/commands/RefreshRecents.ts",
    "content": "import { Command } from '../CommandManager'\nimport NotionPanelManager from '../features/NotionPanelManager'\n\nexport class RefreshRecents implements Command {\n  public readonly id = 'vscode-notion.refreshRecents'\n\n  constructor(private readonly manager: NotionPanelManager) {}\n\n  execute() {\n    this.manager.refreshRecents()\n  }\n}\n"
  },
  {
    "path": "src/commands/RemoveRecent.ts",
    "content": "import * as vscode from 'vscode'\n\nimport { Command } from '../CommandManager'\nimport NotionPanelManager from '../features/NotionPanelManager'\n\nexport class RemoveRecent implements Command {\n  public readonly id = 'vscode-notion.removeRecent'\n\n  constructor(private readonly manager: NotionPanelManager) {}\n\n  execute(item: vscode.TreeItem) {\n    this.manager.removeRecent(item.id!)\n  }\n}\n"
  },
  {
    "path": "src/commands/UnBookmarkPage.ts",
    "content": "import { Command } from '../CommandManager'\nimport NotionPanelManager from '../features/NotionPanelManager'\n\nexport class UnBookmarkPage implements Command {\n  public readonly id = 'vscode-notion.unBookmarkPage'\n\n  constructor(private readonly manager: NotionPanelManager) {}\n\n  execute() {\n    const activeViews = Array.from(this.manager.cache.values()).filter(\n      (x) => x.isActive\n    )\n\n    if (activeViews.length > 0) {\n      activeViews[0].unBookmark()\n    }\n  }\n}\n"
  },
  {
    "path": "src/commands/index.ts",
    "content": "export { OpenPage } from './OpenPage'\nexport { RefreshPage } from './RefreshPage'\nexport { CopyLink } from './CopyLink'\nexport { ClearRecents } from './ClearRecents'\nexport { RefreshRecents } from './RefreshRecents'\nexport { RemoveRecent } from './RemoveRecent'\nexport { RefreshBookmarks } from './RefreshBookmarks'\nexport { BookmarkPage } from './BookmarkPage'\nexport { UnBookmarkPage } from './UnBookmarkPage'\n"
  },
  {
    "path": "src/extension.ts",
    "content": "import * as vscode from 'vscode'\n\nimport * as commands from './commands'\nimport { CommandManager } from './CommandManager'\nimport BookmarksProvider from './features/BookmarksProvider'\nimport NotionPanelManager from './features/NotionPanelManager'\nimport RecentsProvider from './features/RecentsProvider'\n\nexport async function activate(context: vscode.ExtensionContext) {\n  const manager = new NotionPanelManager(context)\n  const recents = new RecentsProvider(manager)\n  const bookmarks = new BookmarksProvider(manager)\n\n  context.subscriptions.push(registerCommands(manager))\n  context.subscriptions.push(\n    vscode.window.registerWebviewPanelSerializer(\n      'vscode-notion.pageView',\n      manager\n    )\n  )\n  context.subscriptions.push(\n    vscode.window.registerTreeDataProvider('vscode-notion-recents', recents)\n  )\n\n  context.subscriptions.push(\n    vscode.window.registerTreeDataProvider('vscode-notion-bookmarks', bookmarks)\n  )\n\n  context.subscriptions.push(\n    vscode.workspace.onDidChangeConfiguration(() => manager.reloadConfig())\n  )\n}\n\nfunction registerCommands(manager: NotionPanelManager): vscode.Disposable {\n  const commandManager = new CommandManager()\n  commandManager.register(new commands.OpenPage(manager))\n  commandManager.register(new commands.RefreshPage(manager))\n  commandManager.register(new commands.CopyLink(manager))\n\n  commandManager.register(new commands.ClearRecents(manager))\n  commandManager.register(new commands.RefreshRecents(manager))\n  commandManager.register(new commands.RemoveRecent(manager))\n\n  commandManager.register(new commands.BookmarkPage(manager))\n  commandManager.register(new commands.UnBookmarkPage(manager))\n  return commandManager\n}\n"
  },
  {
    "path": "src/features/BookmarksProvider.ts",
    "content": "import * as vscode from 'vscode'\n\nimport NotionPageItem from './NotionItem'\nimport NotionPanelManager from './NotionPanelManager'\n\nexport default class BookmarksProvider\n  implements vscode.TreeDataProvider<NotionPageItem> {\n  // --- yep, copied from StackOverflow\n  private _onDidChangeTreeData: vscode.EventEmitter<\n    NotionPageItem | undefined\n  > = new vscode.EventEmitter<NotionPageItem | undefined>()\n\n  readonly onDidChangeTreeData: vscode.Event<NotionPageItem | undefined> = this\n    ._onDidChangeTreeData.event\n\n  private refresh() {\n    this._onDidChangeTreeData.fire(undefined)\n  }\n  /// ---\n\n  constructor(private readonly manager: NotionPanelManager) {\n    this.manager.onDidBookmarksUpdated = () => {\n      this.refresh()\n    }\n  }\n\n  getTreeItem(element: NotionPageItem): vscode.TreeItem {\n    return element\n  }\n\n  getChildren(): Thenable<Array<NotionPageItem>> {\n    return Promise.resolve(\n      Object.entries(this.manager.bookmarks).map(\n        ([id, title]) => new NotionPageItem(title, id)\n      )\n    )\n  }\n}\n"
  },
  {
    "path": "src/features/NotionConfig.ts",
    "content": "import * as vscode from 'vscode'\n\nexport default class NotionConfig {\n  private static readonly key = 'VSCodeNotion'\n\n  public readonly api: string\n  public readonly accessToken: string\n  public readonly allowEmbeds: boolean\n  public readonly fontFamily: string\n  public readonly fontSize: number\n  public readonly lineHeight: number\n\n  constructor() {\n    const config = vscode.workspace.getConfiguration(NotionConfig.key)\n\n    this.api = config.get<string>('api')!\n    this.accessToken = config.get<string>('accessToken')!\n    this.allowEmbeds = config.get<boolean>('allowEmbeds')!\n    this.fontSize = config.get<number>('fontSize')!\n    this.fontFamily = config.get<string>('fontFamily')!\n    this.lineHeight = config.get<number>('lineHeight')!\n  }\n}\n"
  },
  {
    "path": "src/features/NotionItem.ts",
    "content": "import * as vscode from 'vscode'\n\nexport default class NotionPageItem extends vscode.TreeItem {\n  iconPath = new vscode.ThemeIcon('symbol-file')\n  command: vscode.Command = {\n    title: 'Open Page',\n    command: 'vscode-notion.openPage',\n    arguments: [this.id],\n  }\n\n  constructor(public readonly label: string, public readonly id: string) {\n    super(label)\n  }\n}\n"
  },
  {
    "path": "src/features/NotionPanel.ts",
    "content": "import * as vscode from 'vscode'\n\nimport NotionPanelManager from './NotionPanelManager'\nimport fetchData from '../utils/fetchData'\nimport getTitle from '../utils/getTitle'\n\nexport default class NotionPanel {\n  public static readonly viewType = 'vscode-notion.pageView'\n  public static readonly viewActiveContextKey = 'notionPageFocus'\n  public static readonly viewBookmarkContextKey = 'notionPageBookmark'\n\n  private disposables: Array<vscode.Disposable> = []\n\n  constructor(\n    public readonly id: string,\n    private readonly panel: vscode.WebviewPanel,\n    private readonly manager: NotionPanelManager,\n    private data: NotionData\n  ) {\n    this.update()\n    this.panel.onDidDispose(() => this.dispose(), null, this.disposables)\n    this.panel.onDidChangeViewState(\n      (_) => {\n        if (this.panel.visible) {\n          this.update()\n        }\n      },\n      null,\n      this.disposables\n    )\n    this.panel.webview.onDidReceiveMessage(\n      async (message: Message) => {\n        switch (message.command) {\n          case 'open':\n            await manager.createOrShow(message.text)\n            break\n        }\n      },\n      null,\n      this.disposables\n    )\n  }\n\n  public get isActive() {\n    return this.panel.active\n  }\n\n  public revive(column: vscode.ViewColumn | undefined) {\n    this.panel.reveal(column)\n  }\n\n  public async refresh() {\n    this.data = await vscode.window.withProgress<NotionData>(\n      {\n        title: 'VSCode Notion',\n        location: vscode.ProgressLocation.Notification,\n      },\n      async (progress, _) => {\n        progress.report({ message: 'Refreshing...' })\n        return fetchData({\n          id: this.id,\n          api: this.manager.config.api,\n          accessToken: this.manager.config.accessToken,\n        })\n      }\n    )\n\n    this.update()\n  }\n\n  public bookmark() {\n    this.manager.updateBookmarkEntry({\n      id: this.id,\n      title: getTitle(this.data),\n    })\n\n    this.setBookmarkContext(true)\n  }\n\n  public unBookmark() {\n    this.manager.removeBookmarkEntry(this.id)\n    this.update()\n  }\n\n  private dispose() {\n    this.setViewActiveContext(false)\n    this.panel.dispose()\n    this.manager.dispose(this.id)\n\n    while (this.disposables.length) {\n      const x = this.disposables.pop()\n      if (x) {\n        x.dispose()\n      }\n    }\n  }\n\n  private update() {\n    const title = getTitle(this.data)\n    this.panel.title = title\n\n    this.setViewActiveContext(this.panel.active)\n\n    if (Object.keys(this.manager.bookmarks).includes(this.id)) {\n      this.manager.updateBookmarkEntry({\n        id: this.id,\n        title,\n      })\n      this.setBookmarkContext(true)\n    } else {\n      this.setBookmarkContext(false)\n    }\n\n    this.manager.updateRecentEntry({\n      id: this.id,\n      title,\n    })\n\n    this.panel.webview.html = this.manager.getHTML(this.panel.webview, {\n      id: this.id,\n      data: this.data,\n    })\n  }\n\n  private setViewActiveContext(value: boolean) {\n    vscode.commands.executeCommand(\n      'setContext',\n      NotionPanel.viewActiveContextKey,\n      value\n    )\n  }\n\n  private setBookmarkContext(value: boolean) {\n    vscode.commands.executeCommand(\n      'setContext',\n      NotionPanel.viewBookmarkContextKey,\n      value\n    )\n  }\n}\n"
  },
  {
    "path": "src/features/NotionPanelManager.ts",
    "content": "import * as vscode from 'vscode'\n\nimport NotionConfig from './NotionConfig'\nimport NotionPanel from './NotionPanel'\nimport escapeAttribute from '../utils/escapeAttribute'\nimport fetchData from '../utils/fetchData'\nimport getNonce from '../utils/getNonce'\nimport sources from '../sources'\n\nexport default class NotionPanelManager\n  implements vscode.WebviewPanelSerializer {\n  private readonly recentsKey = 'recents'\n  private readonly bookmarksKey = 'bookmarks'\n  private readonly uri: vscode.Uri\n\n  public onDidRecentsUpdated: () => void = () => {}\n  public onDidBookmarksUpdated: () => void = () => {}\n\n  public config = new NotionConfig()\n  public cache = new Map<string, NotionPanel>()\n\n  constructor(private readonly context: vscode.ExtensionContext) {\n    this.uri = this.context.extensionUri\n  }\n\n  public async createOrShow(id: string) {\n    const column = vscode.window.activeTextEditor\n      ? vscode.window.activeTextEditor.viewColumn\n      : undefined\n\n    try {\n      if (this.cache.has(id)) {\n        this.cache.get(id)?.revive(column)\n      } else {\n        const data = await vscode.window.withProgress<NotionData>(\n          {\n            title: 'VSCode Notion',\n            location: vscode.ProgressLocation.Notification,\n          },\n          async (progress, _) => {\n            progress.report({ message: 'Loading...' })\n            return fetchData({\n              id,\n              api: this.config.api,\n              accessToken: this.config.accessToken,\n            })\n          }\n        )\n\n        const panel = vscode.window.createWebviewPanel(\n          NotionPanel.viewType,\n          'VSCode Notion',\n          column || vscode.ViewColumn.One,\n          {\n            enableScripts: true,\n            retainContextWhenHidden: true,\n            localResourceRoots: [vscode.Uri.joinPath(this.uri, 'resources')],\n          }\n        )\n        panel.iconPath = this.iconPath\n\n        this.cache.set(id, new NotionPanel(id, panel, this, data))\n      }\n    } catch (e) {\n      if (e instanceof Error) {\n        vscode.window.showErrorMessage(e.message)\n      } else {\n        vscode.window.showErrorMessage(e)\n      }\n    }\n  }\n\n  public async deserializeWebviewPanel(\n    webviewPanel: vscode.WebviewPanel,\n    state: { id: string; data: NotionData }\n  ) {\n    this.cache.set(\n      state.id,\n      new NotionPanel(state.id, webviewPanel, this, state.data)\n    )\n  }\n\n  public dispose(id: string) {\n    this.cache.delete(id)\n  }\n\n  public reloadConfig() {\n    this.config = new NotionConfig()\n  }\n\n  public get recents() {\n    return (\n      this.context.globalState.get<Record<string, string>>(this.recentsKey) ??\n      {}\n    )\n  }\n\n  public get bookmarks() {\n    return (\n      this.context.globalState.get<Record<string, string>>(this.bookmarksKey) ??\n      {}\n    )\n  }\n\n  public async removeRecent(id: string) {\n    const recents = this.context.globalState.get<Record<string, string>>(\n      this.recentsKey\n    )\n\n    if (recents) {\n      delete recents[id]\n    }\n\n    this.onDidRecentsUpdated()\n  }\n\n  public async removeBookmarkEntry(id: string) {\n    const bookmarks = this.context.globalState.get<Record<string, string>>(\n      this.bookmarksKey\n    )\n\n    if (bookmarks) {\n      delete bookmarks[id]\n    }\n\n    this.onDidBookmarksUpdated()\n  }\n\n  public async updateRecentEntry({ id, title }: { id: string; title: string }) {\n    const recents = this.context.globalState.get<Record<string, string>>(\n      this.recentsKey\n    )\n\n    await this.context.globalState.update(this.recentsKey, {\n      ...(!!recents ? recents : {}),\n      [id]: title,\n    })\n\n    this.onDidRecentsUpdated()\n  }\n\n  public async updateBookmarkEntry({\n    id,\n    title,\n  }: {\n    id: string\n    title: string\n  }) {\n    const bookmarks = this.context.globalState.get<Record<string, string>>(\n      this.bookmarksKey\n    )\n\n    await this.context.globalState.update(this.bookmarksKey, {\n      ...(!!bookmarks ? bookmarks : {}),\n      [id]: title,\n    })\n\n    this.onDidBookmarksUpdated()\n  }\n\n  public refreshRecents() {\n    this.onDidRecentsUpdated()\n  }\n\n  public refreshBookmarks() {\n    this.onDidBookmarksUpdated()\n  }\n\n  public clearRecents() {\n    this.context.globalState.update(this.recentsKey, {})\n    this.onDidRecentsUpdated()\n  }\n\n  private getSettingsOverrideStyles(): string {\n    return [\n      this.config.fontFamily\n        ? `--notion-font-family: ${this.config.fontFamily};`\n        : '',\n      !isNaN(this.config.fontSize)\n        ? `--notion-font-size: ${this.config.fontSize}px;`\n        : '',\n      !isNaN(this.config.lineHeight)\n        ? `--notion-line-height: ${this.config.lineHeight};`\n        : '',\n    ].join('')\n  }\n\n  private getMetaTags(webview: vscode.Webview, nonce: string): string {\n    const trustedSources = this.config.allowEmbeds\n      ? sources.join(' ')\n      : \"'none'\"\n\n    return `\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" \n            content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"Content-Security-Policy\" \n            content=\"frame-src ${trustedSources};\n                    default-src 'none'; \n                    style-src ${webview.cspSource} 'nonce-${nonce}'; \n                    img-src ${webview.cspSource} https:; \n                    script-src 'nonce-${nonce}';\">`\n  }\n\n  private getStyles(webview: vscode.Webview, uri: vscode.Uri): string {\n    return ['reset.css', 'vscode.css', 'notion.css', 'prism.css']\n      .map((x) =>\n        webview.asWebviewUri(vscode.Uri.joinPath(uri, 'resources', 'styles', x))\n      )\n      .map((x) => `<link href=\"${x}\" rel=\"stylesheet\" />`)\n      .join('')\n  }\n\n  private getScripts(\n    webview: vscode.Webview,\n    uri: vscode.Uri,\n    nonce: string,\n    state: NotionState\n  ): string {\n    const reactWebviewUri = webview.asWebviewUri(\n      vscode.Uri.joinPath(uri, 'resources', 'webview', 'index.js')\n    )\n\n    return `\n    <script nonce=${nonce}>\n      const vscode = acquireVsCodeApi();\n      vscode.setState(${JSON.stringify(state)});\n      window.vscode = vscode;\n    </script>\n    <script nonce=\"${nonce}\" src=\"${reactWebviewUri}\"></script>`\n  }\n\n  public get iconPath() {\n    const root = vscode.Uri.joinPath(this.uri, 'resources', 'icons')\n    return {\n      light: vscode.Uri.joinPath(root, 'light', 'notion.svg'),\n      dark: vscode.Uri.joinPath(root, 'dark', 'notion.svg'),\n    }\n  }\n\n  public getHTML(webview: vscode.Webview, state: NotionState) {\n    const nonce = getNonce()\n\n    return `\n    <!DOCTYPE html>\n    <html lang=\"en\" \n          style=\"${escapeAttribute(this.getSettingsOverrideStyles())}\">\n    <head>\n        ${this.getMetaTags(webview, nonce)}\n        ${this.getStyles(webview, this.uri)}\n    </head>\n    <body>\n        <div id=\"root\"></div>\n        ${this.getScripts(webview, this.uri, nonce, state)}\n    </body>\n    </html>`\n  }\n}\n"
  },
  {
    "path": "src/features/RecentsProvider.ts",
    "content": "import * as vscode from 'vscode'\n\nimport NotionPageItem from './NotionItem'\nimport NotionPanelManager from './NotionPanelManager'\n\nexport default class RecentsProvider\n  implements vscode.TreeDataProvider<NotionPageItem> {\n  // --- yep, copied from StackOverflow\n  private _onDidChangeTreeData: vscode.EventEmitter<\n    NotionPageItem | undefined\n  > = new vscode.EventEmitter<NotionPageItem | undefined>()\n\n  readonly onDidChangeTreeData: vscode.Event<NotionPageItem | undefined> = this\n    ._onDidChangeTreeData.event\n\n  private refresh() {\n    this._onDidChangeTreeData.fire(undefined)\n  }\n  /// ---\n\n  constructor(private readonly manager: NotionPanelManager) {\n    this.manager.onDidRecentsUpdated = () => {\n      this.refresh()\n    }\n  }\n\n  getTreeItem(element: NotionPageItem): vscode.TreeItem {\n    return element\n  }\n\n  getChildren(): Thenable<Array<NotionPageItem>> {\n    return Promise.resolve(\n      Object.entries(this.manager.recents)\n        .reverse()\n        .map(([id, title]) => new NotionPageItem(title, id))\n    )\n  }\n}\n"
  },
  {
    "path": "src/sources.ts",
    "content": "export default ['https://www.youtube.com', 'https://www.openstreetmap.org']\n"
  },
  {
    "path": "src/types.d.ts",
    "content": "type NotionData = Record<string, unknown>\ntype NotionState = {\n  id: string\n  data: NotionData\n}\ntype Message = {\n  command: string\n  text: string\n}\n"
  },
  {
    "path": "src/utils/escapeAttribute.ts",
    "content": "export default function escapeAttribute(value: string): string {\n  return value.replace(/\"/g, '&quot;')\n}\n"
  },
  {
    "path": "src/utils/fetchData.ts",
    "content": "import axios from 'axios'\n\nexport default async function fetchData({\n  api,\n  id,\n  accessToken,\n}: {\n  api: string\n  id: string\n  accessToken: string\n}): Promise<NotionData> {\n  if (!api.trim()) {\n    throw new Error(\"API URL can't be empty.\")\n  }\n\n  const res = await axios.get<NotionData>(`${api}/v1/page/${id}`, {\n    headers: !!accessToken\n      ? {\n          // eslint-disable-next-line @typescript-eslint/naming-convention\n          Authorization: `Bearer ${accessToken}`,\n        }\n      : {},\n  })\n\n  if (Object.keys(res.data).length < 1) {\n    throw new Error(\"Couldn't load the data from API.\")\n  } else {\n    return res.data\n  }\n}\n"
  },
  {
    "path": "src/utils/getNonce.ts",
    "content": "export default function getNonce() {\n  let text = ''\n  const possible =\n    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n  for (let i = 0; i < 32; i++) {\n    text += possible.charAt(Math.floor(Math.random() * possible.length))\n  }\n  return text\n}\n"
  },
  {
    "path": "src/utils/getTitle.ts",
    "content": "export default function getTitle(data: NotionData) {\n  const firstKey = Object.keys(data)[0]\n  const firstBlock = (data[firstKey] as {\n    value: Record<string, unknown>\n  }).value as {\n    properties: {\n      title: Array<Array<unknown>>\n    }\n  }\n\n  if (firstBlock?.properties?.title?.[0]) {\n    return firstBlock.properties.title[0]\n      .filter((x) => typeof x === 'string')\n      .reduce<string>((a, b) => a + b, '')\n  } else {\n    return firstKey.substr(0, 5)\n  }\n}\n"
  },
  {
    "path": "src/utils/parseId.ts",
    "content": "export default function parseId(urlOrId: string): string {\n  const pattern = /(?:https?:\\/\\/)?(?:www\\.)?notion\\.so\\/([\\w\\.-]*\\/?)*/\n  if (pattern.test(urlOrId)) {\n    return urlOrId.match(pattern)?.[1]!.replace('/', '')!\n  }\n  return urlOrId\n}\n"
  },
  {
    "path": "src/webview/App.tsx",
    "content": "import { BlockMapType, NotionRenderer } from 'react-notion'\nimport React from 'react'\n\ndeclare global {\n  interface Window {\n    vscode: {\n      getState: () => any\n      setState: (state: any) => void\n      postMessage: (message: any) => void\n    }\n  }\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst App: React.FC = () => {\n  return (\n    <NotionRenderer\n      fullPage\n      hideHeader\n      blockMap={window.vscode.getState().data as BlockMapType}\n      customBlockComponents={{\n        page: ({ blockValue, renderComponent }) => (\n          <span\n            onClick={() =>\n              window.vscode.postMessage({\n                command: 'open',\n                text: blockValue.id,\n              })\n            }\n          >\n            {renderComponent()}\n          </span>\n        ),\n      }}\n    />\n  )\n}\n\nexport default App\n"
  },
  {
    "path": "src/webview/index.tsx",
    "content": "import * as React from 'react'\nimport * as ReactDOM from 'react-dom'\n\nimport App from './App'\n\nReactDOM.render(<App />, document.getElementById('root'))\n"
  },
  {
    "path": "src/webview/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"target\": \"es6\",\n    \"outDir\": \"webview-compiled\",\n    \"lib\": [\"es6\", \"dom\"],\n    \"jsx\": \"react\",\n    \"sourceMap\": true,\n    \"rootDir\": \"..\",\n    \"noUnusedLocals\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"experimentalDecorators\": true,\n    \"resolveJsonModule\": true\n  },\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"target\": \"es6\",\n    \"outDir\": \"out\",\n    \"lib\": [\"es6\"],\n    \"sourceMap\": true,\n    \"rootDir\": \"src\",\n    \"strict\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noUnusedParameters\": true\n  },\n  \"exclude\": [\"node_modules\", \".vscode-test\", \"**/webview/**\"]\n}\n"
  }
]