diff --git a/.env b/.env deleted file mode 100644 index 7c425bb..0000000 --- a/.env +++ /dev/null @@ -1,2 +0,0 @@ -NODE_ENV = development -VUE_APP_PUBLIC_PATH = / \ No newline at end of file diff --git a/.env.deploy b/.env.deploy deleted file mode 100644 index 6984648..0000000 --- a/.env.deploy +++ /dev/null @@ -1,3 +0,0 @@ -NODE_ENV = production -VUE_APP_PUBLIC_PATH = /vue-code-view -VUE_APP_ENV = deploy \ No newline at end of file diff --git a/.env.play b/.env.play deleted file mode 100644 index 7dfa48f..0000000 --- a/.env.play +++ /dev/null @@ -1,3 +0,0 @@ -NODE_ENV = development -VUE_APP_PUBLIC_PATH = / -VUE_APP_ENV = play diff --git a/.env.production b/.env.production deleted file mode 100644 index dfe2880..0000000 --- a/.env.production +++ /dev/null @@ -1,3 +0,0 @@ -NODE_ENV = production -VUE_APP_PUBLIC_PATH = / -VUE_APP_ENV = pub \ No newline at end of file diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index cfe953b..0000000 --- a/.eslintignore +++ /dev/null @@ -1,14 +0,0 @@ -src/utils/popper.js -src/utils/date.js -node_modules -lib -coverage -deploy -*.md -*.scss -*.woff -*.ttf - - -output.js -examples/pages \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 25c67b1..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - root: true, - env: { - node: true, - }, - extends: [ - "eslint:recommended", - "plugin:vue/essential", - "@vue/eslint-config-typescript", - "@vue/eslint-config-prettier", - ], - parserOptions: { - ecmaVersion: 2020, - parser: "@typescript-eslint/parser", - warnOnUnsupportedTypeScriptVersion: false, // Version of TypeScript not officially supported - }, - rules: { - "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", - "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", - "no-useless-escape": process.env.NODE_ENV === "production" ? "warn" : "off", - "no-unused-vars": process.env.NODE_ENV === "production" ? "warn" : "off", - }, -}; diff --git a/.gitignore b/.gitignore index 9eb6541..a547bf3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,22 @@ -.DS_Store -node_modules -/dist -/lib/*.html -/lib/*.html.gz -/deploy - -# local env files -.env.local -.env.*.local - -# Log files +# Logs +logs +*.log npm-debug.log* yarn-debug.log* yarn-error.log* -*pnpm-debug.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local # Editor directories and files +.vscode/* +!.vscode/extensions.json .idea -.vscode +.DS_Store *.suo *.ntvs* *.njsproj diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 1b9fb39..0000000 --- a/.npmignore +++ /dev/null @@ -1,24 +0,0 @@ -# 忽略目录 -.vscode/ -examples/ -node_modules/ -public/ -build/ -src/ -dist/ -deploy/ -lib/*.html -lib/*.html.gz - - -# 忽略指定文件 -.browserslistrc -.eslintignore -.prettierignore -.env -.env.* -*.js -*.yml - -CHANGELOG.zh-CN.md -INSPIRED.zh-CN.md \ No newline at end of file diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index e269bdb..0000000 --- a/.prettierignore +++ /dev/null @@ -1,5 +0,0 @@ -*.md - -node_modules -lib -output.js diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index 15490cb..0000000 --- a/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - endOfLine: 'auto', -}; diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1d95044..0000000 --- a/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: node_js -node_js: 14 -install: - - yarn - -script: npm run deploy:build -after_script: - - mkdir temp_web - - cd temp_web - - git clone --depth 1 -b gh-pages --single-branch https://${TravisCI_Token}@${GH_REF} && cd vue-code-view - - echo 'copy && commit' - - rm -rf js fonts - - cp -rf ../../deploy/** . - - git config user.name "${U_NAME}" - - git config user.email "${U_EMAIL}" - - git add -A . - - git commit -m ":construction_worker:- Build & Deploy by Travis CI" - - git push origin gh-pages - - echo "DONE, Bye~" - - exit 0 \ No newline at end of file diff --git a/README.md b/README.md index 450a57d..ff4c19b 100644 --- a/README.md +++ b/README.md @@ -14,83 +14,21 @@ English | [简体中文](./README.zh-CN.md) -A lightweight code interaction component based on `vue 2.x`, which can edit, run and preview the code effect display in real time on the web page. +Vue SFC REPL as a Vue 2.7 component. -When reading docs that contain a lot of code, many project docs implement a `render` representation of the sample code via the `markdown loader`, but it is static. When we want to debug code, we generally need to open the local IDE or open online editor websites such as `codepen`, `codesandbox`, and it is also subject to whether the computer has a development environment installed or whether the network connection is smooth. +## 💻 Simple Usage -So can there be such a component that can support editing code in the page, edit, run and preview the code effect display in real time in the web page? +```vue + -Special thanks to the component [react-code-view](https://github.com/simonguo/react-code-view), based on which the vue version of the component was written! Using this component, you can edit the running code and preview the effect in real time by using the multi-sample code in the `vue` page or the `markdown` document. - -## ⚡ Online Demo - -![示例][preview-ol-v03] - -demo address: - -`codesandbox` example: [vue-code-view-example](https://codesandbox.io/s/vue-code-view-example-forked-nivmw?fontsize=14&hidenavigation=1&theme=dark) - -## ✨ Features - -- 💻 Code can be edited online and preview the effect in real time. -- 🎨 Support sample code highlighting, configure themes. -- 🌈 Support ` diff --git a/examples/assets/images/vcv-intro.png b/examples/assets/images/vcv-intro.png deleted file mode 100644 index d653040..0000000 Binary files a/examples/assets/images/vcv-intro.png and /dev/null differ diff --git a/examples/assets/images/vcv-logo-older.svg b/examples/assets/images/vcv-logo-older.svg deleted file mode 100644 index 97a46f5..0000000 --- a/examples/assets/images/vcv-logo-older.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - background - - - - - - - Layer 1 - </> - vuecodeview - - \ No newline at end of file diff --git a/examples/assets/images/vcv-logo-small.svg b/examples/assets/images/vcv-logo-small.svg deleted file mode 100644 index bc9c5a7..0000000 --- a/examples/assets/images/vcv-logo-small.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/assets/images/vcv-logo.svg b/examples/assets/images/vcv-logo.svg deleted file mode 100644 index d5fe86f..0000000 --- a/examples/assets/images/vcv-logo.svg +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/components/DemoBlock.vue b/examples/components/DemoBlock.vue deleted file mode 100644 index e17e315..0000000 --- a/examples/components/DemoBlock.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - - diff --git a/examples/components/VCVBackdrop.vue b/examples/components/VCVBackdrop.vue deleted file mode 100644 index d744280..0000000 --- a/examples/components/VCVBackdrop.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/examples/components/VCVFlyout.vue b/examples/components/VCVFlyout.vue deleted file mode 100644 index 5c61223..0000000 --- a/examples/components/VCVFlyout.vue +++ /dev/null @@ -1,70 +0,0 @@ - - - diff --git a/examples/components/VCVHamburger.vue b/examples/components/VCVHamburger.vue deleted file mode 100644 index acef5c8..0000000 --- a/examples/components/VCVHamburger.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/examples/components/VCVLink.vue b/examples/components/VCVLink.vue deleted file mode 100644 index 91aab3a..0000000 --- a/examples/components/VCVLink.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - diff --git a/examples/components/VCVMenu.vue b/examples/components/VCVMenu.vue deleted file mode 100644 index 6e027a4..0000000 --- a/examples/components/VCVMenu.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/examples/components/VCVMenuGroup.vue b/examples/components/VCVMenuGroup.vue deleted file mode 100644 index e72f101..0000000 --- a/examples/components/VCVMenuGroup.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/examples/components/VCVMenuLink.vue b/examples/components/VCVMenuLink.vue deleted file mode 100644 index 4d3857a..0000000 --- a/examples/components/VCVMenuLink.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/examples/components/VCVSocialLink.vue b/examples/components/VCVSocialLink.vue deleted file mode 100644 index 9b52b80..0000000 --- a/examples/components/VCVSocialLink.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - diff --git a/examples/components/VCVSocialLinks.vue b/examples/components/VCVSocialLinks.vue deleted file mode 100644 index d4bcf52..0000000 --- a/examples/components/VCVSocialLinks.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/examples/components/VCVSwitch.vue b/examples/components/VCVSwitch.vue deleted file mode 100644 index 670726d..0000000 --- a/examples/components/VCVSwitch.vue +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/examples/components/VCVSwitchAppearance.vue b/examples/components/VCVSwitchAppearance.vue deleted file mode 100644 index c14a438..0000000 --- a/examples/components/VCVSwitchAppearance.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/examples/components/VPSkipLink.vue b/examples/components/VPSkipLink.vue deleted file mode 100644 index ccc6a37..0000000 --- a/examples/components/VPSkipLink.vue +++ /dev/null @@ -1,65 +0,0 @@ - diff --git a/examples/components/icons/VCVIconAlignJustify.vue b/examples/components/icons/VCVIconAlignJustify.vue deleted file mode 100644 index b213f61..0000000 --- a/examples/components/icons/VCVIconAlignJustify.vue +++ /dev/null @@ -1,21 +0,0 @@ - diff --git a/examples/components/icons/VCVIconAlignLeft.vue b/examples/components/icons/VCVIconAlignLeft.vue deleted file mode 100644 index bd3510d..0000000 --- a/examples/components/icons/VCVIconAlignLeft.vue +++ /dev/null @@ -1,21 +0,0 @@ - diff --git a/examples/components/icons/VCVIconAlignRight.vue b/examples/components/icons/VCVIconAlignRight.vue deleted file mode 100644 index 4434f6c..0000000 --- a/examples/components/icons/VCVIconAlignRight.vue +++ /dev/null @@ -1,21 +0,0 @@ - diff --git a/examples/components/icons/VCVIconChevronDown.vue b/examples/components/icons/VCVIconChevronDown.vue deleted file mode 100644 index 7d5904f..0000000 --- a/examples/components/icons/VCVIconChevronDown.vue +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/examples/components/icons/VCVIconChevronLeft.vue b/examples/components/icons/VCVIconChevronLeft.vue deleted file mode 100644 index 1623404..0000000 --- a/examples/components/icons/VCVIconChevronLeft.vue +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/examples/components/icons/VCVIconChevronRight.vue b/examples/components/icons/VCVIconChevronRight.vue deleted file mode 100644 index 72f7cfd..0000000 --- a/examples/components/icons/VCVIconChevronRight.vue +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/examples/components/icons/VCVIconChevronUp.vue b/examples/components/icons/VCVIconChevronUp.vue deleted file mode 100644 index 25cca7c..0000000 --- a/examples/components/icons/VCVIconChevronUp.vue +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/examples/components/icons/VCVIconExternalLink.vue b/examples/components/icons/VCVIconExternalLink.vue deleted file mode 100644 index 7245990..0000000 --- a/examples/components/icons/VCVIconExternalLink.vue +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/examples/components/icons/VCVIconGitHub.vue b/examples/components/icons/VCVIconGitHub.vue deleted file mode 100644 index a7bc136..0000000 --- a/examples/components/icons/VCVIconGitHub.vue +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/examples/components/icons/VCVIconLanguages.vue b/examples/components/icons/VCVIconLanguages.vue deleted file mode 100644 index 126c58d..0000000 --- a/examples/components/icons/VCVIconLanguages.vue +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/examples/components/icons/VCVIconMoon.vue b/examples/components/icons/VCVIconMoon.vue deleted file mode 100644 index b74a8da..0000000 --- a/examples/components/icons/VCVIconMoon.vue +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/examples/components/icons/VCVIconMoreHorizontal.vue b/examples/components/icons/VCVIconMoreHorizontal.vue deleted file mode 100644 index 1d89acd..0000000 --- a/examples/components/icons/VCVIconMoreHorizontal.vue +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/examples/components/icons/VCVIconOutboundLink.vue b/examples/components/icons/VCVIconOutboundLink.vue deleted file mode 100644 index 4d74eee..0000000 --- a/examples/components/icons/VCVIconOutboundLink.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - diff --git a/examples/components/icons/VCVIconPlus.vue b/examples/components/icons/VCVIconPlus.vue deleted file mode 100644 index cac062d..0000000 --- a/examples/components/icons/VCVIconPlus.vue +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/examples/components/icons/VCVIconSun.vue b/examples/components/icons/VCVIconSun.vue deleted file mode 100644 index d846bad..0000000 --- a/examples/components/icons/VCVIconSun.vue +++ /dev/null @@ -1,36 +0,0 @@ - diff --git a/examples/composables/config.ts b/examples/composables/config.ts deleted file mode 100644 index 32508cb..0000000 --- a/examples/composables/config.ts +++ /dev/null @@ -1,613 +0,0 @@ -import { NavItem, PageData } from "@examples/types/config"; -import { SocialLink } from "@examples/types/socialLink"; - -import { - computed, - defineComponent, - h, - inject, - InjectionKey, - provide, - Ref, -} from "vue"; - -export function useConfig() { - return { - config: { - appearance: true, - socialLinks: [ - { - icon: "github", - link: "https://github.com/andurils/vue-code-view", - }, - // { - // icon: "languages", - // link: "https://staging-cn.vuejs.org/guide/typescript/options-api.html#typing-component-props", - // }, - ] as SocialLink[], - // NavScreenMenu - nav: [ - { - text: "REPL", - link: "/repl", - activeMatch: "repl", - }, - { - text: "文档", - activeMatch: "guide", - items: [ - { - text: "指南", - link: "/guide", - }, - { - text: "更新日志", - link: "/changelog", - }, - ], - }, - { - text: "关于", - items: [ - { - text: "github", - items: [ - { - text: "issues", - link: "https://github.com/andurils/vue-code-view/issues", - }, - { - text: "changelog", - link: "https://github.com/andurils/vue-code-view/blob/main/CHANGELOG.zh-CN.md", - }, - ], - }, - { - text: "参考", - items: [ - { - text: "Ant Design", - link: "https://ant.design/index-cn", - }, - { - text: "Ant Design Vue", - link: "https://www.antdv.com/components/overview", - }, - { - text: "Element UI", - link: "https://element.eleme.cn/#/zh-CN", - }, - ], - }, - ], - }, - ] as NavItem[], - // sidebar: config.sidebar && normalizeSideBar(config.sidebar) - sidebar: { - "/guide/": [ - { - text: "Essentials", - items: [ - { text: "Introduction", link: "/guide/introduction" }, - { text: "Installation", link: "/guide/installation" }, - { - text: "Application & Component Instances", - link: "/guide/instance", - }, - { text: "Template Syntax", link: "/guide/template-syntax" }, - { - text: "Data Properties and Methods", - link: "/guide/data-methods", - }, - { - text: "Computed Properties and Watchers", - link: "/guide/computed", - }, - { - text: "Class and Style Bindings", - link: "/guide/class-and-style", - }, - { text: "Conditional Rendering", link: "/guide/conditional" }, - { text: "List Rendering", link: "/guide/list" }, - { text: "Event Handling", link: "/guide/events" }, - { text: "Form Input Bindings", link: "/guide/forms" }, - { text: "Components Basics", link: "/guide/component-basics" }, - ], - }, - { - text: "Components In-Depth", - items: [ - { - text: "Component Registration", - link: "/guide/component-registration", - }, - { text: "Props", link: "/guide/component-props" }, - { text: "Non-Prop Attributes", link: "/guide/component-attrs" }, - { text: "Custom Events", link: "/guide/component-custom-events" }, - { text: "Slots", link: "/guide/component-slots" }, - { - text: "Provide / inject", - link: "/guide/component-provide-inject", - }, - { - text: "Dynamic & Async Components", - link: "/guide/component-dynamic-async", - }, - { text: "Template refs", link: "/guide/component-template-refs" }, - { - text: "Handling Edge Cases", - link: "/guide/component-edge-cases", - }, - ], - }, - { - text: "Transitions & Animation", - items: [ - { text: "Overview", link: "/guide/transitions-overview" }, - { - text: "Enter & Leave Transitions", - link: "/guide/transitions-enterleave", - }, - { text: "List Transitions", link: "/guide/transitions-list" }, - { text: "State Transitions", link: "/guide/transitions-state" }, - ], - }, - { - text: "Reusability", - items: [ - { text: "Mixins", link: "/guide/mixins" }, - { text: "Custom Directives", link: "/guide/custom-directive" }, - ], - }, - { - text: "Composition API", - items: [ - { - text: "Introduction", - link: "/guide/composition-api-introduction", - }, - { text: "Setup", link: "/guide/composition-api-setup" }, - { - text: "Lifecycle Hooks", - link: "/guide/composition-api-lifecycle-hooks", - }, - { - text: "Provide / Inject", - link: "/guide/composition-api-provide-inject", - }, - { - text: "Template Refs", - link: "/guide/composition-api-template-refs", - }, - ], - }, - { - text: "Advanced", - items: [ - { text: "Teleport", link: "/guide/teleport" }, - { text: "Render Function", link: "/guide/render-function" }, - { text: "Plugins", link: "/guide/plugins" }, - ], - }, - { - text: "Digging Deeper", - items: [ - { text: "Reactivity in Depth", link: "/guide/reactivity" }, - { - text: "Reactivity Fundamentals", - link: "/guide/reactivity-fundamentals", - }, - { - text: "Reactivity in Computed and Watch", - link: "/guide/reactivity-computed-watchers", - }, - { - text: "Rendering Mechanisms and Optimizations", - link: "/guide/optimizations", - }, - ], - }, - { - text: "Tooling", - items: [ - { - text: "Single File Components", - link: "/guide/single-file-component", - }, - { text: "Testing", link: "/guide/testing" }, - { text: "TypeScript Support", link: "/guide/typescript-support" }, - { text: "Mobile", link: "/guide/mobile" }, - { - text: "Production Deployment", - link: "/guide/tooling/deployment", - }, - ], - }, - { - text: "Scaling Up", - items: [ - { text: "Routing", link: "/guide/routing" }, - { text: "State Management", link: "/guide/state-management" }, - { text: "Server-Side Rendering", link: "/guide/ssr" }, - ], - }, - { - text: "Accessibility", - items: [ - { text: "Basics", link: "/guide/a11y-basics" }, - { text: "Semantics", link: "/guide/a11y-semantics" }, - { text: "Standards", link: "/guide/a11y-standards" }, - { text: "Resources", link: "/guide/a11y-resources" }, - ], - }, - ], - "/api/": [ - { - text: "Global API", - items: [ - { text: "Application", link: "/api/application" }, - { text: "Utilities", link: "/api/utilities" }, - ], - }, - { - text: "Component", - items: [ - { text: "Options: State", link: "/api/options-state" }, - { text: "Options: Rendering", link: "/api/options-rendering" }, - { - text: "Options: Lifecycle Hooks", - link: "/api/options-lifecycle", - }, - { - text: "Options: Composition", - link: "/api/options-composition", - }, - { text: "Options: Misc", link: "/api/options-misc" }, - { - text: "Instance", - link: "/api/component-instance", - }, - ], - }, - { - text: "Composition API", - items: [ - { text: "setup()", link: "/api/composition-setup" }, - { text: "Reactivity", link: "/api/composition-reactivity" }, - { text: "Lifecycle", link: "/api/composition-lifecycle" }, - ], - }, - { - text: "Built-ins", - items: [ - { text: "Directives", link: "/api/built-in-directives" }, - { text: "Components", link: "/api/built-in-components" }, - { text: "Special Attributes", link: "/api/special-attributes" }, - ], - }, - { - text: "Single File Component", - items: [ - { text: "Specification", link: "/api/sfc-spec" }, - { text: " -``` - -插件启用功能的配置选项,同时需要引入相关的`js`,`css` 文件。 - -| 参数 | 说明 | 类型 | -| ------------- | ---------------------------- | ----------------- | -|mode| 支持语言语法高亮 MIME-TYPE | string| -|lineNumbers|是否在编辑器左侧显示行号。|boolean| -|lineWrapping| 在长行时文字是换行(wrap)还是滚动(scroll),默认为滚动(scroll)。| boolean| -|styleActiveLine| 高亮选中行|boolean| -|tabSize| tab 字符的宽度|number -|theme|设置主题 |tring| -|autoCloseBrackets| 括号自动关闭|boolean| -|autoCloseTags| 标签自动关闭|boolean| -|matchTags| 标签匹配|boolean| -|matchBrackets| 括号匹配|boolean| -|foldGutter| 代码折叠|boolean| -|readOnly | 是否只读。 “nocursor” 设置只读外,编辑区域还不能获得焦点。|`boolean`\|`string`| - -组件初始化时,会自动初始化编辑器示例,同时将源码赋值给编辑器,并注册监听`change`事件。当编辑器的值发生改变时,会触发 `onchange` 事件,调用组件prop 属性 `codeHandler`将最新值传给父组件。 - -```js -// 初始化编辑器实例,传入需要被实例化的文本域对象和默认配置 -this.codeEditor = CodeMirror.fromTextArea( this.$refs.codeContainer, this.defaultOptions ); -this.codeEditor.setValue(this.value); -// 注册监听`change`事件 -this.codeEditor.on("change", (item) => { this.codeHandler(item.getValue()); }); -``` - -## SFC Parser - -组件的功能场景是用于简单示例代码运行展示,将源码视为 单文件组件(SFC,single-file component)的简单实例。 - -文件`src\utils\sfcParser\parser.js` 移植 vue 源码 [sfc/parser.js](https://github.com/vuejs/vue/blob/dev/src/sfc/parser.js#L14) 的 `parseComponent` 方法,用于实现源码解析生成组件 `SFCDescriptor`。 - -> 暂不支持组件和样式的动态引入,此处功能代码已经移除。 - -```js -// SFCDescriptor 接口声明 -export interface SFCDescriptor { - template: SFCBlock | undefined; // - script: SFCBlock | undefined; - styles: SFCBlock[]; - customBlocks: SFCBlock[]; -} - -export interface SFCBlock { - type: string; - content: string; - attrs: Record; - start?: number; - end?: number; - lang?: string; - src?: string; - scoped?: boolean; - module?: string | boolean; -} -``` - -`SFCDescriptor` 包含 `template`、`script`、`styles`、`customBlocks` 四个部分,将用于示例组件的动态构建。 其中 `styles`是数组,可以包含多个代码块并解析; `template`和`script` 若存在多个代码块只能解析最后一个。 -`customBlocks`是没在`template`的HTML代码,处理逻辑暂未包含此内容。 - -## 组件动态样式 - -文件`src\utils\style-loader\addStylesClient.js` 移植 `vue-style-loader` 源码 [addStylesClient](https://github.com/vuejs/vue-style-loader/blob/master/lib/addStylesClient.js) 方法,用于在页面DOM中动态创建组件样式。 - -![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b1c7fda5256549929e49f5be63326ffd~tplv-k3u1fbpfcp-watermark.image?) - -根据 `SFCDescriptor` 中的 `styles`和组件编号,在DOM中添加对应样式内容,若新增删除 ` -``` - -::: - -### 🎬 ` - -``` - -::: - -### 🎬 组件库混合使用 - -:::tip -项目引入其他组件库后,组件的示例源代码中直接使用即可,实现预览调试功能。 -::: - -::: demo - -```html - - - -``` - -::: - -### 🎬 组件嵌套引用 - -::: demo `MD`文档中组件嵌套示例,示例代码中引用组件. - -```html - - -``` - -::: - -### 🎬 `JSX`使用方式 - -:::tip -组件暂不支持 `JSX` 语法。 -::: - -```html - -``` - -### 🎬 errorHandler 自定义错误处理函数 - -```jsx -render() { - return ( -
- { - this.$notify.error({ - title: "Info", - message: errorMsg, - }); - }} - > -
- ) -} -``` diff --git a/examples/docs/guides/project-intro.md b/examples/docs/guides/project-intro.md deleted file mode 100644 index 4529e6a..0000000 --- a/examples/docs/guides/project-intro.md +++ /dev/null @@ -1,282 +0,0 @@ -# 项目概述 - -本文将从结构、功能等方面讲解下项目 `vue-code-view` 的搭建过程,您可以了解以下内容: - -- 使用 `vue cli 4`从0搭建一个组件库及细致配置信息。 -- 项目的多环境构建配置。 -- 项目网站的发布部署、持续集成。 -- 项目NPM包发布。 -- 项目组件的自定义 `Markdown` 解析 `loader`。 - -## 项目构建 - -### npm scripts 配置 - -调整 `package.json` 里的 `scripts` 配置脚本,并添加 `--mode xxx` 来选择不同环境配置。 - -```js -"scripts": { - // 开发环境 启动项目示例网站 - "dev": "vue-cli-service serve ", - // 组件库构建 - "dist": "vue-cli-service build --mode production --target lib --name vue-code-viewer --dest lib src/index.js", - // 项目示例网站构建 - "deploy:build": "vue-cli-service build --mode deploy" -} -``` - -### 组件构建 - -组件库构建通过指定入口文件`src/index.js`、设定参数选项。 - -```js -用法:vue-cli-service build [options] [entry|pattern] - -参数选项: - --mode 指定环境模式 (默认值:production) - --dest 指定输出目录 (默认值:dist) - --target app | lib | wc | wc-async (默认值:app) - --name 库或 Web Components 模式下的名字 (默认值:package.json 中的 "name" 字段或入口文件名) -``` - -构建一个库会输出: - -- `lib/vue-code-viewer.common.js`:一个给打包器用的 CommonJS 包 。 -- `lib/vue-code-viewer.umd.js`:一个直接给浏览器或 AMD loader 使用的 UMD 包。 -- `lib/vue-code-viewer.umd.min.js`:压缩后的 UMD 构建版本。 -- `lib/vue-code-viewer.css`:提取出来的 CSS 文件。 - -### 组件NPM包发布 - -配置 `package.json` 文件中属性值用于npm 发布。 - -- name: 包名,该名字是唯一的。需要去[npm registry](https://link.juejin.cn?target=http%3A%2F%2Fregistry.npmjs.org%2F "http://registry.npmjs.org/")查看名字是否已被使用。 -- version: 包版本号,版本号规则参考《语义化版本 2.0.0》。每次发布至 npm 需要修改版本号,不能和历史版本号相同。 -- description: 包的描述,描述这个包的主要功能以及用途。 -- main: 入口文件,该字段需指向项目编译后的包文件。 -- unpkg: UMD模式入口包文件 -- keyword:关键字,数组、字符串。 -- author:包的作者。 -- private:是否私有,需要修改为 false 才能发布到 npm -- license: 开源协议。 -- repository:包的Git Repo信息,包括type和URL。 -- homepage:项目官网的url。 - -更新 `package.json` 文件内容: - -```js -{ - "name": "vue-code-view", - "version": "0.3.9", - "description": "A code editor component based on Vue.js 2 ", - "main": "lib/vue-code-viewer.common.js", - "unpkg": "lib/vue-code-viewer.umd.js", - "scripts": {}, - "dependencies": {}, - "peerDependencies": {}, - "devDependencies": {}, - "keywords": [ - "vue", - "components", - "codemirror", - "code editor" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/andurils/vue-code-view.git" - }, - "author": "andurils", - "license": "MIT", - "homepage": "https://andurils.github.io/vue-code-view" -} - -``` - -加`.npmignore` 文件,设置忽略发布文件。发布到 npm 中文件,只保留有的 lib 目录、package.json、README.md。 - -```bash -# 忽略目录 -examples/ -node_modules/ -public/ -build/ -src/ -dist/ -deploy/ -# 忽略指定文件 -.browserslistrc -.eslintignore -.prettierignore -.env -.env.* -*.js -``` - -接下来 `npmjs.com` 上注册账号登录后,执行 `npm publish`命令完成组件包发布操作。 - -发布成功后,进入组件的NPM首页  [npm/vue-code-view](https://www.npmjs.com/package/vue-code-view), 可以看到上面的项目配置信息 。 - -![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c96d56ee6144485f93913b688f664e68~tplv-k3u1fbpfcp-watermark.image?) - -### 项目示例网站构建 - -更新 `vue.config.js`,运行 `npm run deploy:build` 构建项目示例网站输出至 `deploy` 目录下。 - -```js -const path = require("path"); -const resolve = (dir) => path.join(__dirname, dir); -const IS_PROD = ["production", "prod"].includes(process.env.NODE_ENV); - -module.exports = { - publicPath: process.env.VUE_APP_PUBLIC_PATH || "/", - productionSourceMap: false, - outputDir: process.env.VUE_APP_ENV === "deploy" ? "deploy" : "dist", - configureWebpack: (config) => { - // 项目入口 - config.entry.app = "./examples/main.js" - }, - ... -}; - -``` - -### 持续集成 - -使用 `Travis CI`的持续集成服务自动构建项目示例网站并部署至 `gh-pages` 分支 。 - -根目录下添加 `.travis.yml`文件,指定了 Travis 的行为。通过设置一旦代码仓库有新的 Commit,Travis 就会去找这个文件,执行里面的命令(执行构建、部署等操作)。 -y - -```bash -sudo: false -language: node_js -node_js: 14 -install: - - yarn - -script: npm run deploy:build -after_script: - - mkdir temp_web - - cd temp_web - - git clone --depth 1 -b gh-pages --single-branch https://${TravisCI_Token}@${GH_REF} && cd vue-code-view - - echo 'copy && commit' - - rm -rf js fonts - - cp -rf ../../deploy/** . - - git config user.name "${U_NAME}" - - git config user.email "${U_EMAIL}" - - git add -A . - - git commit -m ":construction_worker:- Build & Deploy by Travis CI" - - git push origin gh-pages - - echo "DONE, Bye~" - - exit 0 -``` - -`Travis CI`项目构建后台: - -![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dbfeedcb19854b06acb0af1ec87e415e~tplv-k3u1fbpfcp-watermark.image?) - -### 开启构建压缩 - -安装相关插件。 - -```bash -# gzip webpack 4.x 对应 6.x版本 -npm i compression-webpack-plugin@6.1.1 -D - -# 代码压缩 -npm i uglifyjs-webpack-plugin -D -``` - -配置 `vue.config.js`,开启插件。 - -```js -... -const IS_PROD = ["production", "prod"].includes(process.env.NODE_ENV); -// gzip压缩 webpack 4.x 对应 6.x版本 cnpm i compression-webpack-plugin@6.1.1 --save-dev -const CompressionWebpackPlugin = require("compression-webpack-plugin"); -const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i; -// 代码压缩 -const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); - -module.exports = { - ... - configureWebpack: (config) => { - const plugins = []; - // 生产环境相关配置 - if (IS_PROD && process.env.VUE_APP_ENV === "pub") { - plugins.push( - new CompressionWebpackPlugin({ - filename: "[path][base].gz", - algorithm: "gzip", - minRatio: 0.99, - test: productionGzipExtensions, - deleteOriginalAssets: false, - }) - ); - plugins.push( - new UglifyJsPlugin({ - uglifyOptions: { - // 删除注释 - output: { - comments: false, - }, - // 删除console debugger - compress: { - drop_debugger: true, - drop_console: true, // console - pure_funcs: ["console.log"], // 移除console - }, - // 删除警告 - warnings: false, - }, - sourceMap: false, - parallel: true, //使用多进程并行运行来提高构建速度。默认并发运行数:os.cpus().length - 1。 - }) - ); - } - config.plugins = [...config.plugins, ...plugins]; - }, -}; - -``` - -### 组件说明文档 - -参考`element 2`的实现,自定义 `build/md-loder`对 `Markdown` 文件进行解析渲染,将 `examples\docs\zh-CN\example.md` 编译为 HTML。已在前文 [04.封装组件封装、编写说明文档](https://juejin.cn/post/6953614014546968589#heading-5) 中详细说明,不再过多赘述。 - -配置 `vue.config.js` ,添加 `.md` 文档的自定义 `Markdown Loader`。 - -```js -module.exports = { - ... - configureWebpack: (config) => { - config.resolveLoader.modules = ["node_modules", "./build/"]; // 自定义loader - }, - chainWebpack: (config) => { - // Markdown Loader - config.module - .rule("md") - .test(/\.md/) - .use("vue-loader") - .loader("vue-loader") - .end() - // 自定义loader - .use("md-loader") - .loader("md-loader") - .end(); - }, -}; -``` - -`examples\router\index.js`配置路由: - -```js -const routes = [ - { - path: "/md", - name: "Markdown", - component: (r) => - require.ensure([], () => r(require("../docs/zh-CN/example.md"))), - }, -]; -``` diff --git a/examples/docs/tutorials/todo.md b/examples/docs/tutorials/todo.md deleted file mode 100644 index 6843464..0000000 --- a/examples/docs/tutorials/todo.md +++ /dev/null @@ -1,3 +0,0 @@ -# tutorial - -内容建设中... diff --git a/examples/layouts/content/VPAnnouncer.vue b/examples/layouts/content/VPAnnouncer.vue deleted file mode 100644 index 153c095..0000000 --- a/examples/layouts/content/VPAnnouncer.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/examples/layouts/content/VPCarbonAds.vue b/examples/layouts/content/VPCarbonAds.vue deleted file mode 100644 index 7836e5a..0000000 --- a/examples/layouts/content/VPCarbonAds.vue +++ /dev/null @@ -1,80 +0,0 @@ - - - - - diff --git a/examples/layouts/content/VPContent.vue b/examples/layouts/content/VPContent.vue deleted file mode 100644 index 49d2d2c..0000000 --- a/examples/layouts/content/VPContent.vue +++ /dev/null @@ -1,112 +0,0 @@ - - - - - diff --git a/examples/layouts/content/VPContentDoc.vue b/examples/layouts/content/VPContentDoc.vue deleted file mode 100644 index 062e3ec..0000000 --- a/examples/layouts/content/VPContentDoc.vue +++ /dev/null @@ -1,171 +0,0 @@ - - - - - diff --git a/examples/layouts/content/VPContentDocFooter.vue b/examples/layouts/content/VPContentDocFooter.vue deleted file mode 100644 index cc5b99b..0000000 --- a/examples/layouts/content/VPContentDocFooter.vue +++ /dev/null @@ -1,119 +0,0 @@ - - - - - diff --git a/examples/layouts/content/VPContentDocOutline.vue b/examples/layouts/content/VPContentDocOutline.vue deleted file mode 100644 index 7bf3385..0000000 --- a/examples/layouts/content/VPContentDocOutline.vue +++ /dev/null @@ -1,137 +0,0 @@ - - - - - diff --git a/examples/layouts/content/VPContentPage.vue b/examples/layouts/content/VPContentPage.vue deleted file mode 100644 index fe158d4..0000000 --- a/examples/layouts/content/VPContentPage.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/examples/layouts/content/VPFooter.vue b/examples/layouts/content/VPFooter.vue deleted file mode 100644 index 15102cb..0000000 --- a/examples/layouts/content/VPFooter.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNav.vue b/examples/layouts/header/VPNav.vue deleted file mode 100644 index d392c91..0000000 --- a/examples/layouts/header/VPNav.vue +++ /dev/null @@ -1,56 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavBar.vue b/examples/layouts/header/VPNavBar.vue deleted file mode 100644 index ad90d28..0000000 --- a/examples/layouts/header/VPNavBar.vue +++ /dev/null @@ -1,107 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavBarAppearance.vue b/examples/layouts/header/VPNavBarAppearance.vue deleted file mode 100644 index a2ff135..0000000 --- a/examples/layouts/header/VPNavBarAppearance.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavBarExtra.vue b/examples/layouts/header/VPNavBarExtra.vue deleted file mode 100644 index 781ffee..0000000 --- a/examples/layouts/header/VPNavBarExtra.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavBarHamburger.vue b/examples/layouts/header/VPNavBarHamburger.vue deleted file mode 100644 index 2b47a3c..0000000 --- a/examples/layouts/header/VPNavBarHamburger.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavBarMenu.vue b/examples/layouts/header/VPNavBarMenu.vue deleted file mode 100644 index c5367ac..0000000 --- a/examples/layouts/header/VPNavBarMenu.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavBarMenuGroup.vue b/examples/layouts/header/VPNavBarMenuGroup.vue deleted file mode 100644 index b08758b..0000000 --- a/examples/layouts/header/VPNavBarMenuGroup.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavBarMenuLink.vue b/examples/layouts/header/VPNavBarMenuLink.vue deleted file mode 100644 index 43f7747..0000000 --- a/examples/layouts/header/VPNavBarMenuLink.vue +++ /dev/null @@ -1,63 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavBarSocialLinks.vue b/examples/layouts/header/VPNavBarSocialLinks.vue deleted file mode 100644 index 1eb7967..0000000 --- a/examples/layouts/header/VPNavBarSocialLinks.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavBarTitle.vue b/examples/layouts/header/VPNavBarTitle.vue deleted file mode 100644 index 21f10de..0000000 --- a/examples/layouts/header/VPNavBarTitle.vue +++ /dev/null @@ -1,123 +0,0 @@ - - - diff --git a/examples/layouts/header/VPNavScreen.vue b/examples/layouts/header/VPNavScreen.vue deleted file mode 100644 index 949e31d..0000000 --- a/examples/layouts/header/VPNavScreen.vue +++ /dev/null @@ -1,114 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavScreenAppearance.vue b/examples/layouts/header/VPNavScreenAppearance.vue deleted file mode 100644 index 39cec61..0000000 --- a/examples/layouts/header/VPNavScreenAppearance.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavScreenMenu.vue b/examples/layouts/header/VPNavScreenMenu.vue deleted file mode 100644 index c3b2117..0000000 --- a/examples/layouts/header/VPNavScreenMenu.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - diff --git a/examples/layouts/header/VPNavScreenMenuGroup.vue b/examples/layouts/header/VPNavScreenMenuGroup.vue deleted file mode 100644 index 831eb6b..0000000 --- a/examples/layouts/header/VPNavScreenMenuGroup.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavScreenMenuGroupLink.vue b/examples/layouts/header/VPNavScreenMenuGroupLink.vue deleted file mode 100644 index 49189ef..0000000 --- a/examples/layouts/header/VPNavScreenMenuGroupLink.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavScreenMenuGroupSection.vue b/examples/layouts/header/VPNavScreenMenuGroupSection.vue deleted file mode 100644 index c82d252..0000000 --- a/examples/layouts/header/VPNavScreenMenuGroupSection.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavScreenMenuLink.vue b/examples/layouts/header/VPNavScreenMenuLink.vue deleted file mode 100644 index 2227ebf..0000000 --- a/examples/layouts/header/VPNavScreenMenuLink.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - - - diff --git a/examples/layouts/header/VPNavScreenSocialLinks.vue b/examples/layouts/header/VPNavScreenSocialLinks.vue deleted file mode 100644 index 0991d8a..0000000 --- a/examples/layouts/header/VPNavScreenSocialLinks.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/examples/layouts/sidebar/VPLocalNav.vue b/examples/layouts/sidebar/VPLocalNav.vue deleted file mode 100644 index b928234..0000000 --- a/examples/layouts/sidebar/VPLocalNav.vue +++ /dev/null @@ -1,121 +0,0 @@ - - - - - diff --git a/examples/layouts/sidebar/VPSidebar.vue b/examples/layouts/sidebar/VPSidebar.vue deleted file mode 100644 index 58b6f45..0000000 --- a/examples/layouts/sidebar/VPSidebar.vue +++ /dev/null @@ -1,147 +0,0 @@ - - - - - diff --git a/examples/layouts/sidebar/VPSidebarGroup.vue b/examples/layouts/sidebar/VPSidebarGroup.vue deleted file mode 100644 index 702e3fb..0000000 --- a/examples/layouts/sidebar/VPSidebarGroup.vue +++ /dev/null @@ -1,75 +0,0 @@ - - - - - diff --git a/examples/layouts/sidebar/VPSidebarLink.vue b/examples/layouts/sidebar/VPSidebarLink.vue deleted file mode 100644 index 90d0428..0000000 --- a/examples/layouts/sidebar/VPSidebarLink.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/examples/main.ts b/examples/main.ts deleted file mode 100644 index f68080c..0000000 --- a/examples/main.ts +++ /dev/null @@ -1,36 +0,0 @@ -import Vue from "vue"; -import App from "@examples/App.vue"; -import { PiniaVuePlugin } from "pinia"; -import VueRouter from "vue-router"; -import routes from "@examples/router"; -import { store } from "@examples/store"; - -import CodeViewer from "@/index"; // 组件引入 -import DemoBlock from "@examples/components/DemoBlock.vue"; // 网站页面 模板页面组件 -import OutboundLink from "@examples/components/icons/VCVIconOutboundLink.vue"; // Markdown link - -// 样式 -import "normalize.css"; -import "@examples/styles/index.css"; -import "prismjs/themes/prism-tomorrow.css"; // 代码语法高亮 - -Vue.config.productionTip = false; -Vue.use(VueRouter); -Vue.use(PiniaVuePlugin); -Vue.use(CodeViewer); -// 全局组件注册 -Vue.component("demo-block", DemoBlock); -Vue.component("OutboundLink", OutboundLink); - -const router = new VueRouter({ - mode: "hash", // 'hash' | 'history' - base: process.env.BASE_URL, - // base: __dirname, - routes, -}); - -new Vue({ - router, - pinia: store, - render: (h) => h(App), -}).$mount("#app"); diff --git a/examples/play.ts b/examples/play.ts deleted file mode 100644 index 7f44c63..0000000 --- a/examples/play.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Vue from "vue"; -import App from "@examples/views/play/index.vue"; -import CodeViewer from "@/index"; - -Vue.config.productionTip = false; -Vue.use(CodeViewer); - -new Vue({ - render: (h) => h(App), -}).$mount("#app"); diff --git a/examples/router/constant.ts b/examples/router/constant.ts deleted file mode 100644 index 75f121c..0000000 --- a/examples/router/constant.ts +++ /dev/null @@ -1,25 +0,0 @@ -export const REDIRECT_NAME = "Redirect"; - -export const PARENT_LAYOUT_NAME = "ParentLayout"; - -export const PAGE_NOT_FOUND_NAME = "PageNotFound"; - -export const EXCEPTION_COMPONENT = () => - import("@examples/views/sys/exception/Exception.vue"); - -/** - * @description: default layout - */ -// export const LAYOUT = () => import("/@/layouts/default/index.vue"); - -/** - * @description: parent-layout - */ -// export const getParentLayout = (_name?: string) => { -// return () => -// new Promise((resolve) => { -// resolve({ -// name: PARENT_LAYOUT_NAME, -// }); -// }); -// }; diff --git a/examples/router/index.ts b/examples/router/index.ts deleted file mode 100644 index ef5a52f..0000000 --- a/examples/router/index.ts +++ /dev/null @@ -1,103 +0,0 @@ -import type { RouteConfig } from "vue-router"; - -import tutorial from "@examples/router/routes/tutorial"; -import guide from "@examples/router/routes/guide"; -import Demo from "../views/repl/REPL.vue"; - -const RootRoute: RouteConfig = { - path: "/", - name: "Root", - redirect: "/home", - meta: { - title: "Root", - }, -}; -const HomeRoute: RouteConfig = { - path: "/home", - name: "Home", - component: () => import("../views/home/Home.vue"), - meta: { - hasFooter: true, - }, -}; -const ReplRoute: RouteConfig = { - path: "/repl", - name: "REPL", - meta: { - hasFooter: false, // 隐藏 footer - hasSidebar: false, // 没有 Siderbar - }, - component: Demo, -}; - -const ChangelogRoute: RouteConfig = { - path: "/changelog", - name: "Changelog", - component: (r) => - require.ensure([], () => r(require("../../CHANGELOG.zh-CN.md"))), -}; - -const route: Array = [ - RootRoute, - HomeRoute, - ReplRoute, - ChangelogRoute, - guide, - tutorial, - { - path: "/guide/introduction", - name: "Introduction", - meta: { - hasSidebar: true, // 是否有侧边栏 - }, - // component: () => import("@examples/views/home/Home.vue"), - component: (r) => - require.ensure([], () => r(require("@examples/docs/guides/overview.md"))), - }, - { - path: "/guide/project-intro", - name: "ProjectIntro", - meta: { - hasSidebar: true, // 是否有侧边栏 - title: "项目工程化简介", - }, - component: (r) => - require.ensure([], () => - r(require("@examples/docs/guides/project-intro.md")) - ), - }, - { - path: "/guide/code-logic-intro", - name: "CodeLogicIntro", - meta: { - hasSidebar: true, // 是否有侧边栏 - title: "代码逻辑简介", - }, - component: (r) => - require.ensure([], () => - r(require("@examples/docs/guides/code-logic-intro.md")) - ), - }, -]; - -// // const sideRoutes: Array = registerRoute(sideNavConfig); -// // route = route.concat(sideRoutes); - -// export const RootRoute: RouteConfig = { -// path: "/", -// name: "Root", -// redirect: "/home", -// meta: { -// title: "Root", -// }, -// }; - -// // Basic routing -// export const basicRoutes = [ -// RootRoute, -// // ...mainOutRoutes, -// // REDIRECT_ROUTE, -// // PAGE_NOT_FOUND_ROUTE, -// ]; - -export default route; diff --git a/examples/router/routes/guide.ts b/examples/router/routes/guide.ts deleted file mode 100644 index 135cf77..0000000 --- a/examples/router/routes/guide.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type { RouteConfig } from "vue-router"; - -const guide: RouteConfig = { - path: `/guide`, - name: "Guide", - redirect: `/guide/introduction`, - // component: (r) => - // require.ensure([], () => r(require("@examples/docs/guides/overview.md"))), - meta: { - hasSidebar: true, // 是否有侧边栏 - }, - children: [ - // { - // path: "introduction1", - // name: "Introduction1", - // meta: { - // hasSidebar: true, // 是否有侧边栏 - // }, - // // component: () => import("@examples/views/home/Home.vue"), - // component: (r) => - // require.ensure([], () => - // r(require("@examples/docs/guides/overview.md")) - // ), - // }, - // { - // path: "project-intro", - // name: "ProjectIntro", - // meta: { - // hasSidebar: true, // 是否有侧边栏 - // title: "项目工程化简介", - // }, - // component: (r) => - // require.ensure([], () => - // r(require("@examples/docs/guides/project-intro.md")) - // ), - // }, - // { - // path: "code-logic-intro", - // name: "CodeLogicIntro", - // meta: { - // hasSidebar: true, // 是否有侧边栏 - // title: "代码逻辑简介", - // }, - // component: (r) => - // require.ensure([], () => - // r(require("@examples/docs/guides/code-logic-intro.md")) - // ), - // }, - ], -}; - -export default guide; diff --git a/examples/router/routes/index.ts b/examples/router/routes/index.ts deleted file mode 100644 index d2552de..0000000 --- a/examples/router/routes/index.ts +++ /dev/null @@ -1,59 +0,0 @@ -// import type { AppRouteRecordRaw, AppRouteModule } from "/@/router/types"; - -import type { RouteConfig } from "vue-router"; -import { - REDIRECT_NAME, - // LAYOUT, - EXCEPTION_COMPONENT, - PAGE_NOT_FOUND_NAME, -} from "@examples/router/constant"; - -// import { -// PAGE_NOT_FOUND_ROUTE, -// // REDIRECT_ROUTE, -// } from "@examples/router/routes/basic"; - -// import { mainOutRoutes } from "./mainOut"; -// import { PageEnum } from "/@/enums/pageEnum"; -// import { t } from "/@/hooks/web/useI18n"; - -// const modules = import.meta.globEager("./modules/**/*.ts"); - -// const routeModuleList: AppRouteModule[] = []; - -// Object.keys(modules).forEach((key) => { -// const mod = modules[key].default || {}; -// const modList = Array.isArray(mod) ? [...mod] : [mod]; -// routeModuleList.push(...modList); -// }); - -// export const asyncRoutes = [PAGE_NOT_FOUND_ROUTE, ...routeModuleList]; - -// 404 on a page -const PAGE_NOT_FOUND_ROUTE: RouteConfig = { - path: "/:path(.*)*", - name: PAGE_NOT_FOUND_NAME, - component: EXCEPTION_COMPONENT, - meta: { - title: "ErrorPage", - hideBreadcrumb: true, - hideMenu: true, - }, -}; - -export const RootRoute: RouteConfig = { - path: "/", - name: "Root", - redirect: "/home", - meta: { - title: "Root", - }, -}; - -// Basic routing without permission -export const basicRoutes = [ - RootRoute, - // ...mainOutRoutes, - // REDIRECT_ROUTE, - PAGE_NOT_FOUND_ROUTE, -]; diff --git a/examples/router/routes/tutorial.ts b/examples/router/routes/tutorial.ts deleted file mode 100644 index 58cb050..0000000 --- a/examples/router/routes/tutorial.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { RouteConfig } from "vue-router"; - -const tutorial: RouteConfig = { - path: `/tutorial`, - name: "Tutorial", - component: (r) => - require.ensure([], () => r(require("@examples/docs/tutorials/todo.md"))), - meta: { - hasSidebar: false, // 属性不设置时,默认为 false - }, -}; - -export default tutorial; diff --git a/examples/settings/localeSetting.ts b/examples/settings/localeSetting.ts deleted file mode 100644 index d7eeb26..0000000 --- a/examples/settings/localeSetting.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { LocaleSetting, LocaleType } from "types/config"; - -export const LOCALE: { [key: string]: LocaleType } = { - ZH_CN: "zh_CN", - EN_US: "en", -}; - -export const localeSetting: LocaleSetting = { - // Whether to show the language picker 是否显示语言选择器 - showPicker: true, - // Locale 当前语言 - locale: LOCALE.EN_US, - // Default locale 默认语言 - fallback: LOCALE.ZH_CN, - // available Locales 可用语言 - availableLocales: [LOCALE.ZH_CN, LOCALE.EN_US], -}; diff --git a/examples/settings/projectSetting.ts b/examples/settings/projectSetting.ts deleted file mode 100644 index 0a3ab64..0000000 --- a/examples/settings/projectSetting.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { NavItem, SidebarConfig } from "@examples/types/config"; -import { SocialLink } from "@examples/types/socialLink"; - -export const nav: NavItem[] = [ - { - text: "REPL", - activeMatch: "^/repl/", - link: "/repl/", - }, - { - text: "文档", - activeMatch: `^/(guide|tutorial)/`, - items: [ - { - text: "指南", - link: "/guide/", - }, - { - text: "教程", - link: "/tutorial/", - }, - ], - }, - { - text: "关于", - activeMatch: "^/changelog/", - items: [ - { - items: [ - { - text: "changelog", - link: "/changelog/", - }, - { - text: "issues", - link: "https://github.com/andurils/vue-code-view/issues", - }, - ], - }, - { - items: [ - { - text: "npm", - link: "https://www.npmjs.com/package/vue-code-view", - }, - ], - }, - { - text: "参考", - items: [ - { - text: "Ant Design", - link: "https://ant.design/index-cn", - }, - { - text: "Ant Design Vue", - link: "https://www.antdv.com/components/overview", - }, - { - text: "Element UI", - link: "https://element.eleme.cn/#/zh-CN", - }, - ], - }, - ], - }, -]; - -export const sidebarConfig: SidebarConfig = { - "/guide/": [ - { - text: "简介", - items: [{ text: "项目简介", link: "/guide/introduction" }], - }, - { - text: "组件原理", - items: [ - { text: "项目概述", link: "/guide/project-intro" }, - { - text: "源码概述", - link: "/guide/code-logic-intro", - }, - ], - }, - // { - // text: "使用示例", - // items: [ - // { - // text: "TODO", - // link: "/guide/todo", - // }, - // ], - // }, - ], -}; - -export const socialLinks: SocialLink[] = [ - { - icon: "github", - link: "https://github.com/andurils/vue-code-view", - }, - // { - // icon: "languages", - // link: "https://staging-cn.vuejs.org/guide/typescript/options-api.html#typing-component-props", - // }, -]; - -export const appearance = true; diff --git a/examples/settings/siteSetting.js b/examples/settings/siteSetting.js deleted file mode 100644 index e341300..0000000 --- a/examples/settings/siteSetting.js +++ /dev/null @@ -1,8 +0,0 @@ -// github repo url -export const GITHUB_URL = "https://github.com/andurils/vue-code-view/"; - -// doc url -export const DOC_URL = "https://andurils.github.io/vue-code-view/doc/"; - -// site url -export const SITE_URL = "https://andurils.github.io/vue-code-view/"; diff --git a/examples/shims-vue.d.ts b/examples/shims-vue.d.ts deleted file mode 100644 index 4f74eb9..0000000 --- a/examples/shims-vue.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/// - -declare module "*.vue" { - import Vue from "vue"; - export default Vue; -} diff --git a/examples/shims.d.ts b/examples/shims.d.ts deleted file mode 100644 index 614f382..0000000 --- a/examples/shims.d.ts +++ /dev/null @@ -1,43 +0,0 @@ -declare module "markdown-it-attrs" { - const def: any; - export default def; -} - -declare module "markdown-it-emoji" { - const def: any; - export default def; -} - -declare module "markdown-it-table-of-contents" { - const def: any; - export default def; -} - -declare module "markdown-it-container" { - const def: any; - export default def; -} - -declare module "escape-html" { - const def: (str: string) => string; - export default def; -} - -declare module "prismjs" { - const def: any; - export default def; -} - -declare module "prismjs/components/index" { - const def: any; - export default def; -} - -declare module "diacritics" { - export const remove: (str: string) => string; -} - -declare module "*.json" { - const def: any; - export default def; -} diff --git a/examples/store/index.ts b/examples/store/index.ts deleted file mode 100644 index b8a79c0..0000000 --- a/examples/store/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { createPinia } from "pinia"; -import { createPersistedState } from "pinia-plugin-persistedstate"; - -const store = createPinia(); // 创建一个 pinia(根存储) -store.use(createPersistedState()); //开启缓存,存储在localstorage - -export { store }; diff --git a/examples/store/modules/locale.ts b/examples/store/modules/locale.ts deleted file mode 100644 index 3c2ee72..0000000 --- a/examples/store/modules/locale.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { defineStore } from "pinia"; -import { store } from "@examples/store"; -import type { LocaleSetting, LocaleType } from "types/config"; -import { localeSetting, LOCALE } from "@examples/settings/localeSetting"; - -// 获取配置信息 -const lsLocaleSetting = localeSetting as LocaleSetting; - -interface LocaleState { - localInfo: LocaleSetting; -} -export const useLocaleStore = defineStore("app-locale", { - state: (): LocaleState => ({ - localInfo: lsLocaleSetting, - }), - getters: { - getShowPicker(): boolean { - return !!this.localInfo?.showPicker; - }, - getLocale(): LocaleType { - return this.localInfo?.locale ?? LOCALE.ZH_CN; - }, - }, - actions: { - /** - * Set up multilingual information and cache - * 设置多语言信息并缓存 - * @param info multilingual info - */ - setLocaleInfo(info: Partial) { - this.localInfo = { ...this.localInfo, ...info }; - // ls.set(LOCALE_KEY, this.localInfo); - }, - /** - * Initialize multilingual information and load the existing configuration from the local cache - * 初始化多语言信息并从本地缓存加载现有配置 - */ - initLocale() { - this.setLocaleInfo({ - ...localeSetting, - ...this.localInfo, - }); - }, - }, - persist: true, -}); - -// Need to be used outside the setup -export function useLocaleStoreWithOut() { - return useLocaleStore(store); -} diff --git a/examples/store/modules/sidebar.ts b/examples/store/modules/sidebar.ts deleted file mode 100644 index 7c4038a..0000000 --- a/examples/store/modules/sidebar.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { defineStore } from "pinia"; -import { store } from "@examples/store"; -import { getSidebar } from "@examples/utils/sidebar"; -import type { Route, RouteMeta } from "vue-router"; -import { sidebarConfig } from "@examples/settings/projectSetting"; -import { SidebarGroup } from "@examples/types/config"; - -interface SidebarState { - curRoute: Nullable; - isOpen: boolean; -} - -export const useSidebarStore = defineStore("app-sidebar", { - state: (): SidebarState => ({ - curRoute: null, - isOpen: false, - }), - getters: { - // getCurrentRoute(): Nullable { - // return this.curRoute; - // }, - getCurrentRoutePath(): string { - return this.curRoute?.path || ""; - }, - getSidebarOpen(): boolean { - return this.isOpen; - }, - getSidebar(): SidebarGroup[] { - const relativePath = this.curRoute?.path || ""; - return sidebarConfig ? getSidebar(sidebarConfig, relativePath) : []; - }, - getHasSidebar(): boolean { - return this.getSidebar.length > 0; - }, - }, - actions: { - setCurrentRoute(pageRoute: Route) { - this.curRoute = pageRoute; - this.isOpen = this.getHasSidebar; - }, - setSidebarOpen() { - this.isOpen = true; - }, - setSidebarClose() { - this.isOpen = false; - }, - setSidebarToggle() { - this.isOpen ? this.setSidebarClose() : this.setSidebarOpen(); - }, - }, - persist: true, -}); - -// Need to be used outside the setup -export function useSidebarStoreWithOut() { - return useSidebarStore(store); -} diff --git a/examples/styles/base.css b/examples/styles/base.css deleted file mode 100644 index 8519b07..0000000 --- a/examples/styles/base.css +++ /dev/null @@ -1,207 +0,0 @@ -*, -::before, -::after { - box-sizing: border-box; -} - -body { - width: 100%; - min-width: 320px; - min-height: 100vh; - font-family: var(--vt-font-family-base); - letter-spacing: 0.2px; - line-height: 24px; - font-size: 16px; - font-weight: 400; - color: var(--vt-c-text-1); - background-color: var(--vt-c-bg); - direction: ltr; - font-synthesis: none; - text-rendering: optimizeLegibility; - transition: color 0.5s, background-color 0.5s; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -blockquote, -dl, -dd, -h1, -h2, -h3, -h4, -h5, -h6, -hr, -figure, -p, -pre { - margin: 0; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - font-size: inherit; - font-weight: inherit; -} - -/** - * Avoid 300ms click delay on touch devices that support the `touch-action` - * CSS property. - * - * In particular, unlike most other browsers, IE11+Edge on Windows 10 on - * touch devices and IE Mobile 10-11 DON'T remove the click delay when - * `` is present. - * However, they DO support removing the click delay via - * `touch-action: manipulation`. - * - * See: - * - http://v4-alpha.getbootstrap.com/content/reboot/#click-delay-optimization-for-touch - * - http://caniuse.com/#feat=css-touch-action - * - http://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay - */ -a, -area, -button, -[role="button"], -input, -label, -select, -summary, -textarea { - touch-action: manipulation; -} - -a { - color: inherit; - text-decoration: inherit; -} - -ol, -ul { - list-style: none; - margin: 0; - padding: 0; -} - -pre, -code, -kbd, -samp { - font-family: var(--vt-font-family-mono); -} - -img, -svg, -video, -canvas, -audio, -iframe, -embed, -object { - display: block; - vertical-align: middle; -} - -img, -video { - max-width: 100%; - height: auto; -} - -button, -input, -optgroup, -select, -textarea { - border: 0; - padding: 0; - line-height: inherit; - color: inherit; -} - -button { - padding: 0; - background-color: transparent; - background-image: none; -} - -button, -[role="button"] { - cursor: pointer; -} - -button:focus, -button:focus-visible { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; -} -button:focus:not(:focus-visible) { - outline: none !important; -} - -input:focus, -textarea:focus, -select:focus { - outline: none; -} - -table { - border-collapse: collapse; -} - -input { - background-color: transparent; -} - -input:-ms-input-placeholder, -textarea:-ms-input-placeholder { - color: var(--vt-c-text-3); -} - -input::-ms-input-placeholder, -textarea::-ms-input-placeholder { - color: var(--vt-c-text-3); -} - -input::placeholder, -textarea::placeholder { - color: var(--vt-c-text-3); -} - -input::-webkit-outer-spin-button, -input::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; -} - -input[type="number"] { - -moz-appearance: textfield; -} - -textarea { - resize: vertical; -} - -select { - -webkit-appearance: none; -} - -fieldset { - margin: 0; - padding: 0; -} - -.visually-hidden { - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px; -} diff --git a/examples/styles/index.css b/examples/styles/index.css deleted file mode 100644 index 6023c42..0000000 --- a/examples/styles/index.css +++ /dev/null @@ -1,25 +0,0 @@ -/* @import "normalize.css"; */ -@import "./variables.css"; -@import "./base.css"; -@import "./vt-backdrop.css"; -@import "./vt-code-group.css"; -@import "./vt-doc-base.css"; -@import "./vt-doc-code.css"; -@import "./vt-doc-custom-blocks.css"; -@import "./vt-flyout.css"; -@import "./vt-hamburger.css"; -@import "./vt-link.css"; -@import "./vt-menu.css"; -@import "./vt-menu-group.css"; -@import "./vt-menu-link.css"; -@import "./vt-social-link.css"; -@import "./vt-social-links.css"; -@import "./vt-switch.css"; -@import "./vt-switch-appearance.css"; -@import "./vt-box.css"; -@import "./vt-badge.css"; - -/* @import "./vcv-code.css"; */ -@import "./vcv-github-markdown.css"; - -@import "./vcv-markdown.css"; diff --git a/examples/styles/variables.css b/examples/styles/variables.css deleted file mode 100644 index cc08461..0000000 --- a/examples/styles/variables.css +++ /dev/null @@ -1,198 +0,0 @@ -/** - * Colors Base - * - * These are the pure base color presets. Most of the time, you should not be - * using these colors directly in the theme but rather use "Colors Theme" - * instead because those are "Theme (light or dark)" dependant. - * -------------------------------------------------------------------------- */ - -:root { - --vt-c-white: #ffffff; - --vt-c-white-soft: #f9f9f9; - --vt-c-white-mute: #f1f1f1; - - --vt-c-black: #1a1a1a; - --vt-c-black-pure: #000000; - --vt-c-black-soft: #242424; - --vt-c-black-mute: #2f2f2f; - - --vt-c-indigo: #213547; - --vt-c-indigo-soft: #476582; - --vt-c-indigo-light: #aac8e4; - - --vt-c-gray: #8e8e8e; - --vt-c-gray-light-1: #aeaeae; - --vt-c-gray-light-2: #c7c7c7; - --vt-c-gray-light-3: #d1d1d1; - --vt-c-gray-light-4: #e5e5e5; - --vt-c-gray-light-5: #f2f2f2; - --vt-c-gray-dark-1: #636363; - --vt-c-gray-dark-2: #484848; - --vt-c-gray-dark-3: #3a3a3a; - --vt-c-gray-dark-4: #282828; - --vt-c-gray-dark-5: #202020; - - --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); - --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); - --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); - --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); - - --vt-c-text-light-1: var(--vt-c-indigo); - --vt-c-text-light-2: rgba(60, 60, 60, 0.7); - --vt-c-text-light-3: rgba(60, 60, 60, 0.33); - --vt-c-text-light-4: rgba(60, 60, 60, 0.18); - --vt-c-text-light-code: var(--vt-c-indigo-soft); - - --vt-c-text-dark-1: rgba(255, 255, 255, 0.87); - --vt-c-text-dark-2: rgba(235, 235, 235, 0.6); - --vt-c-text-dark-3: rgba(235, 235, 235, 0.38); - --vt-c-text-dark-4: rgba(235, 235, 235, 0.18); - --vt-c-text-dark-code: var(--vt-c-indigo-light); - - --vt-c-green: #42b883; - --vt-c-green-light: #42d392; - --vt-c-green-lighter: #35eb9a; - --vt-c-green-dark: #33a06f; - --vt-c-green-darker: #155f3e; - - --vt-c-blue: #3b8eed; - --vt-c-blue-light: #549ced; - --vt-c-blue-lighter: #50a2ff; - --vt-c-blue-dark: #3468a3; - --vt-c-blue-darker: #255489; - - --vt-c-yellow: #ffc517; - --vt-c-yellow-light: #ffe417; - --vt-c-yellow-lighter: #ffff17; - --vt-c-yellow-dark: #e0ad15; - --vt-c-yellow-darker: #bc9112; - - --vt-c-red: #ed3c50; - --vt-c-red-light: #f43771; - --vt-c-red-lighter: #fd1d7c; - --vt-c-red-dark: #cd2d3f; - --vt-c-red-darker: #ab2131; - - --vt-c-purple: #de41e0; - --vt-c-purple-light: #e936eb; - --vt-c-purple-lighter: #f616f8; - --vt-c-purple-dark: #823c83; - --vt-c-purple-darker: #602960; -} - -/** - * Colors Theme - * -------------------------------------------------------------------------- */ - -:root { - --vt-c-bg: var(--vt-c-white); - --vt-c-bg-soft: var(--vt-c-white-soft); - --vt-c-bg-mute: var(--vt-c-white-mute); - - --vt-c-divider: var(--vt-c-divider-light-1); - --vt-c-divider-light: var(--vt-c-divider-light-2); - - --vt-c-divider-inverse: var(--vt-c-divider-dark-1); - --vt-c-divider-inverse-light: var(--vt-c-divider-dark-2); - - --vt-c-text-1: var(--vt-c-text-light-1); - --vt-c-text-2: var(--vt-c-text-light-2); - --vt-c-text-3: var(--vt-c-text-light-3); - --vt-c-text-4: var(--vt-c-text-light-4); - --vt-c-text-code: var(--vt-c-text-light-code); - - --vt-c-text-inverse-1: var(--vt-c-text-dark-1); - --vt-c-text-inverse-2: var(--vt-c-text-dark-2); - --vt-c-text-inverse-3: var(--vt-c-text-dark-3); - --vt-c-text-inverse-4: var(--vt-c-text-dark-4); - - --vt-c-brand: var(--vt-c-blue); - --vt-c-brand-light: var(--vt-c-blue-light); - --vt-c-brand-dark: var(--vt-c-blue-dark); - --vt-c-brand-highlight: var(--vt-c-brand-dark); -} - -.dark { - --vt-c-bg: var(--vt-c-black); - --vt-c-bg-soft: var(--vt-c-black-soft); - --vt-c-bg-mute: var(--vt-c-black-mute); - - --vt-c-divider: var(--vt-c-divider-dark-1); - --vt-c-divider-light: var(--vt-c-divider-dark-2); - - --vt-c-divider-inverse: var(--vt-c-divider-light-1); - --vt-c-divider-inverse-light: var(--vt-c-divider-light-2); - - --vt-c-text-1: var(--vt-c-text-dark-1); - --vt-c-text-2: var(--vt-c-text-dark-2); - --vt-c-text-3: var(--vt-c-text-dark-3); - --vt-c-text-4: var(--vt-c-text-dark-4); - --vt-c-text-code: var(--vt-c-text-dark-code); - - --vt-c-text-inverse-1: var(--vt-c-text-light-1); - --vt-c-text-inverse-2: var(--vt-c-text-light-2); - --vt-c-text-inverse-3: var(--vt-c-text-light-3); - --vt-c-text-inverse-4: var(--vt-c-text-light-4); - - --vt-c-brand-highlight: var(--vt-c-brand-light); -} - -/** - * Typography - * -------------------------------------------------------------------------- */ - -:root { - --vt-font-family-base: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", - Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", - "Helvetica Neue", sans-serif; - --vt-font-family-mono: Menlo, Monaco, Consolas, "Courier New", monospace; -} - -/** - * Shadows - * -------------------------------------------------------------------------- */ - -:root { - --vt-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06); - --vt-shadow-2: 0 3px 12px rgba(0, 0, 0, 0.07), 0 1px 4px rgba(0, 0, 0, 0.07); - --vt-shadow-3: 0 12px 32px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08); - --vt-shadow-4: 0 14px 44px rgba(0, 0, 0, 0.12), 0 3px 9px rgba(0, 0, 0, 0.12); - --vt-shadow-5: 0 18px 56px rgba(0, 0, 0, 0.16), 0 4px 12px rgba(0, 0, 0, 0.16); -} - -/** - * Magic Numbers - * -------------------------------------------------------------------------- */ - -:root { - --vt-nav-height: 55px; -} - -/** - * Layouts - * -------------------------------------------------------------------------- */ - -:root { - /* Z Indexes */ - --vp-z-index-local-nav: 10; - --vp-z-index-nav: 20; - --vp-z-index-banner: 30; - --vp-z-index-backdrop: 40; - --vp-z-index-sidebar: 50; - - /* Screen Size */ - --vp-screen-max-width: 1376px; -} - -/** - * Component: Sidebar - * -------------------------------------------------------------------------- */ - -:root { - --vp-sidebar-width-mobile: 320px; - --vp-sidebar-width-small: 272px; -} - -html.dark { - color-scheme: dark; -} diff --git a/examples/styles/vcv-code.css b/examples/styles/vcv-code.css deleted file mode 100644 index 8e8a03d..0000000 --- a/examples/styles/vcv-code.css +++ /dev/null @@ -1,112 +0,0 @@ -div[class*="language-"] { - position: relative; - background-color: #282c34; - border-radius: 6px; -} -div[class*="language-"] .highlight-lines { - user-select: none; - padding-top: 1.3rem; - position: absolute; - top: 0; - left: 0; - width: 100%; - line-height: 1.4; -} -div[class*="language-"] .highlight-lines .highlighted { - background-color: rgba(0, 0, 0, 0.66); -} -div[class*="language-"] pre, -div[class*="language-"] pre[class*="language-"] { - background: transparent; - position: relative; - z-index: 1; -} -div[class*="language-"]::before { - position: absolute; - z-index: 3; - top: 0.8em; - right: 1em; - font-size: 0.75rem; - color: rgba(255, 255, 255, 0.4); -} -div[class*="language-"]:not(.line-numbers-mode) .line-numbers-wrapper { - display: none; -} -div[class*="language-"].line-numbers-mode .highlight-lines .highlighted { - position: relative; -} -div[class*="language-"].line-numbers-mode .highlight-lines .highlighted:before { - content: " "; - position: absolute; - z-index: 3; - left: 0; - top: 0; - display: block; - width: 3.5rem; - height: 100%; - background-color: rgba(0, 0, 0, 0.66); -} -div[class*="language-"].line-numbers-mode pre { - padding-left: 3.5rem + 1rem; - vertical-align: middle; -} -div[class*="language-"].line-numbers-mode .line-numbers-wrapper { - position: absolute; - top: 0; - width: 3.5rem; - text-align: center; - color: rgba(255, 255, 255, 0.3); - padding: 1.25rem 0; - line-height: 1.4; -} -div[class*="language-"].line-numbers-mode .line-numbers-wrapper br { - user-select: none; -} -div[class*="language-"].line-numbers-mode .line-numbers-wrapper .line-number { - position: relative; - z-index: 4; - user-select: none; - font-size: 0.85em; -} -div[class*="language-"].line-numbers-mode::after { - content: ""; - position: absolute; - z-index: 2; - top: 0; - left: 0; - width: 3.5rem; - height: 100%; - border-radius: 6px 0 0 6px; - border-right: 1px solid rgba(0, 0, 0, 0.66); - background-color: #282c34; -} -div[class~="language-$codeLang"]:before { - content: "$codeLang"; -} -div[class~="language-javascript"]:before { - content: "js"; -} -div[class~="language-typescript"]:before { - content: "ts"; -} -div[class~="language-markup"]:before { - content: "html"; -} -div[class~="language-markdown"]:before { - content: "md"; -} -div[class~="language-json"]:before { - content: "json"; -} -div[class~="language-ruby"]:before { - content: "rb"; -} -div[class~="language-python"]:before { - content: "py"; -} -div[class~="language-bash"]:before { - content: "sh"; -} -div[class~="language-php"]:before { - content: "php"; -} diff --git a/examples/styles/vcv-github-markdown.css b/examples/styles/vcv-github-markdown.css deleted file mode 100644 index cc47bc4..0000000 --- a/examples/styles/vcv-github-markdown.css +++ /dev/null @@ -1,1037 +0,0 @@ -/* Modified from https://github.com/sindresorhus/github-markdown-css */ -:root { - --color-prettylights-syntax-comment: #6e7781; - --color-prettylights-syntax-constant: #0550ae; - --color-prettylights-syntax-entity: #8250df; - --color-prettylights-syntax-storage-modifier-import: #24292f; - --color-prettylights-syntax-entity-tag: #116329; - --color-prettylights-syntax-keyword: #cf222e; - --color-prettylights-syntax-string: #0a3069; - --color-prettylights-syntax-variable: #953800; - --color-prettylights-syntax-brackethighlighter-unmatched: #82071e; - --color-prettylights-syntax-invalid-illegal-text: #f6f8fa; - --color-prettylights-syntax-invalid-illegal-bg: #82071e; - --color-prettylights-syntax-carriage-return-text: #f6f8fa; - --color-prettylights-syntax-carriage-return-bg: #cf222e; - --color-prettylights-syntax-string-regexp: #116329; - --color-prettylights-syntax-markup-list: #3b2300; - --color-prettylights-syntax-markup-heading: #0550ae; - --color-prettylights-syntax-markup-italic: #24292f; - --color-prettylights-syntax-markup-bold: #24292f; - --color-prettylights-syntax-markup-deleted-text: #82071e; - --color-prettylights-syntax-markup-deleted-bg: #ffebe9; - --color-prettylights-syntax-markup-inserted-text: #116329; - --color-prettylights-syntax-markup-inserted-bg: #dafbe1; - --color-prettylights-syntax-markup-changed-text: #953800; - --color-prettylights-syntax-markup-changed-bg: #ffd8b5; - --color-prettylights-syntax-markup-ignored-text: #eaeef2; - --color-prettylights-syntax-markup-ignored-bg: #0550ae; - --color-prettylights-syntax-meta-diff-range: #8250df; - --color-prettylights-syntax-brackethighlighter-angle: #57606a; - --color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f; - --color-prettylights-syntax-constant-other-reference-link: #0a3069; - --color-fg-default: #24292f; - --color-fg-muted: #57606a; - --color-fg-subtle: #6e7781; - --color-canvas-default: #ffffff; - --color-canvas-subtle: #f6f8fa; - --color-border-default: #d0d7de; - --color-border-muted: hsla(210, 18%, 87%, 1); - --color-neutral-muted: rgba(175, 184, 193, 0.2); - --color-accent-fg: #0969da; - --color-accent-emphasis: #0969da; - --color-attention-subtle: #fff8c5; - --color-danger-fg: #cf222e; -} - -.dark { - --color-prettylights-syntax-comment: #8b949e; - --color-prettylights-syntax-constant: #79c0ff; - --color-prettylights-syntax-entity: #d2a8ff; - --color-prettylights-syntax-storage-modifier-import: #c9d1d9; - --color-prettylights-syntax-entity-tag: #7ee787; - --color-prettylights-syntax-keyword: #ff7b72; - --color-prettylights-syntax-string: #a5d6ff; - --color-prettylights-syntax-variable: #ffa657; - --color-prettylights-syntax-brackethighlighter-unmatched: #f85149; - --color-prettylights-syntax-invalid-illegal-text: #f0f6fc; - --color-prettylights-syntax-invalid-illegal-bg: #8e1519; - --color-prettylights-syntax-carriage-return-text: #f0f6fc; - --color-prettylights-syntax-carriage-return-bg: #b62324; - --color-prettylights-syntax-string-regexp: #7ee787; - --color-prettylights-syntax-markup-list: #f2cc60; - --color-prettylights-syntax-markup-heading: #1f6feb; - --color-prettylights-syntax-markup-italic: #c9d1d9; - --color-prettylights-syntax-markup-bold: #c9d1d9; - --color-prettylights-syntax-markup-deleted-text: #ffdcd7; - --color-prettylights-syntax-markup-deleted-bg: #67060c; - --color-prettylights-syntax-markup-inserted-text: #aff5b4; - --color-prettylights-syntax-markup-inserted-bg: #033a16; - --color-prettylights-syntax-markup-changed-text: #ffdfb6; - --color-prettylights-syntax-markup-changed-bg: #5a1e02; - --color-prettylights-syntax-markup-ignored-text: #c9d1d9; - --color-prettylights-syntax-markup-ignored-bg: #1158c7; - --color-prettylights-syntax-meta-diff-range: #d2a8ff; - --color-prettylights-syntax-brackethighlighter-angle: #8b949e; - --color-prettylights-syntax-sublimelinter-gutter-mark: #484f58; - --color-prettylights-syntax-constant-other-reference-link: #a5d6ff; - --color-fg-default: #c9d1d9; - --color-fg-muted: #8b949e; - --color-fg-subtle: #484f58; - /* --color-canvas-default: #0d1117; */ - --color-canvas-default: var(--vt-c-black); - - --color-canvas-subtle: #161b22; - --color-border-default: #30363d; - --color-border-muted: #21262d; - --color-neutral-muted: rgba(110, 118, 129, 0.4); - --color-accent-fg: #58a6ff; - --color-accent-emphasis: #1f6feb; - --color-attention-subtle: rgba(187, 128, 9, 0.15); - --color-danger-fg: #f85149; -} - -.markdown-body { - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; - margin: 0; - color: var(--color-fg-default); - background-color: var(--color-canvas-default); - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, - sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; - font-size: 16px; - line-height: 1.5; - word-wrap: break-word; -} - -.markdown-body .octicon { - display: inline-block; - fill: currentColor; - vertical-align: text-bottom; -} - -.markdown-body h1:hover .anchor .octicon-link:before, -.markdown-body h2:hover .anchor .octicon-link:before, -.markdown-body h3:hover .anchor .octicon-link:before, -.markdown-body h4:hover .anchor .octicon-link:before, -.markdown-body h5:hover .anchor .octicon-link:before, -.markdown-body h6:hover .anchor .octicon-link:before { - width: 16px; - height: 16px; - content: " "; - display: inline-block; - background-color: currentColor; - -webkit-mask-image: url("data:image/svg+xml,"); - mask-image: url("data:image/svg+xml,"); -} - -.markdown-body details, -.markdown-body figcaption, -.markdown-body figure { - display: block; -} - -.markdown-body summary { - display: list-item; -} - -.markdown-body [hidden] { - display: none !important; -} - -.markdown-body a { - background-color: transparent; - color: var(--color-accent-fg); - text-decoration: none; -} - -.markdown-body a:active, -.markdown-body a:hover { - outline-width: 0; -} - -.markdown-body abbr[title] { - border-bottom: none; - text-decoration: underline dotted; -} - -.markdown-body b, -.markdown-body strong { - font-weight: 600; -} - -.markdown-body dfn { - font-style: italic; -} - -.markdown-body h1 { - margin: 0.67em 0; - font-weight: 600; - padding-bottom: 0.3em; - font-size: 2em; - border-bottom: 1px solid var(--color-border-muted); -} - -.markdown-body mark { - background-color: var(--color-attention-subtle); - color: var(--color-text-primary); -} - -.markdown-body small { - font-size: 90%; -} - -.markdown-body sub, -.markdown-body sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -.markdown-body sub { - bottom: -0.25em; -} - -.markdown-body sup { - top: -0.5em; -} - -.markdown-body img { - border-style: none; - max-width: 100%; - box-sizing: content-box; - background-color: var(--color-canvas-default); -} - -.markdown-body code, -.markdown-body kbd, -.markdown-body pre, -.markdown-body samp { - font-family: monospace, monospace; - font-size: 1em; -} - -.markdown-body figure { - margin: 1em 40px; -} - -.markdown-body hr { - box-sizing: content-box; - overflow: hidden; - background: transparent; - border-bottom: 1px solid var(--color-border-muted); - height: 0.25em; - padding: 0; - margin: 24px 0; - background-color: var(--color-border-default); - border: 0; -} - -.markdown-body input { - font: inherit; - margin: 0; - overflow: visible; - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -.markdown-body [type="button"], -.markdown-body [type="reset"], -.markdown-body [type="submit"] { - -webkit-appearance: button; -} - -.markdown-body [type="button"]::-moz-focus-inner, -.markdown-body [type="reset"]::-moz-focus-inner, -.markdown-body [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; -} - -.markdown-body [type="button"]:-moz-focusring, -.markdown-body [type="reset"]:-moz-focusring, -.markdown-body [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - -.markdown-body [type="checkbox"], -.markdown-body [type="radio"] { - box-sizing: border-box; - padding: 0; -} - -.markdown-body [type="number"]::-webkit-inner-spin-button, -.markdown-body [type="number"]::-webkit-outer-spin-button { - height: auto; -} - -.markdown-body [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; -} - -.markdown-body [type="search"]::-webkit-search-cancel-button, -.markdown-body [type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -.markdown-body ::-webkit-input-placeholder { - color: inherit; - opacity: 0.54; -} - -.markdown-body ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; -} - -.markdown-body a:hover { - text-decoration: underline; -} - -.markdown-body hr::before { - display: table; - content: ""; -} - -.markdown-body hr::after { - display: table; - clear: both; - content: ""; -} - -.markdown-body table { - border-spacing: 0; - border-collapse: collapse; - display: block; - width: max-content; - max-width: 100%; - overflow: auto; -} - -.markdown-body td, -.markdown-body th { - padding: 0; -} - -.markdown-body details summary { - cursor: pointer; -} - -.markdown-body details:not([open]) > *:not(summary) { - display: none !important; -} - -.markdown-body kbd { - display: inline-block; - padding: 3px 5px; - font: 11px ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, - Liberation Mono, monospace; - line-height: 10px; - color: var(--color-fg-default); - vertical-align: middle; - background-color: var(--color-canvas-subtle); - border: solid 1px var(--color-neutral-muted); - border-bottom-color: var(--color-neutral-muted); - border-radius: 6px; - box-shadow: inset 0 -1px 0 var(--color-neutral-muted); -} - -.markdown-body h1, -.markdown-body h2, -.markdown-body h3, -.markdown-body h4, -.markdown-body h5, -.markdown-body h6 { - margin-top: 24px; - margin-bottom: 16px; - font-weight: 600; - line-height: 1.25; -} - -.markdown-body h2 { - font-weight: 600; - padding-bottom: 0.3em; - font-size: 1.5em; - border-bottom: 1px solid var(--color-border-muted); -} - -.markdown-body h3 { - font-weight: 600; - font-size: 1.25em; -} - -.markdown-body h4 { - font-weight: 600; - font-size: 1em; -} - -.markdown-body h5 { - font-weight: 600; - font-size: 0.875em; -} - -.markdown-body h6 { - font-weight: 600; - font-size: 0.85em; - color: var(--color-fg-muted); -} - -.markdown-body p { - margin-top: 0; - margin-bottom: 10px; -} - -.markdown-body blockquote { - margin: 0; - padding: 0 1em; - color: var(--color-fg-muted); - border-left: 0.25em solid var(--color-border-default); -} - -.markdown-body ul, -.markdown-body ol { - margin-top: 0; - margin-bottom: 0; - padding-left: 2em; -} - -.markdown-body ol ol, -.markdown-body ul ol { - list-style-type: lower-roman; -} - -.markdown-body ul ul ol, -.markdown-body ul ol ol, -.markdown-body ol ul ol, -.markdown-body ol ol ol { - list-style-type: lower-alpha; -} - -.markdown-body dd { - margin-left: 0; -} - -.markdown-body tt, -.markdown-body code { - font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, - Liberation Mono, monospace; - font-size: 12px; -} - -.markdown-body pre { - margin-top: 0; - margin-bottom: 0; - font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, - Liberation Mono, monospace; - font-size: 12px; - word-wrap: normal; -} - -.markdown-body .octicon { - display: inline-block; - overflow: visible !important; - vertical-align: text-bottom; - fill: currentColor; -} - -.markdown-body ::placeholder { - color: var(--color-fg-subtle); - opacity: 1; -} - -.markdown-body input::-webkit-outer-spin-button, -.markdown-body input::-webkit-inner-spin-button { - margin: 0; - -webkit-appearance: none; - appearance: none; -} - -.markdown-body .pl-c { - color: var(--color-prettylights-syntax-comment); -} - -.markdown-body .pl-c1, -.markdown-body .pl-s .pl-v { - color: var(--color-prettylights-syntax-constant); -} - -.markdown-body .pl-e, -.markdown-body .pl-en { - color: var(--color-prettylights-syntax-entity); -} - -.markdown-body .pl-smi, -.markdown-body .pl-s .pl-s1 { - color: var(--color-prettylights-syntax-storage-modifier-import); -} - -.markdown-body .pl-ent { - color: var(--color-prettylights-syntax-entity-tag); -} - -.markdown-body .pl-k { - color: var(--color-prettylights-syntax-keyword); -} - -.markdown-body .pl-s, -.markdown-body .pl-pds, -.markdown-body .pl-s .pl-pse .pl-s1, -.markdown-body .pl-sr, -.markdown-body .pl-sr .pl-cce, -.markdown-body .pl-sr .pl-sre, -.markdown-body .pl-sr .pl-sra { - color: var(--color-prettylights-syntax-string); -} - -.markdown-body .pl-v, -.markdown-body .pl-smw { - color: var(--color-prettylights-syntax-variable); -} - -.markdown-body .pl-bu { - color: var(--color-prettylights-syntax-brackethighlighter-unmatched); -} - -.markdown-body .pl-ii { - color: var(--color-prettylights-syntax-invalid-illegal-text); - background-color: var(--color-prettylights-syntax-invalid-illegal-bg); -} - -.markdown-body .pl-c2 { - color: var(--color-prettylights-syntax-carriage-return-text); - background-color: var(--color-prettylights-syntax-carriage-return-bg); -} - -.markdown-body .pl-sr .pl-cce { - font-weight: bold; - color: var(--color-prettylights-syntax-string-regexp); -} - -.markdown-body .pl-ml { - color: var(--color-prettylights-syntax-markup-list); -} - -.markdown-body .pl-mh, -.markdown-body .pl-mh .pl-en, -.markdown-body .pl-ms { - font-weight: bold; - color: var(--color-prettylights-syntax-markup-heading); -} - -.markdown-body .pl-mi { - font-style: italic; - color: var(--color-prettylights-syntax-markup-italic); -} - -.markdown-body .pl-mb { - font-weight: bold; - color: var(--color-prettylights-syntax-markup-bold); -} - -.markdown-body .pl-md { - color: var(--color-prettylights-syntax-markup-deleted-text); - background-color: var(--color-prettylights-syntax-markup-deleted-bg); -} - -.markdown-body .pl-mi1 { - color: var(--color-prettylights-syntax-markup-inserted-text); - background-color: var(--color-prettylights-syntax-markup-inserted-bg); -} - -.markdown-body .pl-mc { - color: var(--color-prettylights-syntax-markup-changed-text); - background-color: var(--color-prettylights-syntax-markup-changed-bg); -} - -.markdown-body .pl-mi2 { - color: var(--color-prettylights-syntax-markup-ignored-text); - background-color: var(--color-prettylights-syntax-markup-ignored-bg); -} - -.markdown-body .pl-mdr { - font-weight: bold; - color: var(--color-prettylights-syntax-meta-diff-range); -} - -.markdown-body .pl-ba { - color: var(--color-prettylights-syntax-brackethighlighter-angle); -} - -.markdown-body .pl-sg { - color: var(--color-prettylights-syntax-sublimelinter-gutter-mark); -} - -.markdown-body .pl-corl { - text-decoration: underline; - color: var(--color-prettylights-syntax-constant-other-reference-link); -} - -.markdown-body [data-catalyst] { - display: block; -} - -.markdown-body g-emoji { - font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - font-size: 1em; - font-style: normal !important; - font-weight: 400; - line-height: 1; - vertical-align: -0.075em; -} - -.markdown-body g-emoji img { - width: 1em; - height: 1em; -} - -.markdown-body::before { - display: table; - content: ""; -} - -.markdown-body::after { - display: table; - clear: both; - content: ""; -} - -.markdown-body > *:first-child { - margin-top: 0 !important; -} - -.markdown-body > *:last-child { - margin-bottom: 0 !important; -} - -.markdown-body a:not([href]) { - color: inherit; - text-decoration: none; -} - -.markdown-body .absent { - color: var(--color-danger-fg); -} - -.markdown-body .anchor { - float: left; - padding-right: 4px; - margin-left: -20px; - line-height: 1; -} - -.markdown-body .anchor:focus { - outline: none; -} - -.markdown-body p, -.markdown-body blockquote, -.markdown-body ul, -.markdown-body ol, -.markdown-body dl, -.markdown-body table, -.markdown-body pre, -.markdown-body details { - margin-top: 0; - margin-bottom: 16px; -} - -.markdown-body blockquote > :first-child { - margin-top: 0; -} - -.markdown-body blockquote > :last-child { - margin-bottom: 0; -} - -.markdown-body sup > a::before { - content: "["; -} - -.markdown-body sup > a::after { - content: "]"; -} - -.markdown-body h1 .octicon-link, -.markdown-body h2 .octicon-link, -.markdown-body h3 .octicon-link, -.markdown-body h4 .octicon-link, -.markdown-body h5 .octicon-link, -.markdown-body h6 .octicon-link { - color: var(--color-fg-default); - vertical-align: middle; - visibility: hidden; -} - -.markdown-body h1:hover .anchor, -.markdown-body h2:hover .anchor, -.markdown-body h3:hover .anchor, -.markdown-body h4:hover .anchor, -.markdown-body h5:hover .anchor, -.markdown-body h6:hover .anchor { - text-decoration: none; -} - -.markdown-body h1:hover .anchor .octicon-link, -.markdown-body h2:hover .anchor .octicon-link, -.markdown-body h3:hover .anchor .octicon-link, -.markdown-body h4:hover .anchor .octicon-link, -.markdown-body h5:hover .anchor .octicon-link, -.markdown-body h6:hover .anchor .octicon-link { - visibility: visible; -} - -.markdown-body h1 tt, -.markdown-body h1 code, -.markdown-body h2 tt, -.markdown-body h2 code, -.markdown-body h3 tt, -.markdown-body h3 code, -.markdown-body h4 tt, -.markdown-body h4 code, -.markdown-body h5 tt, -.markdown-body h5 code, -.markdown-body h6 tt, -.markdown-body h6 code { - padding: 0 0.2em; - font-size: inherit; -} - -.markdown-body ul.no-list, -.markdown-body ol.no-list { - padding: 0; - list-style-type: none; -} - -.markdown-body ol[type="1"] { - list-style-type: decimal; -} - -.markdown-body ol[type="a"] { - list-style-type: lower-alpha; -} - -.markdown-body ol[type="i"] { - list-style-type: lower-roman; -} - -.markdown-body div > ol:not([type]) { - list-style-type: decimal; -} - -.markdown-body ul ul, -.markdown-body ul ol, -.markdown-body ol ol, -.markdown-body ol ul { - margin-top: 0; - margin-bottom: 0; -} - -.markdown-body li > p { - margin-top: 16px; -} - -.markdown-body li + li { - margin-top: 0.25em; -} - -.markdown-body dl { - padding: 0; -} - -.markdown-body dl dt { - padding: 0; - margin-top: 16px; - font-size: 1em; - font-style: italic; - font-weight: 600; -} - -.markdown-body dl dd { - padding: 0 16px; - margin-bottom: 16px; -} - -.markdown-body table th { - font-weight: 600; -} - -.markdown-body table th, -.markdown-body table td { - padding: 6px 13px; - border: 1px solid var(--color-border-default); -} - -.markdown-body table tr { - background-color: var(--color-canvas-default); - border-top: 1px solid var(--color-border-muted); -} - -.markdown-body table tr:nth-child(2n) { - background-color: var(--color-canvas-subtle); -} - -.markdown-body table img { - background-color: transparent; -} - -.markdown-body img[align="right"] { - padding-left: 20px; -} - -.markdown-body img[align="left"] { - padding-right: 20px; -} - -.markdown-body .emoji { - max-width: none; - vertical-align: text-top; - background-color: transparent; -} - -.markdown-body span.frame { - display: block; - overflow: hidden; -} - -.markdown-body span.frame > span { - display: block; - float: left; - width: auto; - padding: 7px; - margin: 13px 0 0; - overflow: hidden; - border: 1px solid var(--color-border-default); -} - -.markdown-body span.frame span img { - display: block; - float: left; -} - -.markdown-body span.frame span span { - display: block; - padding: 5px 0 0; - clear: both; - color: var(--color-fg-default); -} - -.markdown-body span.align-center { - display: block; - overflow: hidden; - clear: both; -} - -.markdown-body span.align-center > span { - display: block; - margin: 13px auto 0; - overflow: hidden; - text-align: center; -} - -.markdown-body span.align-center span img { - margin: 0 auto; - text-align: center; -} - -.markdown-body span.align-right { - display: block; - overflow: hidden; - clear: both; -} - -.markdown-body span.align-right > span { - display: block; - margin: 13px 0 0; - overflow: hidden; - text-align: right; -} - -.markdown-body span.align-right span img { - margin: 0; - text-align: right; -} - -.markdown-body span.float-left { - display: block; - float: left; - margin-right: 13px; - overflow: hidden; -} - -.markdown-body span.float-left span { - margin: 13px 0 0; -} - -.markdown-body span.float-right { - display: block; - float: right; - margin-left: 13px; - overflow: hidden; -} - -.markdown-body span.float-right > span { - display: block; - margin: 13px auto 0; - overflow: hidden; - text-align: right; -} - -.markdown-body code, -.markdown-body tt { - padding: 0.2em 0.4em; - margin: 0; - font-size: 85%; - background-color: var(--color-neutral-muted); - border-radius: 6px; -} - -.markdown-body code br, -.markdown-body tt br { - display: none; -} - -.markdown-body del code { - text-decoration: inherit; -} - -.markdown-body pre code { - font-size: 100%; -} - -.markdown-body pre > code { - padding: 0; - margin: 0; - word-break: normal; - white-space: pre; - background: transparent; - border: 0; -} - -.markdown-body .highlight { - margin-bottom: 16px; -} - -.markdown-body .highlight pre { - margin-bottom: 0; - word-break: normal; -} - -.markdown-body .highlight pre, -.markdown-body pre { - padding: 16px; - overflow: auto; - font-size: 85%; - line-height: 1.45; - background-color: var(--color-canvas-subtle); - border-radius: 6px; -} - -.markdown-body pre code, -.markdown-body pre tt { - display: inline; - max-width: auto; - padding: 0; - margin: 0; - overflow: visible; - line-height: inherit; - word-wrap: normal; - background-color: transparent; - border: 0; -} - -.markdown-body .csv-data td, -.markdown-body .csv-data th { - padding: 5px; - overflow: hidden; - font-size: 12px; - line-height: 1; - text-align: left; - white-space: nowrap; -} - -.markdown-body .csv-data .blob-num { - padding: 10px 8px 9px; - text-align: right; - background: var(--color-canvas-default); - border: 0; -} - -.markdown-body .csv-data tr { - border-top: 0; -} - -.markdown-body .csv-data th { - font-weight: 600; - background: var(--color-canvas-subtle); - border-top: 0; -} - -.markdown-body .footnotes { - font-size: 12px; - color: var(--color-fg-muted); - border-top: 1px solid var(--color-border-default); -} - -.markdown-body .footnotes ol { - padding-left: 16px; -} - -.markdown-body .footnotes li { - position: relative; -} - -.markdown-body .footnotes li:target::before { - position: absolute; - top: -8px; - right: -8px; - bottom: -8px; - left: -24px; - pointer-events: none; - content: ""; - border: 2px solid var(--color-accent-emphasis); - border-radius: 6px; -} - -.markdown-body .footnotes li:target { - color: var(--color-fg-default); -} - -.markdown-body .footnotes .data-footnote-backref g-emoji { - font-family: monospace; -} - -.markdown-body .task-list-item { - list-style-type: none; -} - -.markdown-body .task-list-item label { - font-weight: 400; -} - -.markdown-body .task-list-item.enabled label { - cursor: pointer; -} - -.markdown-body .task-list-item + .task-list-item { - margin-top: 3px; -} - -.markdown-body .task-list-item .handle { - display: none; -} - -.markdown-body .task-list-item-checkbox { - margin: 0 0.2em 0.25em -1.6em; - vertical-align: middle; -} - -.markdown-body .contains-task-list:dir(rtl) .task-list-item-checkbox { - margin: 0 -1.6em 0.25em 0.2em; -} - -.markdown-body ::-webkit-calendar-picker-indicator { - filter: invert(50%); -} diff --git a/examples/styles/vcv-markdown.css b/examples/styles/vcv-markdown.css deleted file mode 100644 index 373d19e..0000000 --- a/examples/styles/vcv-markdown.css +++ /dev/null @@ -1,13 +0,0 @@ -.markdown-body { - box-sizing: border-box; - min-width: 200px; - max-width: 960px; - margin: 0 auto; - padding: 45px; -} - -@media (max-width: 767px) { - .markdown-body { - padding: 15px; - } -} diff --git a/examples/styles/vt-backdrop.css b/examples/styles/vt-backdrop.css deleted file mode 100644 index c5d4ecf..0000000 --- a/examples/styles/vt-backdrop.css +++ /dev/null @@ -1,24 +0,0 @@ -.vt-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - background: rgba(0, 0, 0, .6); - transition: opacity .5s; -} - -.vt-backdrop.fade-enter-from, -.vt-backdrop.fade-leave-to { - opacity: 0; -} - -.vt-backdrop.fade-leave-active { - transition-duration: .3s; -} - -@media (min-width: 960px) { - .vt-backdrop { - display: none; - } -} diff --git a/examples/styles/vt-badge.css b/examples/styles/vt-badge.css deleted file mode 100644 index 9187c2e..0000000 --- a/examples/styles/vt-badge.css +++ /dev/null @@ -1,19 +0,0 @@ -.vt-badge { - display: inline-block; - border-radius: 6px; - font-size: 0.65em; - line-height: 1; - font-weight: 600; - padding: 0.35em 0.4em 0.3em; - position: relative; - top: -0.65em; - margin-left: 0.5em; - color: var(--vt-c-bg); - transition: color 0.5s; - background-color: var(--vt-c-brand); -} - -.vt-badge.warning { - color: var(--vt-c-text-light-1); - background-color: var(--vt-c-yellow); -} diff --git a/examples/styles/vt-box.css b/examples/styles/vt-box.css deleted file mode 100644 index 88a0291..0000000 --- a/examples/styles/vt-box.css +++ /dev/null @@ -1,22 +0,0 @@ -.vt-box-container { - display: flex; - flex-wrap: wrap; - justify-content: space-between; -} - -.vt-box-container .vt-box { - background-color: var(--vt-c-bg-soft); - transition: color 0.5s, background-color 0.5s; - padding: 28px 36px; - border-radius: 8px; - flex: 0 32%; /* default 3 column */ - font-size: 14px; - font-weight: 500; -} - -@media (max-width: 768px) { - .vt-box-container .vt-box { - flex: 0 100%; - margin-bottom: 20px; - } -} diff --git a/examples/styles/vt-code-group.css b/examples/styles/vt-code-group.css deleted file mode 100644 index 0cd12b0..0000000 --- a/examples/styles/vt-code-group.css +++ /dev/null @@ -1,73 +0,0 @@ -.vt-code-group { - display: flex; - flex-direction: column; -} - -.vt-code-group-contents .vt-code-group-content div[class*='language-'] { - margin-top: 0; - border-top-left-radius: 0; -} - -.vt-code-group-tabs { - display: flex; - overflow: auto; -} - -.vt-code-group-tab { - white-space: pre; - display: flex; - justify-content: center; - align-items: center; - color: var(--vt-c-text-inverse-1); - background: #292d3ef0; - border-bottom-color: rgba(255,255,255,0.3); - padding: 6px 24px; - border-width: 2px; - border-style: solid; - border-top: transparent; - border-right: transparent; - border-left: transparent; - cursor: pointer; - transition: border, background-color .2s; - transition-property: border, background-color; - transition-duration: 0.2s, 0.2s; - transition-timing-function: ease, ease; - transition-delay: 0s, 0s; -} - -.vt-code-group-tab.vt-code-group-tab-active { - background: #292d3e; - border-bottom: 2px solid var(--vt-c-brand); -} - -.vt-code-group-tab:first-child { - border-top-left-radius: 8px; -} - -.vt-code-group-tab:last-child { - border-top-right-radius: 8px; -} - -.dark .vt-code-group-tab { - color: var(--vt-c-text-1); -} - -.dark .vt-code-group-tab:not(.vt-code-group-tab-active) { - border-bottom: 2px solid rgba(255,255,255,.2); - background: var(--vt-c-black-mute); -} - -.dark .vt-code-group-tab.vt-code-group-tab-active { - background: var(--vt-c-black-soft); -} - -@media (max-width: 639px) { - .vt-code-group-tabs { - margin: 0 -24px; - } - - .vt-code-group-tab, .vt-code-group-tab:first-child, .vt-code-group-tab:last-child { - flex-grow: 1; - border-radius: 0; - } -} diff --git a/examples/styles/vt-doc-base.css b/examples/styles/vt-doc-base.css deleted file mode 100644 index 6a50e56..0000000 --- a/examples/styles/vt-doc-base.css +++ /dev/null @@ -1,267 +0,0 @@ -.vt-doc { - font-size: 16px; - line-height: 1.7; -} - -.vt-doc h1, -.vt-doc h2, -.vt-doc h3, -.vt-doc h4, -.vt-doc h5, -.vt-doc h6 { - position: relative; - font-weight: 600; - line-height: 1.5; - outline: none; -} - -.vt-doc h1 { - margin: 0 0 3rem; - font-size: 38px; - line-height: 1.4; - letter-spacing: -0.02em; -} - -.vt-doc h2 { - margin: 4rem 0 1.8rem; - border-top: 1px solid var(--vt-c-divider-light); - padding-top: 1.8rem; - font-size: 24px; - letter-spacing: -0.02em; -} - -@media (max-width: 768px) { - .vt-doc h1 { - font-size: 32px; - margin-bottom: 1.8rem; - } - .vt-doc h1 + h2 { - margin-top: 36px; - } -} - -.vt-doc h3 { - font-size: 19px; - letter-spacing: -0.01em; - margin: 3rem 0 1.25rem; -} - -.vt-doc h2 + h3 { - margin-top: 0; -} - -.vt-doc h4 { - font-size: 17px; - margin: 1.8rem 0 1rem; -} - -.vt-doc .header-anchor { - float: left; - margin-left: -0.87em; - padding-right: 0.23em; - font-weight: 500; - opacity: 0; - transition: color 0.25s, opacity 0.25s; -} - -.vt-doc h1:hover .header-anchor, -.vt-doc h1 .header-anchor:focus, -.vt-doc h2:hover .header-anchor, -.vt-doc h2 .header-anchor:focus, -.vt-doc h3:hover .header-anchor, -.vt-doc h3 .header-anchor:focus, -.vt-doc h4:hover .header-anchor, -.vt-doc h4 .header-anchor:focus, -.vt-doc h5:hover .header-anchor, -.vt-doc h5 .header-anchor:focus, -.vt-doc h6:hover .header-anchor, -.vt-doc h6 .header-anchor:focus { - opacity: 1; -} - -.vt-doc hr { - border: none; - border-top: 1px solid var(--vt-c-divider-light); - margin: 1.8rem 0; -} - -.vt-doc p, -.vt-doc ul, -.vt-doc ol, -.vt-doc summary { - margin-bottom: 1.2em; -} - -.vt-doc a { - font-weight: 500; - color: var(--vt-c-brand); - transition: color 0.25s; - text-decoration-style: dotted; -} - -.vt-doc a:hover { - color: var(--vt-c-brand-highlight); -} - -.vt-doc strong { - font-weight: 600; -} - -.vt-doc table { - display: block; - border-collapse: collapse; - margin: 1rem 0; - overflow-x: auto; -} - -.vt-doc tr { - border-top: 1px solid var(--vt-c-divider); - transition: background-color 0.5s; -} - -.vt-doc tr:nth-child(2n) { - background-color: var(--vt-c-bg-soft); -} - -.vt-doc th, -.vt-doc td { - border: 1px solid var(--vt-c-divider); - padding: 0.6em 1em; -} - -.vt-doc blockquote { - margin: 1rem 0; - border-left: 0.2rem solid var(--vt-c-divider); - padding-left: 1rem; - transition: border-color 0.5s; -} - -.vt-doc blockquote > p { - margin: 0; - font-size: 16px; - color: var(--vt-c-text-2); - transition: color 0.5s; -} - -.vt-doc figure { - margin: 0; -} - -.vt-doc img { - max-width: 100%; -} - -.vt-doc p > img { - margin: 28px auto; -} - -.vt-doc ol { - counter-reset: item; -} -.vt-doc ol[start='2'] { - counter-reset: item 1; -} -.vt-doc ol[start='3'] { - counter-reset: item 2; -} -.vt-doc ol[start='4'] { - counter-reset: item 3; -} -.vt-doc ol[start='5'] { - counter-reset: item 4; -} -.vt-doc ol[start='6'] { - counter-reset: item 5; -} -.vt-doc ol[start='7'] { - counter-reset: item 6; -} -.vt-doc ol[start='8'] { - counter-reset: item 7; -} -.vt-doc ol[start='9'] { - counter-reset: item 8; -} -.vt-doc ol[start='10'] { - counter-reset: item 9; -} - -.vt-doc ol > li { - counter-increment: item; - position: relative; - padding-left: 1.5rem; -} - -.vt-doc ol > li:before { - position: absolute; - left: 2px; - top: 1px; - font-weight: bold; - font-size: 14px; - color: var(--vt-c-text-3); - content: counter(item) '.'; -} - -@media (min-width: 768px) { - .vt-doc ol > li:before { - top: 2px; - } -} - -.vt-doc li { - position: relative; - margin: 1px 0; -} - -.vt-doc ul { - padding-left: 1.25rem; -} - -.vt-doc ul > li:before { - content: ''; - position: absolute; - width: 5px; - height: 5px; - border-radius: 50%; - background-color: var(--vt-c-text-3); - transition: background-color 0.5s; - left: -1.25rem; - top: 0.75rem; -} - -.vt-doc .video::before { - display: block; - content: ''; - padding-top: 56.25%; -} - -.vt-doc .video { - overflow: hidden; - width: calc(100% + 48px); - min-width: 415px; - position: relative; - margin: 0 -24px 18px; -} - -.vt-doc .video-content { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 100%; - height: 100%; - border: 0; -} - -@media (min-width: 640px) { - .vt-doc .video { - border-radius: 8px; - } -} - -@media (max-width: 463px) { - .vt-doc .video { - width: 100%; - margin: 0 calc((100vw - 463px) / 2) 18px; - } -} diff --git a/examples/styles/vt-doc-code.css b/examples/styles/vt-doc-code.css deleted file mode 100644 index 3c1e7f3..0000000 --- a/examples/styles/vt-doc-code.css +++ /dev/null @@ -1,214 +0,0 @@ -.vt-doc { - --vt-doc-code-font-size: 14px; - --vt-doc-code-line-height: 1.5; -} - -/* inline code */ -.vt-doc :not(pre) > code { - background-color: var(--vt-c-bg-mute); - padding: 0.15em 0.5em; - border-radius: 4px; - color: var(--vt-c-text-code); - transition: color 0.5s, background-color 0.5s; -} - -.vt-doc a > code { - color: var(--vt-c-brand-dark); -} - -.vt-doc :not(pre, h1, h2, h3, h4, h5, h6) > code { - font-size: var(--vt-doc-code-font-size); -} - -@media (min-width: 768px) { - .vt-doc :not(pre) > code { - white-space: nowrap; - } -} - -.vt-doc div[class*="language-"] { - position: relative; - margin: 28px -24px; - background-color: #292d3e; - overflow-x: auto; - transition: background-color 0.5s; -} - -.dark .vt-doc div[class*="language-"] { - background-color: var(--vt-c-bg-soft); -} - -@media (min-width: 640px) { - .vt-doc div[class*="language-"] { - margin: 28px 0; - border-radius: 8px; - } -} - -@media (max-width: 639px) { - .vt-doc li div[class*="language-"] { - border-radius: 8px 0 0 8px; - } -} - -.vt-doc div[class*="language-"] + div[class*="language-"], -.vt-doc div[class$="-api"] + div[class*="language-"], -.vt-doc div[class*="language-"] + div[class$="-api"] > div[class*="language-"] { - margin-top: -16px; -} - -.vt-doc [class*="language-"] pre, -.vt-doc [class*="language-"] code { - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; -} - -.vt-doc [class*="language-"] pre { - position: relative; - z-index: 1; - margin: 0; - padding: 14px 24px; - background: transparent; - overflow-x: auto; -} - -.vt-doc [class*="language-"] code { - display: inline-block; - padding: 0; - line-height: var(--vt-doc-code-line-height); - font-size: var(--vt-doc-code-font-size); - color: #a6accd; - transition: color 0.5s; -} - -.vt-doc .highlight-lines { - position: absolute; - top: 0; - bottom: 0; - left: 0; - padding: 13px 0 11px; - width: 100%; - font-family: var(--vt-font-family-mono); - line-height: var(--vt-doc-code-line-height); - font-size: var(--vt-doc-code-font-size); - user-select: none; - overflow: hidden; -} - -.vt-doc .highlight-lines .highlighted { - background-color: rgba(0, 0, 0, 0.3); - transition: background-color 0.5s; -} - -.dark .vt-doc .highlight-lines .highlighted { - background-color: rgba(255, 255, 255, 0.05); -} - -.vt-doc div[class*="language-"].line-numbers-mode { - padding-left: 32px; -} - -.vt-doc .line-numbers-wrapper { - position: absolute; - top: 0; - bottom: 0; - left: 0; - z-index: 3; - border-right: 1px solid var(--vt-c-divider-dark-2); - padding: 13px 0 11px; - width: 32px; - text-align: center; - font-family: var(--vt-font-family-mono); - line-height: var(--vt-doc-code-line-height); - font-size: var(--vt-doc-code-font-size); - color: var(--vt-c-text-dark-3); - transition: border-color 0.5s, color 0.5s; -} - -.vt-doc [class*="language-"]:before { - position: absolute; - top: 4px; - right: 10px; - z-index: 2; - font-size: 12px; - font-weight: 500; - color: var(--vt-c-text-dark-3); - transition: color 0.5s; -} - -@media (max-width: 480px) { - .vt-doc [class*="language-"]:before { - top: 1px; - right: 5px; - font-size: 11px; - } - .vt-doc [class*="language-"] pre { - padding: 18px 20px 12px; - } - .vt-doc .highlight-lines { - padding-top: 17px; - } -} - -/* .vt-doc div[class~="language-$codeLang"]:before { - content: "$codeLang"; -} */ - -.vt-doc div[class~="language-vue"]:before { - content: "vue"; -} - -.vt-doc div[class~="language-html"]:before { - content: "html"; -} - -.vt-doc div[class~="language-vue-html"]:before { - content: "template"; -} - -.vt-doc div[class~="language-css"]:before { - content: "css"; -} - -.vt-doc div[class~="language-js"]:before { - content: "js"; -} - -.vt-doc div[class~="language-javascript"]:before { - content: "js"; -} - -.vt-doc div[class~="language-jsx"]:before { - content: "jsx"; -} - -.vt-doc div[class~="language-ts"]:before { - content: "ts"; -} - -.vt-doc div[class~="language-typescript"]:before { - content: "ts"; -} - -.vt-doc div[class~="language-tsx"]:before { - content: "tsx"; -} - -.vt-doc div[class~="language-json"]:before { - content: "json"; -} - -.vt-doc div[class~="language-sh"]:before, -.vt-doc div[class~="language-bash"]:before { - content: "sh"; -} diff --git a/examples/styles/vt-doc-custom-blocks.css b/examples/styles/vt-doc-custom-blocks.css deleted file mode 100644 index d7133dc..0000000 --- a/examples/styles/vt-doc-custom-blocks.css +++ /dev/null @@ -1,81 +0,0 @@ -.vt-doc .custom-block { - margin: 28px 0; - padding: 20px 24px 4px 42px; - border-radius: 8px; - overflow-x: auto; - transition: color 0.5s, background-color 0.5s; - position: relative; - font-size: 14px; - line-height: 1.6; - font-weight: 500; - color: rgba(0, 0, 0, 0.55); - background-color: var(--vt-c-bg-soft); -} - -.dark .vt-doc .custom-block { - color: var(--vt-c-text-2); -} - -.vt-doc .custom-block:before { - content: 'ⓘ'; - position: absolute; - font-weight: 600; - font-size: 15px; - top: 20px; - left: 17px; -} - -.vt-doc .custom-block.warning:before, -.vt-doc .custom-block.danger:before { - content: '⚠'; - font-size: 17px; - top: 19px; - left: 16ppx; -} - -.vt-doc .custom-block .custom-block-title { - margin-bottom: 8px; - font-size: 15px; - font-weight: 500; - color: var(--vt-c-text-1); - transition: color 0.5s; -} - -.vt-doc .custom-block.tip { - border: 1px solid var(--vt-c-brand); -} -.vt-doc .custom-block.tip:before { - color: var(--vt-c-brand); -} - -.vt-doc .custom-block.warning { - border: 1px solid var(--vt-c-yellow); -} -.vt-doc .custom-block.warning:before { - color: var(--vt-c-yellow); -} - -.vt-doc .custom-block.danger { - border: 1px solid var(--vt-c-red); -} -.vt-doc .custom-block.danger .custom-block-title, -.vt-doc .custom-block.danger:before { - color: var(--vt-c-red); -} - -.vt-doc .custom-block ul li:before { - top: 0.55rem; -} -.vt-doc .custom-block ol li:before { - top: 1px; - font-size: 13px; -} - -.vt-doc .custom-block :not(pre) > code { - font-size: 13px; - background-color: rgba(27, 31, 35, 0.05); -} - -.dark .vt-doc .custom-block :not(pre) > code { - background-color: rgba(0, 0, 0, 0.2); -} diff --git a/examples/styles/vt-flyout.css b/examples/styles/vt-flyout.css deleted file mode 100644 index 1fdaa54..0000000 --- a/examples/styles/vt-flyout.css +++ /dev/null @@ -1,66 +0,0 @@ -.vt-flyout { - position: relative; -} - -.vt-flyout:hover { - color: var(--vt-c-bland); - transition: color .25s; -} - -.vt-flyout:hover .vt-flyout-button-text { - color: var(--vt-c-text-2); -} - -.vt-flyout:hover .vt-flyout-button-icon { - fill: var(--vt-c-text-2); -} - -.vt-flyout:hover .vt-flyout-menu, -.vt-flyout-button[aria-expanded="true"] + .vt-flyout-menu { - opacity: 1; - visibility: visible; - transform: translateY(0); -} - -.vt-flyout-button { - display: flex; - align-items: center; - padding: 0 12px; - height: var(--vt-nav-height); - color: var(--vt-c-text-1); - transition: color .5s; -} - -.vt-flyout-button-text { - display: flex; - align-items: center; - line-height: var(--vt-nav-height); - font-size: 13px; - font-weight: 500; - color: var(--vt-c-text-1); - transition: color .25s; -} - -.vt-flyout-button-text-icon { - margin-left: 4px; - width: 14px; - height: 14px; - fill: currentColor; -} - -.vt-flyout-button-icon { - width: 20px; - height: 20px; - fill: currentColor; - transition: fill .25s; -} - -.vt-flyout-menu { - position: absolute; - top: calc(var(--vt-nav-height) / 2 + 15px); - right: 0; - opacity: 0; - visibility: hidden; - transform: translateY(-4px); - transition: opacity .25s, visibility .25s, transform .25s; -} diff --git a/examples/styles/vt-hamburger.css b/examples/styles/vt-hamburger.css deleted file mode 100644 index 3a0269b..0000000 --- a/examples/styles/vt-hamburger.css +++ /dev/null @@ -1,41 +0,0 @@ -.vt-hamburger { - display: flex; - justify-content: center; - align-items: center; -} - -.vt-hamburger:hover .vt-hamburger-top { top: 0; left: 0; transform: translateX(4px); } -.vt-hamburger:hover .vt-hamburger-middle { top: 6; left: 0; transform: translateX(0); } -.vt-hamburger:hover .vt-hamburger-bottom { top: 12px; left: 0; transform: translateX(8px); } - -.vt-hamburger.is-active .vt-hamburger-top { top: 6px; transform: translateX(0) rotate(225deg); } -.vt-hamburger.is-active .vt-hamburger-middle { top: 6px; transform: translateX(16px); } -.vt-hamburger.is-active .vt-hamburger-bottom { top: 6px; transform: translateX(0) rotate(135deg); } - -.vt-hamburger.is-active:hover .vt-hamburger-top, -.vt-hamburger.is-active:hover .vt-hamburger-middle, -.vt-hamburger.is-active:hover .vt-hamburger-bottom { - background-color: var(--vt-c-text-2); - transition: top .25s, background-color .25s, transform .25s; -} - -.vt-hamburger-container { - position: relative; - width: 16px; - height: 14px; - overflow: hidden; -} - -.vt-hamburger-top, -.vt-hamburger-middle, -.vt-hamburger-bottom { - position: absolute; - width: 16px; - height: 2px; - background-color: var(--vt-c-text-1); - transition: top .25s, background-color .5s, transform .25s; -} - -.vt-hamburger-top { top: 0; left: 0; transform: translateX(0); } -.vt-hamburger-middle { top: 6px; left: 0; transform: translateX(8px); } -.vt-hamburger-bottom { top: 12px; left: 0; transform: translateX(4px); } diff --git a/examples/styles/vt-link.css b/examples/styles/vt-link.css deleted file mode 100644 index 48ec100..0000000 --- a/examples/styles/vt-link.css +++ /dev/null @@ -1,9 +0,0 @@ -.vt-link-icon { - display: inline-block; - margin-top: -2px; - margin-left: 4px; - width: 11px; - height: 11px; - fill: var(--vt-c-text-3); - transition: fill 0.25s; -} diff --git a/examples/styles/vt-menu-group.css b/examples/styles/vt-menu-group.css deleted file mode 100644 index e71c036..0000000 --- a/examples/styles/vt-menu-group.css +++ /dev/null @@ -1,9 +0,0 @@ -.vt-menu-group-title { - padding: 0 18px; - line-height: 28px; - font-size: 10px; - font-weight: 600; - color: var(--vt-c-text-3); - text-transform: uppercase; - transition: color .25s; -} diff --git a/examples/styles/vt-menu-link.css b/examples/styles/vt-menu-link.css deleted file mode 100644 index 39014fb..0000000 --- a/examples/styles/vt-menu-link.css +++ /dev/null @@ -1,14 +0,0 @@ -.vt-menu-link { - display: block; - padding: 0 18px; - line-height: 28px; - font-size: 13px; - font-weight: 400; - color: var(--vt-c-text-1); - white-space: nowrap; - transition: color .25s; -} - -.vt-menu-link:hover { - color: var(--vt-c-brand); -} diff --git a/examples/styles/vt-menu.css b/examples/styles/vt-menu.css deleted file mode 100644 index 27c1276..0000000 --- a/examples/styles/vt-menu.css +++ /dev/null @@ -1,55 +0,0 @@ -.vt-menu { - border-radius: 8px; - padding: 12px 0; - min-width: 192px; - border: 1px solid transparent; - background: var(--vt-c-bg); - box-shadow: var(--vt-shadow-3); - transition: background-color 0.5s; -} - -.dark .vt-menu { - background: var(--vt-c-bg); - box-shadow: var(--vt-shadow-1); - border: 1px solid var(--vt-c-divider-light); -} - -.vt-menu-items { - transition: border-color 0.5s; -} - -.vt-menu .vt-menu-group { - padding: 0 0 12px; -} - -.vt-menu .vt-menu-group + .vt-menu-group { - border-top: 1px solid var(--vt-c-divider-light); - padding: 11px 0 12px; -} - -.vt-menu .vt-menu-group:last-child { - padding-bottom: 0; -} - -.vt-menu .vt-menu-group + .vt-menu-item-item { - border-top: 1px solid var(--vt-c-divider-light); - padding: 11px 16px 0; -} - -.vt-menu .vt-menu-item { - padding: 0 16px; - white-space: nowrap; -} - -.vt-menu-label { - flex-grow: 1; - line-height: 28px; - font-size: 12px; - font-weight: 500; - color: var(--vt-c-text-2); - transition: color 0.5s; -} - -.vt-menu-action { - padding-left: 24px; -} diff --git a/examples/styles/vt-social-link.css b/examples/styles/vt-social-link.css deleted file mode 100644 index 685d6c5..0000000 --- a/examples/styles/vt-social-link.css +++ /dev/null @@ -1,36 +0,0 @@ -.vt-social-link { - display: flex; - justify-content: center; - align-items: center; - color: var(--vt-c-text-2); - transition: color .5s; -} - -.vt-social-link.is-small { - width: 36px; - height: 36px; -} - -.vt-social-link.is-small .vt-social-link-icon { - width: 20px; - height: 20px; -} - -.vt-social-link.is-medium { - width: 48px; - height: 48px; -} - -.vt-social-link.is-medium .vt-social-link-icon { - width: 24px; - height: 24px; -} - -.vt-social-link:hover { - color: var(--vt-c-text-1); - transition: color .25s; -} - -.vt-social-link-icon { - fill: currentColor; -} diff --git a/examples/styles/vt-social-links.css b/examples/styles/vt-social-links.css deleted file mode 100644 index 9d31dfa..0000000 --- a/examples/styles/vt-social-links.css +++ /dev/null @@ -1,4 +0,0 @@ -.vt-social-links { - display: flex; - justify-content: center; -} diff --git a/examples/styles/vt-switch-appearance.css b/examples/styles/vt-switch-appearance.css deleted file mode 100644 index 3d9756b..0000000 --- a/examples/styles/vt-switch-appearance.css +++ /dev/null @@ -1,17 +0,0 @@ -.vt-switch-appearance-sun { - opacity: 1; -} -.vt-switch-appearance-moon { - opacity: 0; -} - -.dark .vt-switch-appearance-sun { - opacity: 0; -} -.dark .vt-switch-appearance-moon { - opacity: 1; -} - -.dark .vt-switch-appearance .vt-switch-check { - transform: translateX(18px); -} diff --git a/examples/styles/vt-switch.css b/examples/styles/vt-switch.css deleted file mode 100644 index f57422a..0000000 --- a/examples/styles/vt-switch.css +++ /dev/null @@ -1,54 +0,0 @@ -.vt-switch { - position: relative; - border-radius: 11px; - display: block; - width: 40px; - height: 22px; - flex-shrink: 0; - border: 1px solid var(--vt-c-divider); - background-color: var(--vt-c-bg-mute); - transition: border-color 0.25s, background-color 0.25s; -} - -.vt-switch:hover { - border-color: var(--vt-c-gray); -} - -.vt-switch-check { - position: absolute; - top: 1px; - left: 1px; - width: 18px; - height: 18px; - border-radius: 50%; - background-color: var(--vt-c-white); - box-shadow: var(--vt-shadow-1); - transition: background-color 0.25s, transform 0.25s; -} - -.dark .vt-switch-check { - background-color: var(--vt-c-black); -} - -.vt-switch-icon { - position: relative; - display: block; - width: 18px; - height: 18px; - border-radius: 50%; - overflow: hidden; -} - -.vt-switch-icon svg { - position: absolute; - top: 3px; - left: 3px; - width: 12px; - height: 12px; - fill: var(--vt-c-text-2); -} - -.dark .vt-switch-icon svg { - fill: var(--vt-c-text-1); - transition: opacity 0.25s; -} diff --git a/examples/types/config.ts b/examples/types/config.ts deleted file mode 100644 index 648c122..0000000 --- a/examples/types/config.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { Ref } from "vue"; -import { MenuItemChildWithChildren, MenuItemWithLink } from "./menu"; -import { SocialLink } from "./socialLink"; - -export interface Config { - /** - * The appearance option to enable/disable light/dark mode. - * - * @default true - */ - appearance?: boolean; - - /** - * The social links to be displayed at the end of the nav bar. Perfect for - * placing links to social services such as GitHub, Twitter, Facebook, etc. - */ - socialLinks?: SocialLink[]; - - /** - * The nav items. - */ - nav?: NavItem[]; - - /** - * The sidebar items. - */ - sidebar?: SidebarConfig; - - /** - * Info for the edit link - */ - editLink?: { - /** - * Repo of the site. - * e.g. `vuejs/docs#next` - * - * If a branch isn't specified, it defaults to `main`. - */ - repo?: string; - text?: string; - }; - - /** - * Global footer settings. The footer will only be displayed when a page has - * the frontmatter option `page: true`. You may pass `footer: false` to the - * frontmatter to hide the footer. - */ - footer?: { - license?: { - text: string; - link: string; - }; - - copyright?: string; - }; - - /** - * Algolia configuration for the site search. - */ - algolia?: AlgoliaSearchOptions; - - /** - * CarbonAds configuration - */ - carbonAds?: { - code: string; - placement: string; - }; -} - -/** - * The Algolia search options. Partially copied from - * @docsearch/react/dist/esm/DocSearch.d.ts - */ -export interface AlgoliaSearchOptions { - appId?: string; - apiKey: string; - indexName: string; - placeholder?: string; - searchParameters?: any; - disableUserPersonalization?: boolean; - initialQuery?: string; -} - -export type NavItem = NavItemWithLink | NavItemWithChildren; - -export type NavItemWithLink = MenuItemWithLink & { - /** - * activeMatch is expected to be a regex string - * We can't use actual RegExp object here because it isn't serializable - */ - activeMatch?: string; -}; - -export interface NavItemWithChildren { - text?: string; - activeMatch?: string; - items: (NavItemWithLink | MenuItemChildWithChildren)[]; -} - -export type SidebarConfig = SidebarGroup[] | MultiSidebarConfig; - -export interface MultiSidebarConfig { - [path: string]: SidebarGroup[]; -} - -export interface SidebarGroup { - text: string; - items: MenuItemWithLink[]; -} - -// vitepress https://github.dev/vuejs/vitepress -export interface VitePressData { - // site: Ref>; - page: Ref; - // theme: Ref; - frontmatter: Ref; - title: Ref; - description: Ref; - lang: Ref; - localePath: Ref; -} - -export interface PageData { - relativePath: string; - title: string; - description: string; - headers: Header[]; - frontmatter: Record; - lastUpdated?: number; -} - -export interface Header { - level: number; - title: string; - slug: string; -} - -/** - * 本地化设置 - */ -export type LocaleType = "zh_CN" | "en"; - -export interface LocaleSetting { - // Whether to show the language picker 是否显示语言选择器 - showPicker: boolean; - // Current language 当前语言 - locale: LocaleType; - // default language 默认语言 - fallback: LocaleType; - // available Locales 可用语言 - availableLocales: LocaleType[]; -} diff --git a/examples/types/menu.ts b/examples/types/menu.ts deleted file mode 100644 index d686b2c..0000000 --- a/examples/types/menu.ts +++ /dev/null @@ -1,18 +0,0 @@ -export type MenuItem = MenuItemWithLink | MenuItemWithChildren; - -export interface MenuItemWithLink { - text: string; - link: string; -} - -export interface MenuItemWithChildren { - text: string; - items: MenuItemChild[]; -} - -export type MenuItemChild = MenuItemWithLink | MenuItemChildWithChildren; - -export interface MenuItemChildWithChildren { - text?: string; - items: MenuItemWithLink[]; -} diff --git a/examples/types/socialLink.ts b/examples/types/socialLink.ts deleted file mode 100644 index 9c436ac..0000000 --- a/examples/types/socialLink.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface SocialLink { - icon: SocialLinkIcon; - link: string; -} - -export type SocialLinkIcon = - | "discord" - | "facebook" - | "github" - | "linkedin" - | "slack" - | "twitter" - | "languages"; - -export type SocialLinkSize = "small" | "medium"; diff --git a/examples/utils/sidebar.ts b/examples/utils/sidebar.ts deleted file mode 100644 index a62bd19..0000000 --- a/examples/utils/sidebar.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { SidebarConfig, SidebarGroup } from "@examples/types/config"; -import { ensureStartingSlash } from "./support"; - -/** - * Get the `SidebarConfig` from sidebar option. This method will ensure to get - * correct sidebar config from `MultiSideBarConfig` with various path - * combinations such as matching `guide/` and `/guide/`. If no matching config - * was found, it will return empty array. - */ -export function getSidebar( - sidebar: SidebarConfig, - path: string -): SidebarGroup[] { - if (Array.isArray(sidebar)) { - return sidebar; - } - - path = ensureStartingSlash(path); - - for (const dir in sidebar) { - // make sure the multi sidebar key starts with slash too - if (path.startsWith(ensureStartingSlash(dir))) { - return sidebar[dir]; - } - } - - return []; -} diff --git a/examples/utils/support.ts b/examples/utils/support.ts deleted file mode 100644 index c02b152..0000000 --- a/examples/utils/support.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function ensureStartingSlash(path: string): string { - return /^\//.test(path) ? path : `/${path}`; -} diff --git a/examples/utils/utils.ts b/examples/utils/utils.ts deleted file mode 100644 index 5a30e52..0000000 --- a/examples/utils/utils.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ref } from "vue"; - -export const hashRE = /#.*$/; -export const extRE = /(index)?\.(md|html)$/; -export const outboundRE = /^[a-z]+:/i; -export const EXTERNAL_URL_RE = /^https?:/i; - -export function isExternal(path: string): boolean { - return outboundRE.test(path); -} - -/** - * Join two paths by resolving the slash collision. - */ -export function joinPath(base: string, path: string): string { - return `${base}${path}`.replace(/\/+/g, "/"); -} - -// export const siteDataRef: Ref = shallowRef(parse(serializedSiteData)) -// function parse(data: string): SiteData { -// const parsed = JSON.parse(data) -// return (import.meta.env.DEV ? readonly(parsed) : parsed) as SiteData -// } - -export function withBase(path: string) { - return EXTERNAL_URL_RE.test(path) ? path : joinPath("http://vuejs.org", path); -} - -export function normalizeLink(url: string): string { - if (isExternal(url)) { - return url; - } - const { pathname, search, hash } = new URL(url, "http://vuejs.org"); - return withBase( - pathname.endsWith("/") || pathname.endsWith(".html") - ? url - : `${pathname.replace(/(\.md)?$/, ".html")}${search}${hash}` - ); -} - -const inBrowser = typeof window !== "undefined"; -const hashRef = ref(inBrowser ? location.hash : ""); - -if (inBrowser) { - window.addEventListener("hashchange", () => { - hashRef.value = location.hash; - }); -} - -export function isActive( - currentPath: string, - matchPath?: string, - asRegex = false -): boolean { - if (matchPath === undefined) { - return false; - } - currentPath = normalize(`/${currentPath}`); - if (asRegex) { - return new RegExp(matchPath).test(currentPath); - } else { - if (normalize(matchPath) !== currentPath) { - return false; - } - const hashMatch = matchPath.match(hashRE); - if (hashMatch) { - return hashRef.value === hashMatch[0]; - } - return true; - } -} - -export function normalize(path: string): string { - return decodeURI(path).replace(hashRE, "").replace(extRE, ""); -} diff --git a/examples/views/banner/Banner.vue b/examples/views/banner/Banner.vue deleted file mode 100644 index b1cd877..0000000 --- a/examples/views/banner/Banner.vue +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - diff --git a/examples/views/home/Home.vue b/examples/views/home/Home.vue deleted file mode 100644 index 0863014..0000000 --- a/examples/views/home/Home.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - - - diff --git a/examples/views/home/HomeExamples.vue b/examples/views/home/HomeExamples.vue deleted file mode 100644 index bd2102b..0000000 --- a/examples/views/home/HomeExamples.vue +++ /dev/null @@ -1,188 +0,0 @@ -/* eslint-disable no-useless-escape */ - - - diff --git a/examples/views/home/HomeFeatures.vue b/examples/views/home/HomeFeatures.vue deleted file mode 100644 index 596eb6e..0000000 --- a/examples/views/home/HomeFeatures.vue +++ /dev/null @@ -1,167 +0,0 @@ - - - - - diff --git a/examples/views/home/HomeHero.vue b/examples/views/home/HomeHero.vue deleted file mode 100644 index a0885c5..0000000 --- a/examples/views/home/HomeHero.vue +++ /dev/null @@ -1,183 +0,0 @@ - - - - - diff --git a/examples/views/home/NewsLetter.vue b/examples/views/home/NewsLetter.vue deleted file mode 100644 index 784125f..0000000 --- a/examples/views/home/NewsLetter.vue +++ /dev/null @@ -1,175 +0,0 @@ - - - - - diff --git a/examples/views/play/index.vue b/examples/views/play/index.vue deleted file mode 100644 index e32878e..0000000 --- a/examples/views/play/index.vue +++ /dev/null @@ -1,139 +0,0 @@ - - - diff --git a/examples/views/repl/REPL.vue b/examples/views/repl/REPL.vue deleted file mode 100644 index 84099bc..0000000 --- a/examples/views/repl/REPL.vue +++ /dev/null @@ -1,207 +0,0 @@ - - - diff --git a/index-dist.html b/index-dist.html new file mode 100644 index 0000000..3a2882e --- /dev/null +++ b/index-dist.html @@ -0,0 +1,31 @@ + + + + + + + + Vue SFC Playground + + + + + + +
+ + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..5e2c7ee --- /dev/null +++ b/index.html @@ -0,0 +1,27 @@ + + + + + + + + Vue SFC Playground + + + + + + +
+ + + \ No newline at end of file diff --git a/lib/img/grid.6fcebe76.svg b/lib/img/grid.6fcebe76.svg deleted file mode 100644 index fd814cc..0000000 --- a/lib/img/grid.6fcebe76.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file diff --git a/lib/img/grid.6fcebe76.svg.gz b/lib/img/grid.6fcebe76.svg.gz deleted file mode 100644 index 9613899..0000000 Binary files a/lib/img/grid.6fcebe76.svg.gz and /dev/null differ diff --git a/lib/vue-code-viewer.common.js b/lib/vue-code-viewer.common.js deleted file mode 100644 index 5c58823..0000000 --- a/lib/vue-code-viewer.common.js +++ /dev/null @@ -1,262133 +0,0 @@ -module.exports = -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = "8db6"); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ 0: -/***/ (function(module, exports) { - -/* (ignored) */ - -/***/ }), - -/***/ "001a": -/***/ (function(module, exports, __webpack_require__) { - -/* - * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined - * in FIPS PUB 180-1 - * This source code is derived from sha1.js of the same repository. - * The difference between SHA-0 and SHA-1 is just a bitwise rotate left - * operation was added. - */ - -var inherits = __webpack_require__("0999") -var Hash = __webpack_require__("cd2c") -var Buffer = __webpack_require__("d150").Buffer - -var K = [ - 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 -] - -var W = new Array(80) - -function Sha () { - this.init() - this._w = W - - Hash.call(this, 64, 56) -} - -inherits(Sha, Hash) - -Sha.prototype.init = function () { - this._a = 0x67452301 - this._b = 0xefcdab89 - this._c = 0x98badcfe - this._d = 0x10325476 - this._e = 0xc3d2e1f0 - - return this -} - -function rotl5 (num) { - return (num << 5) | (num >>> 27) -} - -function rotl30 (num) { - return (num << 30) | (num >>> 2) -} - -function ft (s, b, c, d) { - if (s === 0) return (b & c) | ((~b) & d) - if (s === 2) return (b & c) | (b & d) | (c & d) - return b ^ c ^ d -} - -Sha.prototype._update = function (M) { - var W = this._w - - var a = this._a | 0 - var b = this._b | 0 - var c = this._c | 0 - var d = this._d | 0 - var e = this._e | 0 - - for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) - for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16] - - for (var j = 0; j < 80; ++j) { - var s = ~~(j / 20) - var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0 - - e = d - d = c - c = rotl30(b) - b = a - a = t - } - - this._a = (a + this._a) | 0 - this._b = (b + this._b) | 0 - this._c = (c + this._c) | 0 - this._d = (d + this._d) | 0 - this._e = (e + this._e) | 0 -} - -Sha.prototype._hash = function () { - var H = Buffer.allocUnsafe(20) - - H.writeInt32BE(this._a | 0, 0) - H.writeInt32BE(this._b | 0, 4) - H.writeInt32BE(this._c | 0, 8) - H.writeInt32BE(this._d | 0, 12) - H.writeInt32BE(this._e | 0, 16) - - return H -} - -module.exports = Sha - - -/***/ }), - -/***/ "00f4": -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - - -module.exports = Readable; -/**/ - -var Duplex; -/**/ - -Readable.ReadableState = ReadableState; -/**/ - -var EE = __webpack_require__("16b4").EventEmitter; - -var EElistenerCount = function EElistenerCount(emitter, type) { - return emitter.listeners(type).length; -}; -/**/ - -/**/ - - -var Stream = __webpack_require__("12c2"); -/**/ - - -var Buffer = __webpack_require__("257d").Buffer; - -var OurUint8Array = global.Uint8Array || function () {}; - -function _uint8ArrayToBuffer(chunk) { - return Buffer.from(chunk); -} - -function _isUint8Array(obj) { - return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; -} -/**/ - - -var debugUtil = __webpack_require__(2); - -var debug; - -if (debugUtil && debugUtil.debuglog) { - debug = debugUtil.debuglog('stream'); -} else { - debug = function debug() {}; -} -/**/ - - -var BufferList = __webpack_require__("84bb"); - -var destroyImpl = __webpack_require__("f6d4"); - -var _require = __webpack_require__("270a"), - getHighWaterMark = _require.getHighWaterMark; - -var _require$codes = __webpack_require__("d43a").codes, - ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, - ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF, - ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, - ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT; // Lazy loaded to improve the startup performance. - - -var StringDecoder; -var createReadableStreamAsyncIterator; -var from; - -__webpack_require__("0999")(Readable, Stream); - -var errorOrDestroy = destroyImpl.errorOrDestroy; -var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; - -function prependListener(emitter, event, fn) { - // Sadly this is not cacheable as some libraries bundle their own - // event emitter implementation with them. - if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); // This is a hack to make sure that our error handler is attached before any - // userland ones. NEVER DO THIS. This is here only because this code needs - // to continue to work with older versions of Node.js that do not include - // the prependListener() method. The goal is to eventually remove this hack. - - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; -} - -function ReadableState(options, stream, isDuplex) { - Duplex = Duplex || __webpack_require__("c043"); - options = options || {}; // Duplex streams are both readable and writable, but share - // the same options object. - // However, some cases require setting options to different - // values for the readable and the writable sides of the duplex stream. - // These options can be provided separately as readableXXX and writableXXX. - - if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away - - this.objectMode = !!options.objectMode; - if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // the point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - - this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex); // A linked list is used to store data chunks instead of an array because the - // linked list can remove elements from the beginning faster than - // array.shift() - - this.buffer = new BufferList(); - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; // a flag to be able to tell if the event 'readable'/'data' is emitted - // immediately, or on a later tick. We set this to true at first, because - // any actions that shouldn't happen until "later" should generally also - // not happen before the first read call. - - this.sync = true; // whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; - this.resumeScheduled = false; - this.paused = true; // Should close be emitted on destroy. Defaults to true. - - this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'end' (and potentially 'finish') - - this.autoDestroy = !!options.autoDestroy; // has it been destroyed - - this.destroyed = false; // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - - this.defaultEncoding = options.defaultEncoding || 'utf8'; // the number of writers that are awaiting a drain event in .pipe()s - - this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled - - this.readingMore = false; - this.decoder = null; - this.encoding = null; - - if (options.encoding) { - if (!StringDecoder) StringDecoder = __webpack_require__("cdda").StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; - } -} - -function Readable(options) { - Duplex = Duplex || __webpack_require__("c043"); - if (!(this instanceof Readable)) return new Readable(options); // Checking for a Stream.Duplex instance is faster here instead of inside - // the ReadableState constructor, at least with V8 6.5 - - var isDuplex = this instanceof Duplex; - this._readableState = new ReadableState(options, this, isDuplex); // legacy - - this.readable = true; - - if (options) { - if (typeof options.read === 'function') this._read = options.read; - if (typeof options.destroy === 'function') this._destroy = options.destroy; - } - - Stream.call(this); -} - -Object.defineProperty(Readable.prototype, 'destroyed', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - if (this._readableState === undefined) { - return false; - } - - return this._readableState.destroyed; - }, - set: function set(value) { - // we ignore the value if the stream - // has not been initialized yet - if (!this._readableState) { - return; - } // backward compatibility, the user is explicitly - // managing destroyed - - - this._readableState.destroyed = value; - } -}); -Readable.prototype.destroy = destroyImpl.destroy; -Readable.prototype._undestroy = destroyImpl.undestroy; - -Readable.prototype._destroy = function (err, cb) { - cb(err); -}; // Manually shove something into the read() buffer. -// This returns true if the highWaterMark has not been hit yet, -// similar to how Writable.write() returns true if you should -// write() some more. - - -Readable.prototype.push = function (chunk, encoding) { - var state = this._readableState; - var skipChunkCheck; - - if (!state.objectMode) { - if (typeof chunk === 'string') { - encoding = encoding || state.defaultEncoding; - - if (encoding !== state.encoding) { - chunk = Buffer.from(chunk, encoding); - encoding = ''; - } - - skipChunkCheck = true; - } - } else { - skipChunkCheck = true; - } - - return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); -}; // Unshift should *always* be something directly out of read() - - -Readable.prototype.unshift = function (chunk) { - return readableAddChunk(this, chunk, null, true, false); -}; - -function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { - debug('readableAddChunk', chunk); - var state = stream._readableState; - - if (chunk === null) { - state.reading = false; - onEofChunk(stream, state); - } else { - var er; - if (!skipChunkCheck) er = chunkInvalid(state, chunk); - - if (er) { - errorOrDestroy(stream, er); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { - chunk = _uint8ArrayToBuffer(chunk); - } - - if (addToFront) { - if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true); - } else if (state.ended) { - errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF()); - } else if (state.destroyed) { - return false; - } else { - state.reading = false; - - if (state.decoder && !encoding) { - chunk = state.decoder.write(chunk); - if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); - } else { - addChunk(stream, state, chunk, false); - } - } - } else if (!addToFront) { - state.reading = false; - maybeReadMore(stream, state); - } - } // We can push more data if we are below the highWaterMark. - // Also, if we have no data yet, we can stand some more bytes. - // This is to work around cases where hwm=0, such as the repl. - - - return !state.ended && (state.length < state.highWaterMark || state.length === 0); -} - -function addChunk(stream, state, chunk, addToFront) { - if (state.flowing && state.length === 0 && !state.sync) { - state.awaitDrain = 0; - stream.emit('data', chunk); - } else { - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); - if (state.needReadable) emitReadable(stream); - } - - maybeReadMore(stream, state); -} - -function chunkInvalid(state, chunk) { - var er; - - if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk); - } - - return er; -} - -Readable.prototype.isPaused = function () { - return this._readableState.flowing === false; -}; // backwards compatibility. - - -Readable.prototype.setEncoding = function (enc) { - if (!StringDecoder) StringDecoder = __webpack_require__("cdda").StringDecoder; - var decoder = new StringDecoder(enc); - this._readableState.decoder = decoder; // If setEncoding(null), decoder.encoding equals utf8 - - this._readableState.encoding = this._readableState.decoder.encoding; // Iterate over current buffer to convert already stored Buffers: - - var p = this._readableState.buffer.head; - var content = ''; - - while (p !== null) { - content += decoder.write(p.data); - p = p.next; - } - - this._readableState.buffer.clear(); - - if (content !== '') this._readableState.buffer.push(content); - this._readableState.length = content.length; - return this; -}; // Don't raise the hwm > 1GB - - -var MAX_HWM = 0x40000000; - -function computeNewHighWaterMark(n) { - if (n >= MAX_HWM) { - // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE. - n = MAX_HWM; - } else { - // Get the next highest power of 2 to prevent increasing hwm excessively in - // tiny amounts - n--; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - n++; - } - - return n; -} // This function is designed to be inlinable, so please take care when making -// changes to the function body. - - -function howMuchToRead(n, state) { - if (n <= 0 || state.length === 0 && state.ended) return 0; - if (state.objectMode) return 1; - - if (n !== n) { - // Only flow one buffer at a time - if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; - } // If we're asking for more than the current hwm, then raise the hwm. - - - if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (n <= state.length) return n; // Don't have enough - - if (!state.ended) { - state.needReadable = true; - return 0; - } - - return state.length; -} // you can override either this method, or the async _read(n) below. - - -Readable.prototype.read = function (n) { - debug('read', n); - n = parseInt(n, 10); - var state = this._readableState; - var nOrig = n; - if (n !== 0) state.emittedReadable = false; // if we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - - if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) { - debug('read: emitReadable', state.length, state.ended); - if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); - return null; - } - - n = howMuchToRead(n, state); // if we've ended, and we're now clear, then finish it up. - - if (n === 0 && state.ended) { - if (state.length === 0) endReadable(this); - return null; - } // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. - // if we need a readable event, then we need to do some reading. - - - var doRead = state.needReadable; - debug('need readable', doRead); // if we currently have less than the highWaterMark, then also read some - - if (state.length === 0 || state.length - n < state.highWaterMark) { - doRead = true; - debug('length less than watermark', doRead); - } // however, if we've ended, then there's no point, and if we're already - // reading, then it's unnecessary. - - - if (state.ended || state.reading) { - doRead = false; - debug('reading or ended', doRead); - } else if (doRead) { - debug('do read'); - state.reading = true; - state.sync = true; // if the length is currently zero, then we *need* a readable event. - - if (state.length === 0) state.needReadable = true; // call internal read method - - this._read(state.highWaterMark); - - state.sync = false; // If _read pushed data synchronously, then `reading` will be false, - // and we need to re-evaluate how much data we can return to the user. - - if (!state.reading) n = howMuchToRead(nOrig, state); - } - - var ret; - if (n > 0) ret = fromList(n, state);else ret = null; - - if (ret === null) { - state.needReadable = state.length <= state.highWaterMark; - n = 0; - } else { - state.length -= n; - state.awaitDrain = 0; - } - - if (state.length === 0) { - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true; // If we tried to read() past the EOF, then emit end on the next tick. - - if (nOrig !== n && state.ended) endReadable(this); - } - - if (ret !== null) this.emit('data', ret); - return ret; -}; - -function onEofChunk(stream, state) { - debug('onEofChunk'); - if (state.ended) return; - - if (state.decoder) { - var chunk = state.decoder.end(); - - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } - } - - state.ended = true; - - if (state.sync) { - // if we are sync, wait until next tick to emit the data. - // Otherwise we risk emitting data in the flow() - // the readable code triggers during a read() call - emitReadable(stream); - } else { - // emit 'readable' now to make sure it gets picked up. - state.needReadable = false; - - if (!state.emittedReadable) { - state.emittedReadable = true; - emitReadable_(stream); - } - } -} // Don't emit readable right away in sync mode, because this can trigger -// another read() call => stack overflow. This way, it might trigger -// a nextTick recursion warning, but that's not so bad. - - -function emitReadable(stream) { - var state = stream._readableState; - debug('emitReadable', state.needReadable, state.emittedReadable); - state.needReadable = false; - - if (!state.emittedReadable) { - debug('emitReadable', state.flowing); - state.emittedReadable = true; - process.nextTick(emitReadable_, stream); - } -} - -function emitReadable_(stream) { - var state = stream._readableState; - debug('emitReadable_', state.destroyed, state.length, state.ended); - - if (!state.destroyed && (state.length || state.ended)) { - stream.emit('readable'); - state.emittedReadable = false; - } // The stream needs another readable event if - // 1. It is not flowing, as the flow mechanism will take - // care of it. - // 2. It is not ended. - // 3. It is below the highWaterMark, so we can schedule - // another readable later. - - - state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark; - flow(stream); -} // at this point, the user has presumably seen the 'readable' event, -// and called read() to consume some data. that may have triggered -// in turn another _read(n) call, in which case reading = true if -// it's in progress. -// However, if we're not ended, or reading, and the length < hwm, -// then go ahead and try to read some more preemptively. - - -function maybeReadMore(stream, state) { - if (!state.readingMore) { - state.readingMore = true; - process.nextTick(maybeReadMore_, stream, state); - } -} - -function maybeReadMore_(stream, state) { - // Attempt to read more data if we should. - // - // The conditions for reading more data are (one of): - // - Not enough data buffered (state.length < state.highWaterMark). The loop - // is responsible for filling the buffer with enough data if such data - // is available. If highWaterMark is 0 and we are not in the flowing mode - // we should _not_ attempt to buffer any extra data. We'll get more data - // when the stream consumer calls read() instead. - // - No data in the buffer, and the stream is in flowing mode. In this mode - // the loop below is responsible for ensuring read() is called. Failing to - // call read here would abort the flow and there's no other mechanism for - // continuing the flow if the stream consumer has just subscribed to the - // 'data' event. - // - // In addition to the above conditions to keep reading data, the following - // conditions prevent the data from being read: - // - The stream has ended (state.ended). - // - There is already a pending 'read' operation (state.reading). This is a - // case where the the stream has called the implementation defined _read() - // method, but they are processing the call asynchronously and have _not_ - // called push() with new data. In this case we skip performing more - // read()s. The execution ends in this method again after the _read() ends - // up calling push() with more data. - while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) { - var len = state.length; - debug('maybeReadMore read 0'); - stream.read(0); - if (len === state.length) // didn't get any data, stop spinning. - break; - } - - state.readingMore = false; -} // abstract method. to be overridden in specific implementation classes. -// call cb(er, data) where data is <= n in length. -// for virtual (non-string, non-buffer) streams, "length" is somewhat -// arbitrary, and perhaps not very meaningful. - - -Readable.prototype._read = function (n) { - errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()')); -}; - -Readable.prototype.pipe = function (dest, pipeOpts) { - var src = this; - var state = this._readableState; - - switch (state.pipesCount) { - case 0: - state.pipes = dest; - break; - - case 1: - state.pipes = [state.pipes, dest]; - break; - - default: - state.pipes.push(dest); - break; - } - - state.pipesCount += 1; - debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); - var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; - var endFn = doEnd ? onend : unpipe; - if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn); - dest.on('unpipe', onunpipe); - - function onunpipe(readable, unpipeInfo) { - debug('onunpipe'); - - if (readable === src) { - if (unpipeInfo && unpipeInfo.hasUnpiped === false) { - unpipeInfo.hasUnpiped = true; - cleanup(); - } - } - } - - function onend() { - debug('onend'); - dest.end(); - } // when the dest drains, it reduces the awaitDrain counter - // on the source. This would be more elegant with a .once() - // handler in flow(), but adding and removing repeatedly is - // too slow. - - - var ondrain = pipeOnDrain(src); - dest.on('drain', ondrain); - var cleanedUp = false; - - function cleanup() { - debug('cleanup'); // cleanup event handlers once the pipe is broken - - dest.removeListener('close', onclose); - dest.removeListener('finish', onfinish); - dest.removeListener('drain', ondrain); - dest.removeListener('error', onerror); - dest.removeListener('unpipe', onunpipe); - src.removeListener('end', onend); - src.removeListener('end', unpipe); - src.removeListener('data', ondata); - cleanedUp = true; // if the reader is waiting for a drain event from this - // specific writer, then it would cause it to never start - // flowing again. - // So, if this is awaiting a drain, then we just call it now. - // If we don't know, then assume that we are waiting for one. - - if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); - } - - src.on('data', ondata); - - function ondata(chunk) { - debug('ondata'); - var ret = dest.write(chunk); - debug('dest.write', ret); - - if (ret === false) { - // If the user unpiped during `dest.write()`, it is possible - // to get stuck in a permanently paused state if that write - // also returned false. - // => Check whether `dest` is still a piping destination. - if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { - debug('false write response, pause', state.awaitDrain); - state.awaitDrain++; - } - - src.pause(); - } - } // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - - - function onerror(er) { - debug('onerror', er); - unpipe(); - dest.removeListener('error', onerror); - if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er); - } // Make sure our error handler is attached before userland ones. - - - prependListener(dest, 'error', onerror); // Both close and finish should trigger unpipe, but only once. - - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); - } - - dest.once('close', onclose); - - function onfinish() { - debug('onfinish'); - dest.removeListener('close', onclose); - unpipe(); - } - - dest.once('finish', onfinish); - - function unpipe() { - debug('unpipe'); - src.unpipe(dest); - } // tell the dest that it's being piped to - - - dest.emit('pipe', src); // start the flow if it hasn't been started already. - - if (!state.flowing) { - debug('pipe resume'); - src.resume(); - } - - return dest; -}; - -function pipeOnDrain(src) { - return function pipeOnDrainFunctionResult() { - var state = src._readableState; - debug('pipeOnDrain', state.awaitDrain); - if (state.awaitDrain) state.awaitDrain--; - - if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { - state.flowing = true; - flow(src); - } - }; -} - -Readable.prototype.unpipe = function (dest) { - var state = this._readableState; - var unpipeInfo = { - hasUnpiped: false - }; // if we're not piping anywhere, then do nothing. - - if (state.pipesCount === 0) return this; // just one destination. most common case. - - if (state.pipesCount === 1) { - // passed in one, but it's not the right one. - if (dest && dest !== state.pipes) return this; - if (!dest) dest = state.pipes; // got a match. - - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - if (dest) dest.emit('unpipe', this, unpipeInfo); - return this; - } // slow case. multiple pipe destinations. - - - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - - for (var i = 0; i < len; i++) { - dests[i].emit('unpipe', this, { - hasUnpiped: false - }); - } - - return this; - } // try to find the right one. - - - var index = indexOf(state.pipes, dest); - if (index === -1) return this; - state.pipes.splice(index, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) state.pipes = state.pipes[0]; - dest.emit('unpipe', this, unpipeInfo); - return this; -}; // set up data events if they are asked for -// Ensure readable listeners eventually get something - - -Readable.prototype.on = function (ev, fn) { - var res = Stream.prototype.on.call(this, ev, fn); - var state = this._readableState; - - if (ev === 'data') { - // update readableListening so that resume() may be a no-op - // a few lines down. This is needed to support once('readable'). - state.readableListening = this.listenerCount('readable') > 0; // Try start flowing on next tick if stream isn't explicitly paused - - if (state.flowing !== false) this.resume(); - } else if (ev === 'readable') { - if (!state.endEmitted && !state.readableListening) { - state.readableListening = state.needReadable = true; - state.flowing = false; - state.emittedReadable = false; - debug('on readable', state.length, state.reading); - - if (state.length) { - emitReadable(this); - } else if (!state.reading) { - process.nextTick(nReadingNextTick, this); - } - } - } - - return res; -}; - -Readable.prototype.addListener = Readable.prototype.on; - -Readable.prototype.removeListener = function (ev, fn) { - var res = Stream.prototype.removeListener.call(this, ev, fn); - - if (ev === 'readable') { - // We need to check if there is someone still listening to - // readable and reset the state. However this needs to happen - // after readable has been emitted but before I/O (nextTick) to - // support once('readable', fn) cycles. This means that calling - // resume within the same tick will have no - // effect. - process.nextTick(updateReadableListening, this); - } - - return res; -}; - -Readable.prototype.removeAllListeners = function (ev) { - var res = Stream.prototype.removeAllListeners.apply(this, arguments); - - if (ev === 'readable' || ev === undefined) { - // We need to check if there is someone still listening to - // readable and reset the state. However this needs to happen - // after readable has been emitted but before I/O (nextTick) to - // support once('readable', fn) cycles. This means that calling - // resume within the same tick will have no - // effect. - process.nextTick(updateReadableListening, this); - } - - return res; -}; - -function updateReadableListening(self) { - var state = self._readableState; - state.readableListening = self.listenerCount('readable') > 0; - - if (state.resumeScheduled && !state.paused) { - // flowing needs to be set to true now, otherwise - // the upcoming resume will not flow. - state.flowing = true; // crude way to check if we should resume - } else if (self.listenerCount('data') > 0) { - self.resume(); - } -} - -function nReadingNextTick(self) { - debug('readable nexttick read 0'); - self.read(0); -} // pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. - - -Readable.prototype.resume = function () { - var state = this._readableState; - - if (!state.flowing) { - debug('resume'); // we flow only if there is no one listening - // for readable, but we still have to call - // resume() - - state.flowing = !state.readableListening; - resume(this, state); - } - - state.paused = false; - return this; -}; - -function resume(stream, state) { - if (!state.resumeScheduled) { - state.resumeScheduled = true; - process.nextTick(resume_, stream, state); - } -} - -function resume_(stream, state) { - debug('resume', state.reading); - - if (!state.reading) { - stream.read(0); - } - - state.resumeScheduled = false; - stream.emit('resume'); - flow(stream); - if (state.flowing && !state.reading) stream.read(0); -} - -Readable.prototype.pause = function () { - debug('call pause flowing=%j', this._readableState.flowing); - - if (this._readableState.flowing !== false) { - debug('pause'); - this._readableState.flowing = false; - this.emit('pause'); - } - - this._readableState.paused = true; - return this; -}; - -function flow(stream) { - var state = stream._readableState; - debug('flow', state.flowing); - - while (state.flowing && stream.read() !== null) { - ; - } -} // wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. - - -Readable.prototype.wrap = function (stream) { - var _this = this; - - var state = this._readableState; - var paused = false; - stream.on('end', function () { - debug('wrapped end'); - - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) _this.push(chunk); - } - - _this.push(null); - }); - stream.on('data', function (chunk) { - debug('wrapped data'); - if (state.decoder) chunk = state.decoder.write(chunk); // don't skip over falsy values in objectMode - - if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; - - var ret = _this.push(chunk); - - if (!ret) { - paused = true; - stream.pause(); - } - }); // proxy all the other methods. - // important when wrapping filters and duplexes. - - for (var i in stream) { - if (this[i] === undefined && typeof stream[i] === 'function') { - this[i] = function methodWrap(method) { - return function methodWrapReturnFunction() { - return stream[method].apply(stream, arguments); - }; - }(i); - } - } // proxy certain important events. - - - for (var n = 0; n < kProxyEvents.length; n++) { - stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n])); - } // when we try to consume some more bytes, simply unpause the - // underlying stream. - - - this._read = function (n) { - debug('wrapped _read', n); - - if (paused) { - paused = false; - stream.resume(); - } - }; - - return this; -}; - -if (typeof Symbol === 'function') { - Readable.prototype[Symbol.asyncIterator] = function () { - if (createReadableStreamAsyncIterator === undefined) { - createReadableStreamAsyncIterator = __webpack_require__("7763"); - } - - return createReadableStreamAsyncIterator(this); - }; -} - -Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._readableState.highWaterMark; - } -}); -Object.defineProperty(Readable.prototype, 'readableBuffer', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._readableState && this._readableState.buffer; - } -}); -Object.defineProperty(Readable.prototype, 'readableFlowing', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._readableState.flowing; - }, - set: function set(state) { - if (this._readableState) { - this._readableState.flowing = state; - } - } -}); // exposed for testing purposes only. - -Readable._fromList = fromList; -Object.defineProperty(Readable.prototype, 'readableLength', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._readableState.length; - } -}); // Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. - -function fromList(n, state) { - // nothing buffered - if (state.length === 0) return null; - var ret; - if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { - // read it all, truncate the list - if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length); - state.buffer.clear(); - } else { - // read part of list - ret = state.buffer.consume(n, state.decoder); - } - return ret; -} - -function endReadable(stream) { - var state = stream._readableState; - debug('endReadable', state.endEmitted); - - if (!state.endEmitted) { - state.ended = true; - process.nextTick(endReadableNT, state, stream); - } -} - -function endReadableNT(state, stream) { - debug('endReadableNT', state.endEmitted, state.length); // Check that we didn't get one last unshift. - - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); - - if (state.autoDestroy) { - // In case of duplex streams we need a way to detect - // if the writable side is ready for autoDestroy as well - var wState = stream._writableState; - - if (!wState || wState.autoDestroy && wState.finished) { - stream.destroy(); - } - } - } -} - -if (typeof Symbol === 'function') { - Readable.from = function (iterable, opts) { - if (from === undefined) { - from = __webpack_require__("ace0"); - } - - return from(Readable, iterable, opts); - }; -} - -function indexOf(xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; - } - - return -1; -} -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__("d8fc"), __webpack_require__("0418"))) - -/***/ }), - -/***/ "00fa": -/***/ (function(module, exports, __webpack_require__) { - -// style-loader: Adds some css to the DOM by adding a diff --git a/src/Repl.vue b/src/Repl.vue new file mode 100644 index 0000000..b945438 --- /dev/null +++ b/src/Repl.vue @@ -0,0 +1,151 @@ + + + + + diff --git a/src/vcv/SplitPane.vue b/src/SplitPane.vue similarity index 55% rename from src/vcv/SplitPane.vue rename to src/SplitPane.vue index 20b5376..9f5b581 100644 --- a/src/vcv/SplitPane.vue +++ b/src/SplitPane.vue @@ -1,3 +1,50 @@ + + - diff --git a/src/components/VCVDropdownItem.vue b/src/components/VCVDropdownItem.vue deleted file mode 100644 index 0f1fa4e..0000000 --- a/src/components/VCVDropdownItem.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/src/editor/Editor.vue b/src/editor/Editor.vue new file mode 100644 index 0000000..4826809 --- /dev/null +++ b/src/editor/Editor.vue @@ -0,0 +1,41 @@ + + + + + + diff --git a/src/editor/FileSelector.vue b/src/editor/FileSelector.vue new file mode 100644 index 0000000..bcd4e68 --- /dev/null +++ b/src/editor/FileSelector.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/src/index.ts b/src/index.ts index cb22885..172a706 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,15 +1,7 @@ -import CodeViewer from "./vcv/VCV.vue"; - -const install = function (Vue: any) { - // Vue.component(CodeViewer.name, CodeViewer); - Vue.component("CodeViewer", CodeViewer); -}; - -// CDN 引入 -if (typeof window !== "undefined" && window.Vue) { - install(window.Vue); -} - -export default { - install, -}; +export { default as Repl } from './Repl.vue' +export { default as Preview } from './output/Preview.vue' +export { ReplStore, File } from './store' +export { compileFile } from './transform' +export type { Props as ReplProps } from './Repl.vue' +export type { Store, StoreOptions, SFCOptions, StoreState } from './store' +export type { OutputModes } from './output/types' diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..7a238db --- /dev/null +++ b/src/main.ts @@ -0,0 +1,6 @@ +import Vue from 'vue'; + +import Repl from './Repl.vue'; +new Vue({ + render: (h) => h(Repl), +}).$mount('#app'); \ No newline at end of file diff --git a/src/output/Output.vue b/src/output/Output.vue index 836adb7..68a2370 100644 --- a/src/output/Output.vue +++ b/src/output/Output.vue @@ -1,221 +1,83 @@ + + + - diff --git a/src/output/OutputContainer.vue b/src/output/OutputContainer.vue deleted file mode 100644 index 062c4f6..0000000 --- a/src/output/OutputContainer.vue +++ /dev/null @@ -1,194 +0,0 @@ - - - diff --git a/src/output/Preview.vue b/src/output/Preview.vue index 913131c..f82fc18 100644 --- a/src/output/Preview.vue +++ b/src/output/Preview.vue @@ -1,200 +1,271 @@ - + try { + const mainFile = store.state.mainFile; - diff --git a/src/output/PreviewProxy.ts b/src/output/PreviewProxy.ts new file mode 100644 index 0000000..12f9778 --- /dev/null +++ b/src/output/PreviewProxy.ts @@ -0,0 +1,96 @@ +// ReplProxy and srcdoc implementation from Svelte REPL +// MIT License https://github.com/sveltejs/svelte-repl/blob/master/LICENSE + +let uid = 1; + +export class PreviewProxy { + iframe: HTMLIFrameElement; + handlers: Record; + pending_cmds: Map< + number, + { resolve: (value: unknown) => void; reject: (reason?: any) => void } + >; + handle_event: (e: any) => void; + + constructor(iframe: HTMLIFrameElement, handlers: Record) { + this.iframe = iframe; + this.handlers = handlers; + + this.pending_cmds = new Map(); + + this.handle_event = (e) => this.handle_repl_message(e); + window.addEventListener("message", this.handle_event, false); + } + + destroy() { + window.removeEventListener("message", this.handle_event); + } + + iframe_command(action: string, args: any) { + return new Promise((resolve, reject) => { + const cmd_id = uid++; + + this.pending_cmds.set(cmd_id, { resolve, reject }); + + this.iframe.contentWindow!.postMessage({ action, cmd_id, args }, "*"); + }); + } + + handle_command_message(cmd_data: any) { + const action = cmd_data.action; + const id = cmd_data.cmd_id; + const handler = this.pending_cmds.get(id); + + if (handler) { + this.pending_cmds.delete(id); + if (action === "cmd_error") { + const { message, stack } = cmd_data; + const e = new Error(message); + e.stack = stack; + handler.reject(e); + } + + if (action === "cmd_ok") { + handler.resolve(cmd_data.args); + } + } else if (action !== "cmd_error" && action !== "cmd_ok") { + console.error("command not found", id, cmd_data, [ + ...this.pending_cmds.keys(), + ]); + } + } + + handle_repl_message(event: any) { + if (event.source !== this.iframe.contentWindow) return; + + const { action, args } = event.data; + + switch (action) { + case "cmd_error": + case "cmd_ok": + return this.handle_command_message(event.data); + case "fetch_progress": + return this.handlers.on_fetch_progress(args.remaining); + case "error": + return this.handlers.on_error(event.data); + case "unhandledrejection": + return this.handlers.on_unhandled_rejection(event.data); + case "console": + return this.handlers.on_console(event.data); + case "console_group": + return this.handlers.on_console_group(event.data); + case "console_group_collapsed": + return this.handlers.on_console_group_collapsed(event.data); + case "console_group_end": + return this.handlers.on_console_group_end(event.data); + } + } + + eval(script: string | string[]) { + return this.iframe_command("eval", { script }); + } + + handle_links() { + return this.iframe_command("catch_clicks", {}); + } +} diff --git a/src/output/moduleCompiler.ts b/src/output/moduleCompiler.ts new file mode 100644 index 0000000..a3d513c --- /dev/null +++ b/src/output/moduleCompiler.ts @@ -0,0 +1,309 @@ +import { File, Store } from "../store"; +import { + babelParse, + MagicString, + walk, + walkIdentifiers, + extractIdentifiers, + isInDestructureAssignment, + isStaticProperty, +} from "@vue/compiler-sfc"; +import { ExportSpecifier, Identifier, Node } from "@babel/types"; + +export function compileModulesForPreview(store: Store, isSSR = false) { + const seen = new Set(); + const processed: string[] = []; + processFile( + store, + store.state.files[store.state.mainFile], + processed, + seen, + isSSR + ); + + if (!isSSR) { + // also add css files that are not imported + for (const filename in store.state.files) { + if (filename.endsWith(".css")) { + const file = store.state.files[filename]; + if (!seen.has(file)) { + processed.push( + `\nwindow.__css__ += ${JSON.stringify(file.compiled.css)}` + ); + } + } + } + } + + return processed; +} + +const modulesKey = `__modules__`; +const exportKey = `__export__`; +const dynamicImportKey = `__dynamic_import__`; +const moduleKey = `__module__`; + +// similar logic with Vite's SSR transform, except this is targeting the browser +function processFile( + store: Store, + file: File, + processed: string[], + seen: Set, + isSSR: boolean +) { + if (seen.has(file)) { + return []; + } + seen.add(file); + + if (!isSSR && file.filename.endsWith(".html")) { + return processHtmlFile(store, file.code, file.filename, processed, seen); + } + + // eslint-disable-next-line prefer-const + let [js, importedFiles] = processModule( + store, + isSSR ? file.compiled.ssr : file.compiled.js, + file.filename + ); + // append css + if (!isSSR && file.compiled.css) { + js += `\nwindow.__css__ += ${JSON.stringify(file.compiled.css)}`; + } + // crawl child imports + if (importedFiles.size) { + for (const imported of importedFiles) { + processFile(store, store.state.files[imported], processed, seen, isSSR); + } + } + // push self + processed.push(js); +} + +function processModule( + store: Store, + src: string, + filename: string +): [string, Set] { + const s = new MagicString(src); + + const ast = babelParse(src, { + sourceFilename: filename, + sourceType: "module", + }).program.body; + + const idToImportMap = new Map(); + const declaredConst = new Set(); + const importedFiles = new Set(); + const importToIdMap = new Map(); + + function defineImport(node: Node, source: string) { + const filename = source.replace(/^\.\/+/, ""); + if (!(filename in store.state.files)) { + throw new Error(`File "${filename}" does not exist.`); + } + if (importedFiles.has(filename)) { + return importToIdMap.get(filename)!; + } + importedFiles.add(filename); + const id = `__import_${importedFiles.size}__`; + importToIdMap.set(filename, id); + s.appendLeft( + node.start!, + `const ${id} = ${modulesKey}[${JSON.stringify(filename)}]\n` + ); + return id; + } + + function defineExport(name: string, local = name) { + s.append(`\n${exportKey}(${moduleKey}, "${name}", () => ${local})`); + } + + // 0. instantiate module + s.prepend( + `const ${moduleKey} = ${modulesKey}[${JSON.stringify( + filename + )}] = { [Symbol.toStringTag]: "Module" }\n\n` + ); + + // 1. check all import statements and record id -> importName map + for (const node of ast) { + // import foo from 'foo' --> foo -> __import_foo__.default + // import { baz } from 'foo' --> baz -> __import_foo__.baz + // import * as ok from 'foo' --> ok -> __import_foo__ + if (node.type === "ImportDeclaration") { + const source = node.source.value; + if (source.startsWith("./")) { + const importId = defineImport(node, node.source.value); + for (const spec of node.specifiers) { + if (spec.type === "ImportSpecifier") { + idToImportMap.set( + spec.local.name, + `${importId}.${(spec.imported as Identifier).name}` + ); + } else if (spec.type === "ImportDefaultSpecifier") { + idToImportMap.set(spec.local.name, `${importId}.default`); + } else { + // namespace specifier + idToImportMap.set(spec.local.name, importId); + } + } + s.remove(node.start!, node.end!); + } + } + } + + // 2. check all export statements and define exports + for (const node of ast) { + // named exports + if (node.type === "ExportNamedDeclaration") { + if (node.declaration) { + if ( + node.declaration.type === "FunctionDeclaration" || + node.declaration.type === "ClassDeclaration" + ) { + // export function foo() {} + defineExport(node.declaration.id!.name); + } else if (node.declaration.type === "VariableDeclaration") { + // export const foo = 1, bar = 2 + for (const decl of node.declaration.declarations) { + for (const id of extractIdentifiers(decl.id)) { + defineExport(id.name); + } + } + } + s.remove(node.start!, node.declaration.start!); + } else if (node.source) { + // export { foo, bar } from './foo' + const importId = defineImport(node, node.source.value); + for (const spec of node.specifiers) { + defineExport( + (spec.exported as Identifier).name, + `${importId}.${(spec as ExportSpecifier).local.name}` + ); + } + s.remove(node.start!, node.end!); + } else { + // export { foo, bar } + for (const spec of node.specifiers) { + const local = (spec as ExportSpecifier).local.name; + const binding = idToImportMap.get(local); + defineExport((spec.exported as Identifier).name, binding || local); + } + s.remove(node.start!, node.end!); + } + } + + // default export + if (node.type === "ExportDefaultDeclaration") { + if ("id" in node.declaration && node.declaration.id) { + // named hoistable/class exports + // export default function foo() {} + // export default class A {} + const { name } = node.declaration.id; + s.remove(node.start!, node.start! + 15); + s.append(`\n${exportKey}(${moduleKey}, "default", () => ${name})`); + } else { + // anonymous default exports + s.overwrite(node.start!, node.start! + 14, `${moduleKey}.default =`); + } + } + + // export * from './foo' + if (node.type === "ExportAllDeclaration") { + const importId = defineImport(node, node.source.value); + s.remove(node.start!, node.end!); + s.append(`\nfor (const key in ${importId}) { + if (key !== 'default') { + ${exportKey}(${moduleKey}, key, () => ${importId}[key]) + } + }`); + } + } + + // 3. convert references to import bindings + for (const node of ast) { + if (node.type === "ImportDeclaration") continue; + walkIdentifiers(node, (id, parent, parentStack) => { + const binding = idToImportMap.get(id.name); + if (!binding) { + return; + } + if (isStaticProperty(parent) && parent.shorthand) { + // let binding used in a property shorthand + // { foo } -> { foo: __import_x__.foo } + // skip for destructure patterns + if ( + !(parent as any).inPattern || + isInDestructureAssignment(parent, parentStack) + ) { + s.appendLeft(id.end!, `: ${binding}`); + } + } else if ( + parent.type === "ClassDeclaration" && + id === parent.superClass + ) { + if (!declaredConst.has(id.name)) { + declaredConst.add(id.name); + // locate the top-most node containing the class declaration + const topNode = parentStack[1]; + s.prependRight(topNode.start!, `const ${id.name} = ${binding};\n`); + } + } else { + s.overwrite(id.start!, id.end!, binding); + } + }); + } + + // 4. convert dynamic imports + (walk as any)(ast, { + enter(node: Node, parent: Node) { + if (node.type === "Import" && parent.type === "CallExpression") { + const arg = parent.arguments[0]; + if (arg.type === "StringLiteral" && arg.value.startsWith("./")) { + s.overwrite(node.start!, node.start! + 6, dynamicImportKey); + s.overwrite( + arg.start!, + arg.end!, + JSON.stringify(arg.value.replace(/^\.\/+/, "")) + ); + } + } + }, + }); + + return [s.toString(), importedFiles]; +} + +const scriptRE = /]*>|>)([^]*?)<\/script>/gi; +const scriptModuleRE = + /]*type\s*=\s*(?:"module"|'module')[^>]*>([^]*?)<\/script>/gi; + +function processHtmlFile( + store: Store, + src: string, + filename: string, + processed: string[], + seen: Set +) { + const deps: string[] = []; + let jsCode = ""; + const html = src + .replace(scriptModuleRE, (_, content) => { + const [code, importedFiles] = processModule(store, content, filename); + if (importedFiles.size) { + for (const imported of importedFiles) { + processFile(store, store.state.files[imported], deps, seen, false); + } + } + jsCode += "\n" + code; + return ""; + }) + .replace(scriptRE, (_, content) => { + jsCode += "\n" + content; + return ""; + }); + processed.push(`document.body.innerHTML = ${JSON.stringify(html)}`); + processed.push(...deps); + processed.push(jsCode); +} diff --git a/src/output/srcdoc.html b/src/output/srcdoc.html new file mode 100644 index 0000000..df0a720 --- /dev/null +++ b/src/output/srcdoc.html @@ -0,0 +1,263 @@ + + + + + + + + + + + + + diff --git a/src/output/srcdocBase64.ts b/src/output/srcdocBase64.ts new file mode 100644 index 0000000..b39e039 --- /dev/null +++ b/src/output/srcdocBase64.ts @@ -0,0 +1,5 @@ +import { atou } from "../utils"; +const srcdocBase64 = ` +PCFkb2N0eXBlIGh0bWw+CjxodG1sPgoJPGhlYWQ+CgkJPHN0eWxlPgoJCQlib2R5IHsKCQkJCWZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICJTZWdvZSBVSSIsIFJvYm90bywKCQkJCU94eWdlbiwgVWJ1bnR1LCBDYW50YXJlbGwsICJPcGVuIFNhbnMiLCAiSGVsdmV0aWNhIE5ldWUiLCBzYW5zLXNlcmlmOwoJCQl9CgkJPC9zdHlsZT4KCQk8c3R5bGUgaWQ9Il9fc2ZjLXN0eWxlcyI+PC9zdHlsZT4KCQk8c2NyaXB0PgoJCQkoKCkgPT4gewoJCQkJbGV0IHNjcmlwdEVscyA9IFtdCgoJCQkJd2luZG93LnByb2Nlc3MgPSB7IGVudjoge30gfQoJCQkJd2luZG93Ll9fbW9kdWxlc19fID0ge30KCgkJCQl3aW5kb3cuX19leHBvcnRfXyA9IChtb2QsIGtleSwgZ2V0KSA9PiB7CgkJCQkJT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZCwga2V5LCB7CgkJCQkJCWVudW1lcmFibGU6IHRydWUsCgkJCQkJCWNvbmZpZ3VyYWJsZTogdHJ1ZSwKCQkJCQkJZ2V0CgkJCQkJfSkKCQkJCX0KCgkJCQl3aW5kb3cuX19keW5hbWljX2ltcG9ydF9fID0ga2V5ID0+IHsKCQkJCQlyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHdpbmRvdy5fX21vZHVsZXNfX1trZXldKQoJCQkJfQoKCQkJCWFzeW5jIGZ1bmN0aW9uIGhhbmRsZV9tZXNzYWdlKGV2KSB7CgkJCQkJbGV0IHsgYWN0aW9uLCBjbWRfaWQgfSA9IGV2LmRhdGE7CgkJCQkJY29uc3Qgc2VuZF9tZXNzYWdlID0gKHBheWxvYWQpID0+IHBhcmVudC5wb3N0TWVzc2FnZSggeyAuLi5wYXlsb2FkIH0sIGV2Lm9yaWdpbik7CgkJCQkJY29uc3Qgc2VuZF9yZXBseSA9IChwYXlsb2FkKSA9PiBzZW5kX21lc3NhZ2UoeyAuLi5wYXlsb2FkLCBjbWRfaWQgfSk7CgkJCQkJY29uc3Qgc2VuZF9vayA9ICgpID0+IHNlbmRfcmVwbHkoeyBhY3Rpb246ICdjbWRfb2snIH0pOwoJCQkJCWNvbnN0IHNlbmRfZXJyb3IgPSAobWVzc2FnZSwgc3RhY2spID0+IHNlbmRfcmVwbHkoeyBhY3Rpb246ICdjbWRfZXJyb3InLCBtZXNzYWdlLCBzdGFjayB9KTsKCgkJCQkJaWYgKGFjdGlvbiA9PT0gJ2V2YWwnKSB7CgkJCQkJCXRyeSB7CgkJCQkJCQlpZiAoc2NyaXB0RWxzLmxlbmd0aCkgewoJCQkJCQkJCXNjcmlwdEVscy5mb3JFYWNoKGVsID0+IHsKCQkJCQkJCQkJZG9jdW1lbnQuaGVhZC5yZW1vdmVDaGlsZChlbCkKCQkJCQkJCQl9KQoJCQkJCQkJCXNjcmlwdEVscy5sZW5ndGggPSAwCgkJCQkJCQl9CgoJCQkJCQkJbGV0IHsgc2NyaXB0OiBzY3JpcHRzIH0gPSBldi5kYXRhLmFyZ3MKCQkJCQkJCWlmICh0eXBlb2Ygc2NyaXB0cyA9PT0gJ3N0cmluZycpIHNjcmlwdHMgPSBbc2NyaXB0c10KCgkJCQkJCQlmb3IgKGNvbnN0IHNjcmlwdCBvZiBzY3JpcHRzKSB7CgkJCQkJCQkJY29uc3Qgc2NyaXB0RWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKQoJCQkJCQkJCXNjcmlwdEVsLnNldEF0dHJpYnV0ZSgndHlwZScsICdtb2R1bGUnKQoJCQkJCQkJCS8vIHNlbmQgb2sgaW4gdGhlIG1vZHVsZSBzY3JpcHQgdG8gZW5zdXJlIHNlcXVlbnRpYWwgZXZhbHVhdGlvbgoJCQkJCQkJCS8vIG9mIG11bHRpcGxlIHByb3h5LmV2YWwoKSBjYWxscwoJCQkJCQkJCWNvbnN0IGRvbmUgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gewoJCQkJCQkJCQl3aW5kb3cuX19uZXh0X18gPSByZXNvbHZlCgkJCQkJCQkJfSkKCQkJCQkJCQlzY3JpcHRFbC5pbm5lckhUTUwgPSBzY3JpcHQgKyBgXG53aW5kb3cuX19uZXh0X18oKWAKCQkJCQkJCQlkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHNjcmlwdEVsKQoJCQkJCQkJCXNjcmlwdEVsLm9uZXJyb3IgPSBlcnIgPT4gc2VuZF9lcnJvcihlcnIubWVzc2FnZSwgZXJyLnN0YWNrKQoJCQkJCQkJCXNjcmlwdEVscy5wdXNoKHNjcmlwdEVsKQoJCQkJCQkJCWF3YWl0IGRvbmUKCQkJCQkJCX0KCQkJCQkJCXNlbmRfb2soKQoJCQkJCQl9IGNhdGNoIChlKSB7CgkJCQkJCQlzZW5kX2Vycm9yKGUubWVzc2FnZSwgZS5zdGFjayk7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCWlmIChhY3Rpb24gPT09ICdjYXRjaF9jbGlja3MnKSB7CgkJCQkJCXRyeSB7CgkJCQkJCQljb25zdCB0b3Bfb3JpZ2luID0gZXYub3JpZ2luOwoJCQkJCQkJZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGV2ZW50ID0+IHsKCQkJCQkJCQlpZiAoZXZlbnQud2hpY2ggIT09IDEpIHJldHVybjsKCQkJCQkJCQlpZiAoZXZlbnQubWV0YUtleSB8fCBldmVudC5jdHJsS2V5IHx8IGV2ZW50LnNoaWZ0S2V5KSByZXR1cm47CgkJCQkJCQkJaWYgKGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHJldHVybjsKCgkJCQkJCQkJLy8gZW5zdXJlIHRhcmdldCBpcyBhIGxpbmsKCQkJCQkJCQlsZXQgZWwgPSBldmVudC50YXJnZXQ7CgkJCQkJCQkJd2hpbGUgKGVsICYmIGVsLm5vZGVOYW1lICE9PSAnQScpIGVsID0gZWwucGFyZW50Tm9kZTsKCQkJCQkJCQlpZiAoIWVsIHx8IGVsLm5vZGVOYW1lICE9PSAnQScpIHJldHVybjsKCgkJCQkJCQkJaWYgKGVsLmhhc0F0dHJpYnV0ZSgnZG93bmxvYWQnKSB8fCBlbC5nZXRBdHRyaWJ1dGUoJ3JlbCcpID09PSAnZXh0ZXJuYWwnIHx8IGVsLnRhcmdldCkgcmV0dXJuOwoKCQkJCQkJCQlldmVudC5wcmV2ZW50RGVmYXVsdCgpOwoKCQkJCQkJCQlpZiAoZWwuaHJlZi5zdGFydHNXaXRoKHRvcF9vcmlnaW4pKSB7CgkJCQkJCQkJCWNvbnN0IHVybCA9IG5ldyBVUkwoZWwuaHJlZik7CgkJCQkJCQkJCWlmICh1cmwuaGFzaFswXSA9PT0gJyMnKSB7CgkJCQkJCQkJCQl3aW5kb3cubG9jYXRpb24uaGFzaCA9IHVybC5oYXNoOwoJCQkJCQkJCQkJcmV0dXJuOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoKCQkJCQkJCQl3aW5kb3cub3BlbihlbC5ocmVmLCAnX2JsYW5rJyk7CgkJCQkJCQl9KTsKCQkJCQkJCXNlbmRfb2soKTsKCQkJCQkJfSBjYXRjaChlKSB7CgkJCQkJCQlzZW5kX2Vycm9yKGUubWVzc2FnZSwgZS5zdGFjayk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgoJCQkJd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBoYW5kbGVfbWVzc2FnZSwgZmFsc2UpOwoKCQkJCXdpbmRvdy5vbmVycm9yID0gZnVuY3Rpb24gKG1zZywgdXJsLCBsaW5lTm8sIGNvbHVtbk5vLCBlcnJvcikgewoJCQkJCS8vIGlnbm9yZSBlcnJvcnMgZnJvbSBpbXBvcnQgbWFwIHBvbHlmaWxsIC0gdGhlc2UgYXJlIG5lY2Vzc2FyeSBmb3IKCQkJCQkvLyBpdCB0byBkZXRlY3QgYnJvd3NlciBzdXBwb3J0CgkJCQkJaWYgKG1zZy5pbmNsdWRlcygnbW9kdWxlIHNwZWNpZmllciDigJx2dWXigJ0nKSkgewoJCQkJCQkvLyBmaXJlZm94IG9ubHkgZXJyb3IsIGlnbm9yZQoJCQkJCQlyZXR1cm4gZmFsc2UKCQkJCQl9CgkJCQkJaWYgKG1zZy5pbmNsdWRlcygnTW9kdWxlIHNwZWNpZmllciwgXCd2dWUnKSkgewoJCQkJCQkvLyBTYWZhcmkgb25seQoJCQkJCQlyZXR1cm4gZmFsc2UKCQkJCQl9CgkJCQkJdHJ5IHsKCQkJCQkJcGFyZW50LnBvc3RNZXNzYWdlKHsgYWN0aW9uOiAnZXJyb3InLCB2YWx1ZTogZXJyb3IgfSwgJyonKTsKCQkJCQl9IGNhdGNoIChlKSB7CgkJCQkJCXBhcmVudC5wb3N0TWVzc2FnZSh7IGFjdGlvbjogJ2Vycm9yJywgdmFsdWU6IG1zZyB9LCAnKicpOwoJCQkJCX0KCQkJCX0KCgkJCQl3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigidW5oYW5kbGVkcmVqZWN0aW9uIiwgZXZlbnQgPT4gewoJCQkJCWlmIChldmVudC5yZWFzb24ubWVzc2FnZS5pbmNsdWRlcygnQ3Jvc3Mtb3JpZ2luJykpIHsKCQkJCQkJZXZlbnQucHJldmVudERlZmF1bHQoKQoJCQkJCQlyZXR1cm4KCQkJCQl9CgkJCQkJdHJ5IHsKCQkJCQkJcGFyZW50LnBvc3RNZXNzYWdlKHsgYWN0aW9uOiAndW5oYW5kbGVkcmVqZWN0aW9uJywgdmFsdWU6IGV2ZW50LnJlYXNvbiB9LCAnKicpOwoJCQkJCX0gY2F0Y2ggKGUpIHsKCQkJCQkJcGFyZW50LnBvc3RNZXNzYWdlKHsgYWN0aW9uOiAndW5oYW5kbGVkcmVqZWN0aW9uJywgdmFsdWU6IGV2ZW50LnJlYXNvbi5tZXNzYWdlIH0sICcqJyk7CgkJCQkJfQoJCQkJfSk7CgoJCQkJbGV0IHByZXZpb3VzID0geyBsZXZlbDogbnVsbCwgYXJnczogbnVsbCB9OwoKCQkJCVsnY2xlYXInLCAnbG9nJywgJ2luZm8nLCAnZGlyJywgJ3dhcm4nLCAnZXJyb3InLCAndGFibGUnXS5mb3JFYWNoKChsZXZlbCkgPT4gewoJCQkJCWNvbnN0IG9yaWdpbmFsID0gY29uc29sZVtsZXZlbF07CgkJCQkJY29uc29sZVtsZXZlbF0gPSAoLi4uYXJncykgPT4gewoJCQkJCQljb25zdCBtc2cgPSBTdHJpbmcoYXJnc1swXSkKCQkJCQkJaWYgKAoJCQkJCQkJbXNnLmluY2x1ZGVzKCdZb3UgYXJlIHJ1bm5pbmcgYSBkZXZlbG9wbWVudCBidWlsZCBvZiBWdWUnKSB8fAoJCQkJCQkJbXNnLmluY2x1ZGVzKCdZb3UgYXJlIHJ1bm5pbmcgdGhlIGVzbS1idW5kbGVyIGJ1aWxkIG9mIFZ1ZScpCgkJCQkJCSkgewoJCQkJCQkJcmV0dXJuCgkJCQkJCX0KCQkJCQkJY29uc3Qgc3RyaW5naWZpZWRBcmdzID0gc3RyaW5naWZ5KGFyZ3MpOwoJCQkJCQlpZiAoCgkJCQkJCQlwcmV2aW91cy5sZXZlbCA9PT0gbGV2ZWwgJiYKCQkJCQkJCXByZXZpb3VzLmFyZ3MgJiYKCQkJCQkJCXByZXZpb3VzLmFyZ3MgPT09IHN0cmluZ2lmaWVkQXJncwoJCQkJCQkpIHsKCQkJCQkJCXBhcmVudC5wb3N0TWVzc2FnZSh7IGFjdGlvbjogJ2NvbnNvbGUnLCBsZXZlbCwgZHVwbGljYXRlOiB0cnVlIH0sICcqJyk7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlwcmV2aW91cyA9IHsgbGV2ZWwsIGFyZ3M6IHN0cmluZ2lmaWVkQXJncyB9OwoKCQkJCQkJCXRyeSB7CgkJCQkJCQkJcGFyZW50LnBvc3RNZXNzYWdlKHsgYWN0aW9uOiAnY29uc29sZScsIGxldmVsLCBhcmdzIH0sICcqJyk7CgkJCQkJCQl9IGNhdGNoIChlcnIpIHsKCQkJCQkJCQlwYXJlbnQucG9zdE1lc3NhZ2UoeyBhY3Rpb246ICdjb25zb2xlJywgbGV2ZWwsIGFyZ3M6IGFyZ3MubWFwKGEgPT4gewoJCQkJCQkJCQlyZXR1cm4gYSBpbnN0YW5jZW9mIEVycm9yID8gYS5tZXNzYWdlIDogU3RyaW5nKGEpCgkJCQkJCQkJfSkgfSwgJyonKTsKCQkJCQkJCX0KCQkJCQkJfQoKCQkJCQkJb3JpZ2luYWwoLi4uYXJncyk7CgkJCQkJfQoJCQkJfSk7CgoJCQkJWwoJCQkJCXsgbWV0aG9kOiAnZ3JvdXAnLCBhY3Rpb246ICdjb25zb2xlX2dyb3VwJyB9LAoJCQkJCXsgbWV0aG9kOiAnZ3JvdXBFbmQnLCBhY3Rpb246ICdjb25zb2xlX2dyb3VwX2VuZCcgfSwKCQkJCQl7IG1ldGhvZDogJ2dyb3VwQ29sbGFwc2VkJywgYWN0aW9uOiAnY29uc29sZV9ncm91cF9jb2xsYXBzZWQnIH0sCgkJCQldLmZvckVhY2goKGdyb3VwX2FjdGlvbikgPT4gewoJCQkJCWNvbnN0IG9yaWdpbmFsID0gY29uc29sZVtncm91cF9hY3Rpb24ubWV0aG9kXTsKCQkJCQljb25zb2xlW2dyb3VwX2FjdGlvbi5tZXRob2RdID0gKGxhYmVsKSA9PiB7CgkJCQkJCXBhcmVudC5wb3N0TWVzc2FnZSh7IGFjdGlvbjogZ3JvdXBfYWN0aW9uLmFjdGlvbiwgbGFiZWwgfSwgJyonKTsKCgkJCQkJCW9yaWdpbmFsKGxhYmVsKTsKCQkJCQl9OwoJCQkJfSk7CgoJCQkJY29uc3QgdGltZXJzID0gbmV3IE1hcCgpOwoJCQkJY29uc3Qgb3JpZ2luYWxfdGltZSA9IGNvbnNvbGUudGltZTsKCQkJCWNvbnN0IG9yaWdpbmFsX3RpbWVsb2cgPSBjb25zb2xlLnRpbWVMb2c7CgkJCQljb25zdCBvcmlnaW5hbF90aW1lZW5kID0gY29uc29sZS50aW1lRW5kOwoKCQkJCWNvbnNvbGUudGltZSA9IChsYWJlbCA9ICdkZWZhdWx0JykgPT4gewoJCQkJCW9yaWdpbmFsX3RpbWUobGFiZWwpOwoJCQkJCXRpbWVycy5zZXQobGFiZWwsIHBlcmZvcm1hbmNlLm5vdygpKTsKCQkJCX0KCQkJCWNvbnNvbGUudGltZUxvZyA9IChsYWJlbCA9ICdkZWZhdWx0JykgPT4gewoJCQkJCW9yaWdpbmFsX3RpbWVsb2cobGFiZWwpOwoJCQkJCWNvbnN0IG5vdyA9IHBlcmZvcm1hbmNlLm5vdygpOwoJCQkJCWlmICh0aW1lcnMuaGFzKGxhYmVsKSkgewoJCQkJCQlwYXJlbnQucG9zdE1lc3NhZ2UoeyBhY3Rpb246ICdjb25zb2xlJywgbGV2ZWw6ICdzeXN0ZW0tbG9nJywgYXJnczogW2Ake2xhYmVsfTogJHtub3cgLSB0aW1lcnMuZ2V0KGxhYmVsKX1tc2BdIH0sICcqJyk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJcGFyZW50LnBvc3RNZXNzYWdlKHsgYWN0aW9uOiAnY29uc29sZScsIGxldmVsOiAnc3lzdGVtLXdhcm4nLCBhcmdzOiBbYFRpbWVyICcke2xhYmVsfScgZG9lcyBub3QgZXhpc3RgXSB9LCAnKicpOwoJCQkJCX0KCQkJCX0KCQkJCWNvbnNvbGUudGltZUVuZCA9IChsYWJlbCA9ICdkZWZhdWx0JykgPT4gewoJCQkJCW9yaWdpbmFsX3RpbWVlbmQobGFiZWwpOwoJCQkJCWNvbnN0IG5vdyA9IHBlcmZvcm1hbmNlLm5vdygpOwoJCQkJCWlmICh0aW1lcnMuaGFzKGxhYmVsKSkgewoJCQkJCQlwYXJlbnQucG9zdE1lc3NhZ2UoeyBhY3Rpb246ICdjb25zb2xlJywgbGV2ZWw6ICdzeXN0ZW0tbG9nJywgYXJnczogW2Ake2xhYmVsfTogJHtub3cgLSB0aW1lcnMuZ2V0KGxhYmVsKX1tc2BdIH0sICcqJyk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJcGFyZW50LnBvc3RNZXNzYWdlKHsgYWN0aW9uOiAnY29uc29sZScsIGxldmVsOiAnc3lzdGVtLXdhcm4nLCBhcmdzOiBbYFRpbWVyICcke2xhYmVsfScgZG9lcyBub3QgZXhpc3RgXSB9LCAnKicpOwoJCQkJCX0KCQkJCQl0aW1lcnMuZGVsZXRlKGxhYmVsKTsKCQkJCX07CgoJCQkJY29uc3Qgb3JpZ2luYWxfYXNzZXJ0ID0gY29uc29sZS5hc3NlcnQ7CgkJCQljb25zb2xlLmFzc2VydCA9IChjb25kaXRpb24sIC4uLmFyZ3MpID0+IHsKCQkJCQlpZiAoY29uZGl0aW9uKSB7CgkJCQkJCWNvbnN0IHN0YWNrID0gbmV3IEVycm9yKCkuc3RhY2s7CgkJCQkJCXBhcmVudC5wb3N0TWVzc2FnZSh7IGFjdGlvbjogJ2NvbnNvbGUnLCBsZXZlbDogJ2Fzc2VydCcsIGFyZ3MsIHN0YWNrIH0sICcqJyk7CgkJCQkJfQoJCQkJCW9yaWdpbmFsX2Fzc2VydChjb25kaXRpb24sIC4uLmFyZ3MpOwoJCQkJfTsKCgkJCQljb25zdCBjb3VudGVyID0gbmV3IE1hcCgpOwoJCQkJY29uc3Qgb3JpZ2luYWxfY291bnQgPSBjb25zb2xlLmNvdW50OwoJCQkJY29uc3Qgb3JpZ2luYWxfY291bnRyZXNldCA9IGNvbnNvbGUuY291bnRSZXNldDsKCgkJCQljb25zb2xlLmNvdW50ID0gKGxhYmVsID0gJ2RlZmF1bHQnKSA9PiB7CgkJCQkJY291bnRlci5zZXQobGFiZWwsIChjb3VudGVyLmdldChsYWJlbCkgfHwgMCkgKyAxKTsKCQkJCQlwYXJlbnQucG9zdE1lc3NhZ2UoeyBhY3Rpb246ICdjb25zb2xlJywgbGV2ZWw6ICdzeXN0ZW0tbG9nJywgYXJnczogYCR7bGFiZWx9OiAke2NvdW50ZXIuZ2V0KGxhYmVsKX1gIH0sICcqJyk7CgkJCQkJb3JpZ2luYWxfY291bnQobGFiZWwpOwoJCQkJfTsKCgkJCQljb25zb2xlLmNvdW50UmVzZXQgPSAobGFiZWwgPSAnZGVmYXVsdCcpID0+IHsKCQkJCQlpZiAoY291bnRlci5oYXMobGFiZWwpKSB7CgkJCQkJCWNvdW50ZXIuc2V0KGxhYmVsLCAwKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlwYXJlbnQucG9zdE1lc3NhZ2UoeyBhY3Rpb246ICdjb25zb2xlJywgbGV2ZWw6ICdzeXN0ZW0td2FybicsIGFyZ3M6IGBDb3VudCBmb3IgJyR7bGFiZWx9JyBkb2VzIG5vdCBleGlzdGAgfSwgJyonKTsKCQkJCQl9CgkJCQkJb3JpZ2luYWxfY291bnRyZXNldChsYWJlbCk7CgkJCQl9OwoKCQkJCWNvbnN0IG9yaWdpbmFsX3RyYWNlID0gY29uc29sZS50cmFjZTsKCgkJCQljb25zb2xlLnRyYWNlID0gKC4uLmFyZ3MpID0+IHsKCQkJCQljb25zdCBzdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrOwoJCQkJCXBhcmVudC5wb3N0TWVzc2FnZSh7IGFjdGlvbjogJ2NvbnNvbGUnLCBsZXZlbDogJ3RyYWNlJywgYXJncywgc3RhY2sgfSwgJyonKTsKCQkJCQlvcmlnaW5hbF90cmFjZSguLi5hcmdzKTsKCQkJCX07CgoJCQkJZnVuY3Rpb24gc3RyaW5naWZ5KGFyZ3MpIHsKCQkJCQl0cnkgewoJCQkJCQlyZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJncyk7CgkJCQkJfSBjYXRjaCAoZXJyb3IpIHsKCQkJCQkJcmV0dXJuIG51bGw7CgkJCQkJfQoJCQkJfQoJCQl9KSgpCgkJPC9zY3JpcHQ+CgoJCTwhLS0gRVMgTW9kdWxlIFNoaW1zOiBJbXBvcnQgbWFwcyBwb2x5ZmlsbCBmb3IgbW9kdWxlcyBicm93c2VycyB3aXRob3V0IGltcG9ydCBtYXBzIHN1cHBvcnQgKGFsbCBleGNlcHQgQ2hyb21lIDg5KykgLS0+CgkJPHNjcmlwdCBhc3luYyBzcmM9Imh0dHBzOi8vdW5wa2cuY29tL2VzLW1vZHVsZS1zaGltc0AxLjUuMTgvZGlzdC9lcy1tb2R1bGUtc2hpbXMud2FzbS5qcyI+PC9zY3JpcHQ+CgkJPHNjcmlwdCB0eXBlPSJpbXBvcnRtYXAiPjwhLS1JTVBPUlRfTUFQLS0+PC9zY3JpcHQ+Cgk8L2hlYWQ+Cgk8Ym9keT48L2JvZHk+CjwvaHRtbD4K`; + +export const srcdoc = atou(srcdocBase64); diff --git a/src/output/types.ts b/src/output/types.ts new file mode 100644 index 0000000..d173151 --- /dev/null +++ b/src/output/types.ts @@ -0,0 +1 @@ +export type OutputModes = "preview" | "js" | "css" | "ssr"; diff --git a/src/settings/sysSetting.ts b/src/settings/sysSetting.ts deleted file mode 100644 index ff99961..0000000 --- a/src/settings/sysSetting.ts +++ /dev/null @@ -1,49 +0,0 @@ -import type { DropdownItem, DropdownItemChild } from "types/vcv"; - -export const screenSizes: DropdownItem[] = [ - { label: "Default", key: [0, 0] }, - { - label: "phone", - items: [ - { label: "Moto 4G", key: [360, 640] }, - { label: "Galaxy S5", key: [360, 640] }, - { label: "Pixel 2", key: [411, 731] }, - { label: "Pixel 2 XL", key: [411, 823] }, - { label: "iPhone 5/SE", key: [320, 568] }, - { label: "iPhone 6/7/8", key: [375, 667] }, - { label: "iPhone 6/7/8 Plus", key: [414, 736] }, - { label: "iPhone X", key: [375, 812] }, - ], - }, - { - label: "pad", - items: [ - { label: "iPad", key: [768, 1024] }, - { label: "iPad Pro", key: [1024, 1366] }, - { label: "Surface Duo", key: [540, 720] }, - { label: "Galaxy Fold", key: [280, 653] }, - ], - }, -]; - -// { -// "Default": [0, 0], -// "Moto 4G": [360, 640], -// "Galaxy S5": [360, 640], -// "Pixel 2": [411, 731], -// "Pixel 2 XL": [411, 823], -// "iPhone 5/SE": [320, 568], -// "iPhone 6/7/8": [375, 667], -// "iPhone 6/7/8 Plus": [414, 736], -// "iPhone X": [375, 812], -// "iPad": [768, 1024], -// "iPad Pro": [1024, 1366], -// "Surface Duo": [540, 720], -// "Galaxy Fold": [280, 653] -// } - -export const dockSides: DropdownItem[] = [ - { label: "top", key: "top", icon: "mdi:dock-top" }, - { label: "right", key: "right", icon: "mdi:dock-right" }, - { label: "left", key: "left", icon: "mdi:dock-left" }, -]; diff --git a/src/shims-tsx.d.ts b/src/shims-tsx.d.ts deleted file mode 100644 index abb2e0d..0000000 --- a/src/shims-tsx.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import Vue, { VNode } from "vue"; -import { ComponentRenderProxy } from "vue"; - -declare global { - namespace JSX { - // tslint:disable no-empty-interface - interface Element extends VNode {} - // tslint:disable no-empty-interface - // interface ElementClass extends Vue {} - interface ElementClass extends ComponentRenderProxy {} - interface ElementAttributesProperty { - $props: any; // specify the property name to use - } - interface IntrinsicElements { - [elem: string]: any; - } - } -} diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts deleted file mode 100644 index 4f74eb9..0000000 --- a/src/shims-vue.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/// - -declare module "*.vue" { - import Vue from "vue"; - export default Vue; -} diff --git a/src/store.ts b/src/store.ts new file mode 100644 index 0000000..4883f80 --- /dev/null +++ b/src/store.ts @@ -0,0 +1,327 @@ +import Vue, { version, reactive, watchEffect } from "vue"; +import * as defaultCompiler from "@vue/compiler-sfc"; +import { compileFile } from "./transform"; +import { utoa, atou } from "./utils"; +import { + SFCScriptCompileOptions, + SFCStyleCompileOptions, + SFCTemplateCompileOptions, +} from "@vue/compiler-sfc"; +import { OutputModes } from "./output/types"; + +const defaultMainFile = "App.vue"; + +// const welcomeCode = ` +// + +// +// `.trim(); + +const welcomeCode = ` + + +`.trim(); + +export class File { + // filename is the key in the files object in the store state and is used to identify the file + // 文件名是文件对象在存储状态中的键,用于标识文件 + filename: string; + // code is the actual content of the file zh:代码是文件的实际内容 + code: string; + // hidden files are not shown in the file tree and are not compiled zh:隐藏的文件不会显示在文件树中,也不会被编译 + hidden: boolean; + // compiled is the result of compiling the file zh:编译是编译文件的结果 + compiled = { + js: "", + css: "", + ssr: "", + }; + // 构造函数 + constructor(filename: string, code = "", hidden = false) { + this.filename = filename; + this.code = code; + this.hidden = hidden; + } +} +// the state of the store +export interface StoreState { + // mainFile is the file that is rendered in the preview iframe + //主文件是在预览iframe中呈现的文件 + mainFile: string; + // files is a map of filename to file + // 文件是文件名到文件的映射 + files: Record; + // activeFile is the file that is currently being edited + // activeFile是当前正在编辑的文件 + activeFile: File; + // errors is an array of errors that occurred during compilation + //错误是编译期间发生的错误数组 + errors: (string | Error)[]; + // vueRuntimeURL is the URL of the runtime to use in the preview iframe + // 在预览iframe中使用的运行时的URL + vueRuntimeURL: string; + // vueServerRendererURL is the URL of the server renderer to use in the preview iframe + // vueServerRendererURL是在预览iframe中使用的服务器渲染器的URL + vueServerRendererURL: string; + // used to force reset the sandbox zh:用于强制重置沙箱 + resetFlip: boolean; +} + +export interface SFCOptions { + script?: Omit; + style?: SFCStyleCompileOptions; + template?: SFCTemplateCompileOptions; +} + +export interface Store { + state: StoreState; + options?: SFCOptions; + compiler: typeof defaultCompiler; + vueVersion?: string; + init: () => void; + setActive: (filename: string) => void; + addFile: (filename: string | File) => void; + deleteFile: (filename: string) => void; + getImportMap: () => any; + initialShowOutput: boolean; + initialOutputMode: OutputModes; +} + +// ReplStore 构造函数参数 +export interface StoreOptions { + // serializedState is the serialized state of the store zh:序列化的状态是存储的序列化状态 + serializedState?: string; + // showOutput is whether the output should be shown by default zh:showOutput是默认情况下是否应该显示输出 + showOutput?: boolean; + // loose type to allow getting from the URL without inducing a typing error zh:松散类型,允许从URL获取而不引起类型错误 + outputMode?: OutputModes | string; + // defaultVueRuntimeURL is the default URL of the runtime to use in the preview iframe zh:defaultVueRuntimeURL是在预览iframe中使用的运行时的默认URL + defaultVueRuntimeURL?: string; + // defaultVueServerRendererURL is the default URL of the server renderer to use in the preview iframe zh:defaultVueServerRendererURL是在预览iframe中使用的服务器渲染器的默认URL + defaultVueServerRendererURL?: string; +} + +// ReplStore is the main store for the REPL +export class ReplStore implements Store { + state: StoreState; + compiler = defaultCompiler; + vueVersion?: string; + options?: SFCOptions; + initialShowOutput: boolean; + initialOutputMode: OutputModes; + + private defaultVueRuntimeURL: string; + private defaultVueServerRendererURL: string; + private pendingCompiler: Promise | null = null; + + // `https://unpkg.com/browse/vue@${version}/dist/vue.esm.browser.js`, + constructor({ + serializedState = "", + defaultVueRuntimeURL = `https://unpkg.com/@vue/runtime-dom@3.2.47/dist/runtime-dom.esm-browser.js`, + defaultVueServerRendererURL = `https://unpkg.com/@vue/server-renderer@3.2.47/dist/server-renderer.esm-browser.js`, + showOutput = false, + outputMode = "preview", + }: StoreOptions = {}) { + console.log(`vue@${version}`); + let files: StoreState["files"] = {}; + + if (serializedState) { + const saved = JSON.parse(atou(serializedState)); + for (const filename in saved) { + files[filename] = new File(filename, saved[filename]); + } + } else { + files = { + [defaultMainFile]: new File(defaultMainFile, welcomeCode), + }; + } + // console.log("constructor", files); + this.defaultVueRuntimeURL = defaultVueRuntimeURL; + this.defaultVueServerRendererURL = defaultVueServerRendererURL; + this.initialShowOutput = showOutput; + this.initialOutputMode = outputMode as OutputModes; + + let mainFile = defaultMainFile; + if (!files[mainFile]) { + mainFile = Object.keys(files)[0]; + } + this.state = reactive({ + mainFile, + files, + activeFile: files[mainFile], + errors: [], + vueRuntimeURL: this.defaultVueRuntimeURL, + vueServerRendererURL: this.defaultVueServerRendererURL, + resetFlip: true, + }); + this.initImportMap(); + } + + // don't start compiling until the options are set + init() { + watchEffect(() => compileFile(this, this.state.activeFile)); + for (const file in this.state.files) { + if (file !== defaultMainFile) { + compileFile(this, this.state.files[file]); + } + } + } + + setActive(filename: string) { + this.state.activeFile = this.state.files[filename]; + } + + addFile(fileOrFilename: string | File): void { + const file = + typeof fileOrFilename === "string" + ? new File(fileOrFilename) + : fileOrFilename; + this.state.files[file.filename] = file; + if (!file.hidden) this.setActive(file.filename); + } + + deleteFile(filename: string) { + if (confirm(`Are you sure you want to delete ${filename}?`)) { + if (this.state.activeFile.filename === filename) { + this.state.activeFile = this.state.files[this.state.mainFile]; + } + // delete this.state.files[filename]; + Vue.delete(this.state.files, filename); + } + } + + serialize() { + return "#" + utoa(JSON.stringify(this.getFiles())); + } + + getFiles() { + const exported: Record = {}; + for (const filename in this.state.files) { + exported[filename] = this.state.files[filename].code; + } + return exported; + } + + async setFiles(newFiles: Record, mainFile = defaultMainFile) { + const files: Record = {}; + if (mainFile === defaultMainFile && !newFiles[mainFile]) { + files[mainFile] = new File(mainFile, welcomeCode); + } + for (const filename in newFiles) { + files[filename] = new File(filename, newFiles[filename]); + } + for (const file in files) { + await compileFile(this, files[file]); + } + this.state.mainFile = mainFile; + this.state.files = files; + this.initImportMap(); + this.setActive(mainFile); + this.forceSandboxReset(); + } + + private forceSandboxReset() { + this.state.resetFlip = !this.state.resetFlip; + } + + private initImportMap() { + const map = this.state.files["import-map.json"]; + if (!map) { + this.state.files["import-map.json"] = new File( + "import-map.json", + JSON.stringify( + { + imports: { + vue: this.defaultVueRuntimeURL, + }, + }, + null, + 2 + ) + ); + } else { + try { + const json = JSON.parse(map.code); + if (!json.imports.vue) { + json.imports.vue = this.defaultVueRuntimeURL; + map.code = JSON.stringify(json, null, 2); + } + if (!json.imports["vue/server-renderer"]) { + json.imports["vue/server-renderer"] = + this.defaultVueServerRendererURL; + map.code = JSON.stringify(json, null, 2); + } + // eslint-disable-next-line no-empty + } catch (e) { } + } + } + + getImportMap() { + try { + return JSON.parse(this.state.files["import-map.json"].code); + } catch (e) { + this.state.errors = [ + `Syntax error in import-map.json: ${(e as Error).message}`, + ]; + return {}; + } + } + + setImportMap(map: { + imports: Record; + scopes?: Record>; + }) { + this.state.files["import-map.json"]!.code = JSON.stringify(map, null, 2); + } + + async setVueVersion(version: string) { + this.vueVersion = version; + const compilerUrl = `https://unpkg.com/@vue/compiler-sfc@${version}/dist/compiler-sfc.esm-browser.js`; + const runtimeUrl = `https://unpkg.com/@vue/runtime-dom@${version}/dist/runtime-dom.esm-browser.js`; + const ssrUrl = `https://unpkg.com/@vue/server-renderer@${version}/dist/server-renderer.esm-browser.js`; + this.pendingCompiler = import(/* @vite-ignore */ compilerUrl); + this.compiler = await this.pendingCompiler; + this.pendingCompiler = null; + this.state.vueRuntimeURL = runtimeUrl; + this.state.vueServerRendererURL = ssrUrl; + const importMap = this.getImportMap(); + const imports = importMap.imports || (importMap.imports = {}); + imports.vue = runtimeUrl; + imports["vue/server-renderer"] = ssrUrl; + this.setImportMap(importMap); + this.forceSandboxReset(); + console.info(`[@vue/repl] Now using Vue version: ${version}`); + } + + resetVueVersion() { + this.vueVersion = undefined; + this.compiler = defaultCompiler; + this.state.vueRuntimeURL = this.defaultVueRuntimeURL; + this.state.vueServerRendererURL = this.defaultVueServerRendererURL; + const importMap = this.getImportMap(); + const imports = importMap.imports || (importMap.imports = {}); + imports.vue = this.defaultVueRuntimeURL; + imports["vue/server-renderer"] = this.defaultVueServerRendererURL; + this.setImportMap(importMap); + this.forceSandboxReset(); + console.info(`[@vue/repl] Now using default Vue version`); + } +} diff --git a/src/transform.ts b/src/transform.ts new file mode 100644 index 0000000..212f6c4 --- /dev/null +++ b/src/transform.ts @@ -0,0 +1,312 @@ +import { Store, File } from "./store"; +import { + SFCDescriptor, + BindingMetadata, + shouldTransformRef, + transformRef, + CompilerOptions, +} from "@vue/compiler-sfc"; +import { transform } from "sucrase"; +// @ts-ignore +import hashId from "hash-sum"; + +export const COMP_IDENTIFIER = `__sfc__`; + +async function transformTS(src: string) { + return transform(src, { + transforms: ["typescript"], + }).code; +} + +export async function compileFile( + store: Store, + { filename, code, compiled }: File +) { + if (!code.trim()) { + store.state.errors = []; + return; + } + + if (filename.endsWith(".css")) { + compiled.css = code; + store.state.errors = []; + return; + } + + if (filename.endsWith(".js") || filename.endsWith(".ts")) { + if (shouldTransformRef(code)) { + code = transformRef(code, { filename }).code; + } + if (filename.endsWith(".ts")) { + code = await transformTS(code); + } + compiled.js = compiled.ssr = code; + store.state.errors = []; + return; + } + + if (!filename.endsWith(".vue")) { + store.state.errors = []; + return; + } + + const id = hashId(filename); + const { errors, descriptor } = store.compiler.parse(code, { + filename, + sourceMap: true, + }); + if (errors.length) { + store.state.errors = errors; + return; + } + + if ( + descriptor.styles.some((s) => s.lang) || + (descriptor.template && descriptor.template.lang) + ) { + store.state.errors = [ + `lang="x" pre-processors for